eBPFを⽤いた
トレーシングについて
さくらインターネット株式会社
技術本部 クラウドチーム アプリケーショングループ
穎川 和弘
1
Agenda
u 概説
u eBPFとは
u Bpftraceとは
u Dtrace, Systemtap
u Dtrace, Systemtap
u Dtraceとは
u Systemtapとは
u そしてBpftraceへ
u Bpftrace
u インストール要件
u トレースの種別
u Bpftraceを使ってみる
u bcc-tools
2
誰︖
u 名前: 穎川 和弘 (えがわ かずひろ)
u 業務: IaaSのバックエンドで動作するアプリケーションの開発 (golang)
u 趣味: 分散システムや並⾏処理、⾔語処理系に興味
u アニメも⼤好き (特にまんがタイムきらら枠)
u 実は登壇系は初めてで、めっっっっちゃ緊張してます (><)
3
本スライドの⽬標
u dtrace や systemtapを簡単に説明し、eBPFを⽤いたトレーシングの嬉しいとこ
ろを伝える
u Bpftrace, bcc-toolsといったツールの簡単な使い⽅を紹介し、細かいツールを
調べる上での⾜がかりになるようにする
u GithubのIOvisor org の資料がかなり充実していることを伝える
u このスライドで使ってる画像はまさにそこから使わせていただいております
4
概説
5
eBPFとは
u Linuxカーネル 3.15から、BPFの拡張仕様としてeBPFが導⼊されました
u より詳細な話は少しづつお話ししていきます
u BPFはこれまでにも、パケットフィルタやシステムコールフィルタなど強⼒な
機能を有していましたが、eBPFの導⼊によって、⾼速なネットワーク処理、よ
り詳細なLinuxでのメトリクス取得に活⽤の幅が広がってきています
u eBPFを取り巻くOSSプロダクトでは、開発も盛んに⾏われており、本スライド
では特にbpftrace (+ちょっとbcc) を取り上げ、その⼀⾯を覗こうと思います。
6
トレーシングを可能にするツール
u パフォーマンスのボトルネック調査、エラーの発⽣原因調査の際には、よく
procpsやsysstat, perf-toolsといったパッケージのツール、syslogなどをまずは
調査することが多いかと思います。
u ただし、それらから観測できるカウンタ値、ログのみからは判別できないため
に、より詳細なメトリクスやトレーシングが要求される状況もあるかと思いま
す。
u そうした際、これまでは Dtrace やSystemtapといったツールが利⽤され、DSL
の記述によってトレーシングが実現できていましたが、eBPFがLinuxカーネル
に導⼊されたことに伴い、bpftraceがこれの後継として開発されました。
7
DTrace, Systemtap
u まずは、dtrace, systemtapを⾒てみましょう
u Bpftraceはdtraceやsystemtapの後継にあたるので、これまで使われていたツー
ルを知ることで、bpftraceを使う理由も⾒えてくると思います
8
DTrace, Systemtap
9
DTraceとは
u DTraceは元々、Solaris 10, OpenSolarisに対して⾼度なトレーシングを⾏うため
に開発されました
u D⾔語というプログラミング⾔語を⽤います
u ただ、書き味はpure Dよりも⾼級なDSLです
u Dtraceはいくつかのプロバイダーを提供しており、これらによってプローブが
設置されます
u プローブの先頭にはどのプロバイダを利⽤するのか指定する必要があり、これに
よってどのようにトレースされるのかが決定されます
u プロバイダはカーネルモジュールとして実装され、ユーザランドから ioctl(2)
を⽤いてやり取りが⾏われることで、トレーシングが実現されます
10
DTraceスクリプト
11
Systemtapとは
u Systemtapは、Linuxで⾼度なトレーシングを⾏うために開発されました
u DSLで記述されたコードは、C⾔語のソースに変換され、カーネルモジュールに
コンパイルされます
u Stapdynと呼ばれるユーザランドのSystemtapバックエンドも開発されているよ
うで、この場合はstapフロントエンドによって共有ライブラリにコンパイルさ
れたものを利⽤するようです
u Systemtapは probe points をいくつか定義しており、これらによってどこに対
してトレーシングを実施するかが決定されます
12
Systemtapスクリプト
13
そしてBpftrace へ …
u 「どちらでもやりたいことは実現できそうなんだけど、どちらを使えばいい
の︖」という⾵に悩むケースもあるかと思いますが、このように開発経緯や設
計などが異なるだけで、優劣をつけるのが難しいと思われます
u ⼤きな共通点は、どちらもカーネルモジュールを⽤いていて、それによってト
レーシングが実現されているということです
u Bpftrace はこれらの後継に相当し、良い設計を取り込みつつ、eBPFに併せて
ゼロベースで開発されたOSSです。
14
Bpftrace で可能になったこと
u カーネル空間である程度計算が⾏われるため、ユーザ空間へのデータコピーによる
コストが下がりました
u 例えば、特定プローブ呼び出し回数のヒストグラムを⽣成したい場合に、ヒストグラムの
計算処理をカーネル空間で⾏います
u BPFの命令セットによる中間⾔語に変換され、JITコンパイルできるようになりまし
た
u Linux内部に存在するVerifierによってプログラムが厳格に検査され、より安全性が
向上しました
u これまで利⽤できたMapなどのデータ構造などもeBPFでサポートされました
15
Bpftrace
16
Bpftraceとは
u DSLの記述で⾼レベルなトレーシングが⾏える、eBPFフロントエンドです。
u IOvisor organization のOSSプロダクトとして開発が⾏われています。
17
インストール要件
u 公式 (https://github.com/iovisor/bpftrace/blob/master/INSTALL.md#linux-
kernel-requirements) から、個⼈的な認識では
u Linux 5.x を⽤いた⽅が良いです
u *BPF*, *EBPF*, FTRACE_SYSCALLS 周りのカーネルコンフィグについて設定されてい
ることを確認しておきましょう
u Ubuntuでは、debパッケージやsnapパッケージが利⽤可能ですので、これらで
インストールすればおkです
u より詳しくは、上記公式インストールガイドを参照ください
18
Bpftrace 概観
u 参考: https://github.com/iovisor/bpftrace/blob/master/docs/internals_development.md
19
トレースの種別
u Kprobe
u Uprobe
u Tracepoint
u USDT (User Statically-Defined Tracing)
u Kprobe, uprobe には、関数呼び出しプローブポイントを⽰すkprobe, uprobe,
関数終了プローブポイントを⽰すkretprobe, uretprobeがあります
u これらの中でも、特に安定して使えるトレース種別は Tracepointですので、
Tracepointを使って情報を取得する例について話します
u http://www.brendangregg.com/blog/2018-03-22/tcp-tracepoints.html 20
Bpftraceを使ってみる
u Linuxのプロセススケジューラがプロセスを終了させた時、そのプロセスのコ
マンド名をMapデータ構造に保存し、呼び出し回数を記録してみましょう
21
使う環境
u OS
u Ubuntu 18.04.4 LTS (bionic)
u Uname –a
u Linux kazu-desktop 5.3.0-51-generic #44~18.04.2-Ubuntu SMP Thu Apr 23 14:27:18
UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
u CPU4コア 、メモリ16GB
22
トレーシングの流れ
u Tracepoint⼀覧に欲しいものがあるか探す
u 引数にコマンド名をとっていることを確認する
u DSLを書く
u 実⾏
23
Tracepoint⼀覧に欲しいものがあるか探す
u Bpftrace –l によって列挙が可能で、ワイルドカードで検索ができます
u Tracepoint:sched:sched_process_exit を⽤いれば、トレースできそうですね
24
引数にコマンド名をとっていることを確認す
る
u /sys/kernel/debug/tracing/events/$(先ほど⾒つけたtracepointをパス化した
もの)/format のファイルに詳細が記述されます
u comm[16] がコマンド名を⽰すので、これを使えば良さそうです
25
DSLを書く
u こんな感じになりました。早速実⾏してみましょう
26
実⾏
u 実⾏後、ちょっと時間が経ってから CTRL-C で終了させると、以下のように出
⼒されます
27
bcc-tools
28
Bcc-toolsとは
u Bpftraceと同じように実⾏できるbccというものが、同じく iovisorプロジェク
トで開発されています。
u 詳細な解説はここでは⾏いませんので、「そういうものがあるのね」と認識いただ
ければ問題ありません
u このbccで書かれたツール群、bcc-tools を⽤いることで、これまで⽤いていた
可観測性ツールよりもより役⽴つ情報が得られるようになります
u インストール要件は https://github.com/iovisor/bcc/blob/master/INSTALL.md を
ご覧ください
u もしかすると、procpsやsysstatの代替として bcc-tools が広く使われる未来が
来るかもしれません
29
Linuxに⼊ってすぐ調べること
u LAを⾒て、負荷が⾼いかどうか
u Syslogを⾒て、OOMだとか、パケットドロップが発⽣していないか
u Vmstat で概況を確認
u CPUコアごとの負荷を確認
u リアルタイムに実⾏されてるコマンドを確認
u I/O負荷の確認
u メモリ容量の確認
u ネットワーク、TCP周りの統計情報を確認
u などなど
30
Bcc-toolsをちょっとみてみる
u いくつかの分かりやすく使えそうなツールを紹介してみようと思います
u Execsnoop
u Opensnoop
u Biosnoop
u Biolatency
u Tcpconnect
u Tcpretrans
u Runqlat
31
execsnoop
u 実⾏プロセスを追跡できます (PPIDや終了コードも表⽰してくれます)
32
opensnoop
u どのプロセスがどのファイルを開いているのかが⾒れます (fdやエラー発⽣な
ども)
33
biosnoop
u ブロックI/Oのバイト数、使⽤ディスク、コマンド、PID, 経過時間などを⾒れ
ます
34
biolatency
u ブロックI/O のレイテンシを計測し、それをヒストグラムで表⽰します
35
biolatency
u I/Oフラグ(rwbsと呼ばれる) ごとにヒストグラムを出すことも可能です (--flags
オプション)
u https://elixir.bootlin.com/linux/v4.7/source/kernel/trace/blktrace.c#L1772
36
tcpconnect
u TCPのconnect(3)呼び出しをトレースします
u どのコマンド実⾏によって、どこからどこへのやりとりが⾏われているか把握
できます
37
tcpretrans
u TCPの再送を列挙します
38
runqlat
u プロセスがrun queueに積まれるまでにどれくらいの遅延が起きているかをヒ
ストグラム化してくれます
39
オプション指定について
u Usage, Options, Examplesを
-–helpオプションの指定で確認で
きます
u Examplesにはコマンド例と簡易な
説明が表⽰されます
40
Bcc-tools は何で書かれているか
u 多くがPythonスクリプトで⽤意されています
u Bcc-tools は、 iovisor/bcc リポジトリに同梱されており、toolsディレクトリ配
下に置いてあります
u https://github.com/iovisor/bcc/tree/master/tools
u Iovisor/bcc リポジトリには、Pythonのbccライブラリ実装が配置されており、
bcc-tools がこのライブラリをimportする形で利⽤されています
41
bccライブラリを使った実⾏の⼤まかな
流れ (execsnoop.pyの場合)
u bccライブラリをimport
u Cのソースを bcc.BPFクラス に渡して初期化
u Cのソースは、⽂字列で定義して渡しても良し、別ファイル読み込んでも良し、ヘッダ
ファイルを読み込んでも良しです
u 初期化されたbcc.BPF の attach_xxx メソッドを呼び出します
u xxxは、kprobeとかtracepointとか
u perf_event_open(2) が呼び出されることを契機にカーネル空間でパフォーマンスカウンタ
が収集されるようになります
u bcc.BPF の open_perf_bufferを呼び出し、コールバック関数を登録します
u bcc.BPFの perf_buffer_poll を呼び出し、イベントの発⽣を監視します
u 内部的には、poll(2) が呼び出されることでperf ring bufferのイベント監視が⾏われます
u 以上により、イベントがコールバック関数にわたり、適切に加⼯されて出⼒されま
す
42
Bcc-tools overview
u ここでご紹介したbcc-toolsは実はほんの⼀部で、このほかに⾮常に多くのツールが
⽤意されています
u 参考: https://github.com/iovisor/bcc#tools 43
終わりに
44
より詳しく知りたい⽅向けに
u 「BPF Performance Tools」がおすすめです
u eBPFのトレーシングについては、おそらくこの書籍が⼀番詳しいかと思います
u https://www.amazon.co.jp/Performance-Tools-Addison-Wesley-Professional-
Computing/dp/0136554822/
u ネットワーク処理、XDP周りにも興味があるよ︕と⾔う⽅には 「Linux
Observability with BPF」がおすすめです
u 導⼊に必要な知識が少ないページ数でキッチリ説明されてます
u Githubリポジトリのコードも参照しながら読み進めることをお勧めします
u https://www.amazon.co.jp/Linux-Observability-Bpf-Programming-
Performance/dp/1492050202/
45
おわりに
u ここまでで紹介したトレーシングツールは、障害原因を調査する⽬的はもちろ
んのこと、Linuxについてより詳しく挙動を知りたい場合にも有⽤だと思いま
す
u Bcc-toolsには分かりやすいオプションが定義されているので、そちらも確認してみ
てください︕
u ここでは紹介しきれていませんが、iovisorプロジェクト外の CilliumやKatran
などのOSS、Prometheusと連携できるebpf_exporter、パケット解析できるP4
⾔語、LinuxのLSMであるLandlockなど⾯⽩い活⽤の仕⽅もあったりします
u 今後も⽬が離せなさそうで、⾮常に⾯⽩い技術ネタだと思っています︕
46
その他の参考記事
u [1] Systemtap HomePage
u https://sourceware.org/systemtap/wiki
u [2] Github opendtrace/opendtrace
u https://github.com/opendtrace/opendtrace
u [3] Dtrace is open 2005/01/25
u https://blogs.oracle.com/ahl/dtrace-is-open
u [4] bcc-tools README.md
u https://github.com/iovisor/bcc
u [5] bpftrace README.md
u https://github.com/iovisor/bpftrace
47
ご清聴ありがとうございました
48

eBPFを用いたトレーシングについて