[[eBPF]](extended Berkley Packet Filter)という用語を著者が初めてみかけたのは、2015年ごろだった。最初は、eBPFをその字面のとおり、パケットキャプチャやパケットフィルタリングを担うだけの、Linuxの新しいサブシステムであろうと認識していた。しかし、実際にはそうではなかった。 システム性能の分析のための方法論をまとめた書籍Systems Performance<sup id="a1">[1](#f1)</sup>の著者で有名なBrendan Greggが、Linuxのネットワークサブシステムとは特に関係ない文脈で、古典的なシステム性能計測ツールでは計測できないことを計測するツールを作っていた。その計測ツールがeBPFという技術によって実装されていることを知ったときに、eBPFに興味をもったのだった。また、eBPFは、システム性能を調べる用途以外に[[XDP]](eXpress Data Path)と呼ばれるプログラマブルなパケット処理機構を備えている。10年近く前に、Linuxカーネルのパケット処理機構を扱っていたことがあった(([超高速なパケットI/Oフレームワーク netmap について - ゆううきブログ](https://blog.yuuk.io/entry/2013/08/03/162715)))([GPUを用いたSSLリバースプロキシの実装について - ゆううきブログ](https://blog.yuuk.io/entry/2013/04/17/171230)、 [Linuxでロードバランサやキャッシュサーバをマルチコアスケールさせるためのカーネルチューニング - ゆううきブログ](https://blog.yuuk.io/entry/linux-networkstack-tuning-rfs))ことから、より興味を引き立てられた。 このように、5年以上前からeBPFに興味はあったものの、当時扱っていたシステムのLinuxカーネルバージョンは、eBPFをサポートしていなかった、あるいはサポートしていても最初期のeBPFの機能を使用できるのみであったため、本格的にeBPFを学習しようとはしてこなかった。 その後、仕事の内容が研究開発に移り、特定の現場に依存する仕事がなくなった。偶然ではあるが、以前から進めていた研究のプロトタイピングで、eBPFによるカーネル内のネットワーク通信をトレースすることにより、依存関係マップを構築するための基礎技術を研究することになった。そのため、eBPFをいちから学ぶ必要があったのだが、eBPFは機能が豊富かつ開発も活発なため、まずeBPFの各機能の位置付けや歴史を知ることが難しく、さらに実際にeBPFの最新の機能を用いてアプリケーションを開発するとなると、参考文献や参考コードが少なく、それなりの困難を伴った。 [分散アプリケーションの依存発見に向いたTCP/UDPソケットに基づく低負荷トレーシング - ゆううきブログ](https://blog.yuuk.io/entry/2021/wsa08) その経験を踏まえて、この記事では、今年の4月にゲスト出演したポッドキャスト[e34.fm ep2](https://e34.fm/2/)のエピソードをもとに、eBPFを用いたLinuxカーネルのトレーシング技術の概要とトレーシングアプリケーションの実装プロセスを整理する。この記事がeBPF登場の動機からeBPFの基本要素とツールの実装に至るまでのガイドラインとなれば幸いである。 (extended BPFの正式略称はBPFであるため、以降では書き分ける必要がない限りBPFと表記する。) [:contents] ## ![[BPFとはなにか]] ## ![[トレーシングにおけるBPFの位置付け]] ## ![[BPFトレーシングの技術要素]] ## ![[BPFトレーシングの歴史]] ## ![[BPFトレーシングのプログラミング]] ## まとめ この記事では、BPFの定義から始まり、トレーシングの文脈でのBPFの位置付け、BPFトレーシングを構成する技術要素、BPFとBPFトレーシングの歴史、BPFトレーシングツールのプログラミングまでを概観した。BPFでツールをつくってみたいと思い立ったときに、実装の細部の試行錯誤以外では、迷いがないように体系的な知識として整理されるように心がけた。 来春のUbuntu 22.04 LTSのリリースをきっかけに、今後は、デフォルトでCO-REをサポートする環境が増えていくはずだ。それに伴い、BPFトレーシングツールのデプロイが容易になるため、BPFトレーシングは一層普及していくだろう。 ## あとがき 冒頭で述べたように、研究開発向けに着想した手法を実装するために、BPFを学習する必要があった。OSに近しい低レイヤのプログラミングは好きではあるものの、得意というほどでもないため、それなりの学習コストがあった。C言語は8年ぶりぐらいに書いたように思う。BPFのC言語は制約が強く、コードに明らかな欠陥があればBPF Verifierが検出してくれるため、C言語自体にはそれほど苦労しなかった。カーネルのコードのどの箇所をフックするか、どの変数から必要なデータを読み出すかといったコードの理解により苦労した。 今年の前半にBPFの話を仲間内でしていたら、[@deeeet](https://twitter.com/deeeet)と[@rrreeeyyy](https://twitter.com/rrreeeyyy)がホストするe34.fmに出演させてもらった。このときに、BPFの基本と応用例をそれなりに調査していたので、そのうち、テキストにまとめようと思ったものの、そのままになっていた内容を今年のうちにまとめることができてよかった。e34.fmでは触れらなかったBPFトレーシングの実装に踏み込んだ話も整理できた。 今年の春頃から、前職の同僚たちによるBPF Performance Tools<sup id="a2">[2](#f2)</sup>の輪読会に参加させてもらっている。この本の後半は、CPU・メモリ・ファイルシステム・ディスク・ネットワークについて、BCCの性能分析ツールがひたすらに紹介されている。ひとつずつ読んでいくのが苦行に感じてはいるものの、BPFトレーシングでどういうことができるのか、トレーシング結果の表示形式、トレーシングのオーバヘッド、kprobeとtracepointのそれぞれにアタッチしたときの利点と欠点の肌感をおかげで掴めつつある。(Thanks to id:masayoshi:detail, id:dekokun:detail, id:hokkai7go:detail, id:hayajo_77:detail) この輪読会のなかで、6年以上前の時系列データベースのディスクI/O関連のトラブルシューティングに、BPFが使えていればなあと何度も吐露していた[Mackerelにおける時系列データベースの性能改善 / Performance Improvement of TSDB in Mackerel - Speaker Deck](https://speakerdeck.com/yuukit/performance-improvement-of-tsdb-in-mackerel)。とはいえ、kprobeやtracepointはそれ以前から存在していたので、perfやSystemTapを使いこなせていれば効率よくトラブルシュートできていたかもしれない。 今後はBPFを活用していきたい一方で、2010年代後半のBPFが普及した時期と同時期に、クラウドの分野では、OSよりも上位層のソフトウェアを抽象化してサービス化するマネージドサービスが普及していることは見逃せない。多くのマネージドサービスは、利用者がLinuxカーネルがアクセスことを制限しているため、BPFを使おうと思っても使えないか、使う必要すらないこともある。マネージドサービスは極めて便利で、実務上は使わない手はないのだけど、システムソフトウェアの領域で、自分のアイデアでなにかをつくれるような余地が徐々に狭まっているように感じる自分もいる。実務上の利便性を無視することは難しいが、BPFやWASMのようなユーザーが拡張可能な技術の上に、システムソフトウェアに関心のある研究者や技術者が自分のアイデアを創造できるような世界であってほしいと願う。 ## 参考文献 - <b id="f1">[1]</b>: Brendan Gregg, "Systems Performance", Pearson, ed. 1st, 2013. [↩](#a1) - <b id="f2">[2]</b>: Brendan Gregg, "BPF Performance Tools", Addison-Wesley Professional, 2019. [↩](#a2) - <b id="f3">[3]</b>: David Calavera, and Fontana Lorenzo, "Linux Observability with BPF: Advanced Programming for Performance Analysis and Networking", O'Reilly Media, 2019. [↩](#a3) - <b id="f4">[4]</b>: The Linux Foundation, eBPF - Introduction, Tutorials & Community Resources, <https://ebpf.io/>, 2021. [↩](#a4) - <b id="f5">[5]</b>: Steven McCanne, and Van Jacobson, "The BSD Packet Filter: A New Architecture for User-level Packet Capture." USENIX winter. Vol. 46. 1993. [↩](#a5)