eBPF入門——カーネルを再起動なしで拡張する仕組みと、今日から始めるオブザーバビリティ実践ガイド

はじめに

結論から言うと、eBPFとはLinuxカーネルを再起動せずに、しかも安全に拡張できる技術です。カーネルのソースコードを改変することも、壊れやすいカーネルモジュールをロードすることもなく、独自のプログラムをカーネル空間で動かせます。かつてパケットフィルタとして生まれたBPF(Berkeley Packet Filter)が進化した「extended BPF」は、今やオブザーバビリティ、セキュリティ、ネットワーキングを支えるLinuxの基盤技術へと成長しています。

なぜ今、eBPFなのか

eBPFはすでに「研究段階の新技術」ではありません。広く採用が進んでいます。

  • クラウドベンダーでの採用: AWSのEKS標準CNIやGuardDutyのランタイム監視、Azureの「Azure CNI Powered by Cilium」、GKEなど、3大クラウドのオブザーバビリティ・ネットワーキング基盤に組み込まれています。
  • 商用オブザーバビリティ製品での標準利用: New Relicをはじめ、DatadogやGrafanaといった主要プラットフォームがeBPFベースの機能を提供しています。New Relic eBPFであれば、Helmコマンド1つでエージェントをデプロイするだけで、アプリケーションのコードを1行も変えずにサービス間通信を自動検出できます。
  • CNCFエコシステムの中核: Cilium(kube-proxy置換のロードバランシング)やTetragon(ランタイムセキュリティ)といったeBPFベースのプロジェクトがKubernetes環境で広く使われています。

つまり、LinuxやKubernetesの運用・観測に携わるエンジニアにとって、eBPFの理解は「あると嬉しい知識」から「前提となる知識」へと変わりつつあるのです。

この記事でわかること

この記事では、eBPFの仕組みから今日から始められる実践まで、次の流れで解説します。

  1. eBPFとは何か: 「カーネル再起動なし」がなぜ大きなのか、従来手法との比較で理解する
  2. どう動くのか: Verifier・JITコンパイラ・Maps・ヘルパー関数という4大要素の仕組み
  3. カーネルモジュールとの違い: 安全性・保守性・可搬性を比較表で整理
  4. 何ができるのか: オブザーバビリティ・セキュリティ・ネットワーキングの3大ユースケース
  5. ツールの選び方: bpftrace / BCC / Cilium / Tetragon / eBPF Exporterの特徴徹底比較
  6. 今日から始めるステップバイステップガイド: ワンライナーからの第一歩から、Prometheus + Grafanaでの可視化、KubernetesでのTetragon導入まで
  7. 実際の採用事例: New Relic・クラウドベンダー・Cloudflareでの活用

「カーネルの中でプログラムを動かす」と聞くと難しそうに感じるかもしれません。しかし、実際の第一歩はbpftraceのワンライナー1行です。難解な理論からではなく、動かせるところから始められるのもeBPFの魅力です。それでは見ていきましょう。

eBPFとは何か?——「カーネル再起動なし」の意味を解説

eBPF(extended Berkeley Packet Filter)とは、Linuxカーネル内で安全にプログラムを実行できる技術です。カーネルのソースコードを書き換えたり、カーネルモジュールをロードしたりすることなく、システムコールやネットワークイベントといった「カーネルの動作ポイント」に独自の処理を差し込めます。しかも、その処理はロード時に厳密な検証を通過したうえでネイティブコード相当の速度で動きます。

「カーネルを再起動なしで拡張する」という表現の意味を理解するには、eBPFが登場する前に、カーネルを拡張するのがどれだけ大変だったかを知るのが一番の近道です。

従来のカーネル拡張には2つの選択肢しかなかった

Linuxカーネルの内部で新しい処理を動かしたい——たとえば「全システムコールを記録したい」「パケットの遅延を測りたい」という場合、従来は次の2つの方法しかありませんでした。

1つ目は、カーネルのソースコードを直接改変する方法です。 改変したカーネルをビルドし、全ノードに配布して再起動する必要があります。そして何より、その変更をLinuxカーネル本体に取り込んでもらうには、メーリングリストでのレビューを経てメインラインにマージされ、各ディストリビューションのカーネルとしてリリースされるまで待たなければなりません。このプロセスは年単位の時間がかかることも珍しくありません。企業の都合に合わせてカーネルを変えるのは、現実的にはほぼ不可能です。

2つ目は、カーネルモジュール(LKM)としてロードする方法です。 こちらはカーネルの再起動なしで機能を追加できるため、デバイスドライバなどでは今も標準的な手法です。しかし、カーネルモジュールには重大な課題があります。モジュールは検証なしでカーネル空間で動作するため、バグひとつでカーネルパニック(システム全体のクラッシュ)を引き起こします。さらに、カーネル内部の安定しないインターフェース(シンボル)に依存するため、カーネルを更新するたびに再コンパイルや修正が必要になり、脆弱性や安定性のリスクも抱えます。

つまり、従来のカーネル拡張は「遅いが比較的堅実」(ソース改変)か「手軽だが危険」(カーネルモジュール)の二択だったのです。

eBPFはカーネルを「プログラマブル」にする

この状況を変えたのがeBPFです。公式ドキュメント(ebpf.io)は、eBPFの意義を次のようなたとえで説明しています。

JavaScriptがウェブブラウザをプログラマブルにしたように、eBPFはカーネルをプログラマブルにする。

かつてのウェブブラウザは、決められたHTMLと画像を表示するだけの「静的な箱」でした。JavaScriptの登場によって、ブラウザは任意のアプリケーションを安全に実行できるプラットフォームへと生まれ変わります。しかも、そのJavaScriptコードがブラウザを壊すことはありません。

eBPFはこれと同じ変化をカーネルにもたらしました。カーネル側に手を加えず、実行時にeBPFプログラムをロードするだけで、観測・セキュリティ・ネットワーキングといった処理をカーネル内で動かせるのです。プログラムはサンドボックス化された環境で検証されてから実行されるため、カーネルをクラッシュさせる心配はありません。まさに「カーネルを再起動なしで、安全に拡張する」——これが冒頭の表現の正体です。

仕組みの詳細(Verifierによる安全性の保証や、JITコンパイラによる高速実行など)は次のセクションで掘り下げます。

cBPFからの進化——「パケットフィルタ」から汎用基盤へ

「BPF」という名前に含まれる歴史も押さえておきましょう。BPF(Berkeley Packet Filter)は、もともと1992年に考案されたパケットフィルタリングのための仕組みでした。tcpdumpがパケットを効率的に絞り込む裏側で動いていた、あのBPFです。

2014年頃、この古典的なBPF(現在はcBPF: classic BPFと呼ばれます)が大幅に拡張されました。汎用レジスタマシンへの刷新、検証器(Verifier)の導入、マップやヘルパー関数の整備などを経て、パケットフィルタの枠を超えた汎用的なカーネル拡張基盤へと進化したのです。これが「extended BPF」——eBPFです。

現在では「eBPF」は単なる略語ではなく、それ自体が一つの固有名詞として認識されています。パケットフィルタという出自を感じさせないほど、その役割は広がりました。オブザーバビリティ、セキュリティ、ネットワーキング——今日のeBPFは、クラウドネイティブインフラの中核技術として使われています。

まとめ: なぜ「安全・高速・再起動なし」を両立できるのか

このセクションの要点を整理します。

  • カーネル拡張の従来手法は「ソース改変(年単位の時間がかかる)」か「カーネルモジュール(クラッシュ・脆弱性・保守のリスク)」の二択だった
  • eBPFはカーネルに手を加えず、プログラムを実行時にロードしてカーネル内で安全に動かせる——JavaScriptがブラウザを変えたのと同じ構図
  • eBPFはcBPF(パケットフィルタ)を拡張した技術で、今や汎用的なカーネル拡張基盤へ成長した

では、eBPFプログラムはどのようにロードされ、どうやって安全性と速度を保証しているのでしょうか。次のセクションでは、中核を担う4つの要素——フックポイント、Verifier、JITコンパイラ、Mapsとヘルパー関数——を詳しく見ていきます。

eBPFはどう動く?——Verifier/JIT/Maps/ヘルパー関数の4大要素

eBPFが「安全で速いカーネル拡張」であり続ける理由は、実行までの道のりに幾重もの関門と仕組みが用意されているからです。ここでは、eBPFプログラムが書かれてから実際に動くまでの流れを、4つの構成要素——フックポイント/Verifier/JITコンパイラ/Mapsとヘルパー関数——に分けて解説します。

全体の流れは次のとおりです。C言語風に書かれたプログラムは、clang/LLVMによってeBPFバイトコードへコンパイルされ、bpfシステムコールでカーネルにロードされます。このときVerifierが安全性を検証し、通過したプログラムのみがJITコンパイルされてネイティブコード化。その後、イベントフックにアタッチされ、実行結果はMaps経由でユーザ空間のアプリケーションと共有されます。

flowchart LR
    A["eBPFプログラム<br/>(C風コード)"] -->|"clang/LLVM<br/>コンパイル"| B["eBPFバイトコード"]
    B -->|"bpfシステムコール<br/>でロード"| C["Verifier<br/>(安全性検証)"]
    C -->|"検証通過"| D["JITコンパイラ<br/>(ネイティブコード化)"]
    C -->|"検証失敗"| X["拒否<br/>(ロード不可)"]
    D --> E["フックポイントに<br/>アタッチ"]
    E --> F["イベント駆動で実行"]
    F <-->|"読み書き"| G["Maps<br/>(状態・データ共有)"]
    G <-->|"システムコール経由"| H["ユーザ空間アプリ<br/>(可視化・分析)"]

フックポイント(イベント駆動)

eBPFはイベント駆動で動作します。プログラムを常時実行するのではなく、あらかじめ指定した「フックポイント」をイベントが通過した瞬間にだけ実行される仕組みです。これが、低オーバーヘッドな観測を実現する大きな理由にもなっています。

利用できる主なフックポイントは次のとおりです。

フックポイント 概要
システムコール プロセスがカーネルの機能を呼び出す入口・出口
トレースポイント(tracepoint) カーネルが公式に提供する安定した観測点
kprobe カーネル内のほぼ任意の関数に動的にアタッチ
uprobe ユーザ空間アプリの任意の関数に動的にアタッチ
ネットワークイベント パケットの受信・送信など

システムコールやトレースポイントのように定義済みのフックがない場所も、kprobe(カーネル動的プローブ)やuprobe(ユーザ空間動的プローブ)を使えば任意の場所にアタッチできます。この柔軟性により、「システムコールの統計を取りたい」「特定のライブラリ関数の呼び出しを追いたい」といった用途に広く対応できます。

Verifier(検証器)——安全性はどう保証されるのか

「カーネル空間で任意のコードを動かす」と聞くと、カーネルパニックやシステム崩壊が心配になるでしょう。eBPFではこの恐怖に対して、ロード時に**Verifier(検証器)**がすべてのプログラムを事前検証するというアプローチで答えます。カーネルにロードする前に、プログラムの全実行パスが解析されるのです。

検証の主な内容は次の4つです。

  1. 特権チェック: ロードするプロセスがrootまたはCAP_BPFなどの適切な特権を持っていること
  2. 完了保証: プログラムが必ず終了すること。無限ループは拒否され、ループは終了条件が保証される場合にのみ許可されます
  3. メモリアクセスの検査: 未初期化変数の使用や境界外メモリアクセスの禁止
  4. 複雑さの上限: プログラムサイズと複雑さに上限があり、全実行パスの解析が上限内で完了しなければなりません

ここで大切な注意点があります。Verifierは**「安全に実行できるか」を検証するツールであり、「何をするプログラムか」を審査するものではない**ということです。検証を通過したプログラムでも、その意図まで保証されるわけではありません。ポリシーとして許可するプログラムの管理は、別途オペレーターの責任で行う必要があります。

JITコンパイラ——ネイティブ同等の速度

検証を通過したeBPFバイトコードは、JIT(Just-In-Time)コンパイラによって、実行環境のCPUに固有のマシン語へと実行時コンパイルされます。汎用バイトコードを逐次解釈するのではなくネイティブ命令へ変換するため、ebpf.ioの説明によればネイティブにコンパイルされたカーネルコードに匹敵する速度とされ、多くの用途で低オーバーヘッドで動作します(性能はプログラム構成や用途に依存します)。この「検証による安全性」と「JITによる速度」の両立こそ、eBPFの核心といえます。

また、JITコンパイル後のプログラムには堅牢化(ハードニング)も施されます。

  • 読み取り専用メモリによる保護: カーネル空間に置かれたプログラムメモリは読み取り専用として保護される
  • スペクター脆弱性への緩和: メモリアクセスのマスクやRetpolineなどの緩和策を適用
  • 定数隠蔽(コンスタントブラインディング): JITスプレー攻撃を防ぐため、即値を難読化して埋め込む

つまりJITは「速さ」のためだけではなく、生成されたコードが攻撃の足場に使われないための防御機構でもあるのです。

Mapsとヘルパー関数——カーネルとユーザ空間をつなぐ仕組み

eBPFプログラムは孤立して動くわけではありません。状態の保存やデータの共有を担うのがeBPF Maps(マップ)、カーネルの機能への安全なアクセス手段がヘルパー関数です。

Mapsは、eBPFプログラムが情報を共有・状態を保存するためのデータ構造で、ユーザ空間のアプリケーションからもシステムコール経由で読み書きできます。これにより「カーネル内で集計した統計を、ユーザ空間のダッシュボードで表示する」という連携が可能になります。主なマップタイプには次のようなものがあります。

  • ハッシュテーブル/配列(基本的なキー・バリュー型)
  • LRU(容量上限で古いエントリから追放)
  • リングバッファ(イベントストリームの効率的な送受信)
  • スタックトレース(パフォーマンス解析用)
  • LPM(Longest Prefix Match。ネットワークの経路探索などに最適化)

CPU間で共有する型と、CPUごとに独立したPer-CPU型が用意されている点も特徴で、ロック競合を避けた高頻度カウンタの収集などに活用されます。

一方、eBPFプログラムからは任意のカーネル関数を直接呼べません。代わりに、カーネルが提供するヘルパー関数を経由してカーネルの機能を利用します。乱数生成、現在日時の取得、マップへのアクセス、プロセス/cgroupコンテキストの取得、ネットワークパケットの操作などがヘルパー関数として用意されています。カーネル内部の関数シンボルはバージョンごとに変わりがちですが、ヘルパー関数というインターフェースを挟むことで互換性は改善されますが、カーネルバージョン間の機能互換性はCO-REやfeature probingで確認する必要があります。

さらに、末尾呼び出し(tail call)と関数呼び出しを使ってプログラムを組み合わせることもできます。複雑な処理を小さなプログラムに分割し、つなぎ合わせて実行できるため、Verifierの複雑さ上限とも上手く付き合いながら、柔軟なロジックを構築できます。

この4つの要素が組み合わさって、「カーネル再起動なしで、安全に、ネイティブ並みの速さでカーネルを拡張する」というeBPFの約束が実現されているのです。

カーネルモジュールとの違いは?——比較表

「カーネルを拡張する」と聞いて思い浮かぶのは、従来のカーネルモジュール(LKM: Loadable Kernel Module)かもしれません。デバイスドライバやファイルシステムの追加で長年使われてきた方式ですが、eBPFとは「安全性の保証」と「カーネルバージョンへの依存度」という点で決定的に異なります。

カーネルモジュールはカーネル空間で無制限に動作します。コードにバグがあればカーネルクラッシュ(カーネルパニック)やシステム全体のフリーズを引き起こし、悪意あるコードならシステムのあらゆる情報にアクセスできてしまいます。ロード前の検証はなく、カーネルと同じ権限で動く「信用できないコード」を載せる賭けに近い運用です。さらに、カーネル内部の構造体やシンボルに直接依存するため、カーネルが更新されるたびに再コンパイル・修正が必要になり、保守コストも無視できません。

一方のeBPFは、ロード時にVerifierが安全性を検証してから実行します。無限ループの禁止、境界外メモリアクセスの禁止、プログラムサイズと複雑さの上限といったチェックを通過しないプログラムは、そもそもカーネルに載ることができません。また、カーネルの内部関数を直接呼べず、ヘルパー関数を経由する設計により、カーネル更新への追従コストが低くなりやすい設計です(機能互換性の確認は必要です)。

両者の違いを表にまとめると、次のとおりです。

観点 eBPF カーネルモジュール
安全性 Verifierで検証済み 検証なし(カーネルクラッシュ可)
性能 JITでネイティブ同等 ネイティブ同等
保守 カーネル更新に強い(ヘルパーAPI安定) カーネル更新のたびに修正が必要
可搬性 CO-RE等で比較的高い カーネルバージョン依存が強い
主用途 観測・ネットワーキング・セキュリティ デバイスドライバ等

それぞれの観点を、もう少し掘り下げて解説します。

安全性が最大の違いです。eBPFプログラムはロード時にVerifierによる全実行パスの解析をパスしなければならず、カーネルをクラッシュさせる恐れのあるコードは実行そのものが拒否されます。カーネルモジュールにはこの仕組みがなく、動かしている最中に不具合が出て初めて問題が判明します。

性能は、実はどちらも高い水準にあります。eBPFはJITコンパイラによってバイトコードがマシン固有の命令へ実行時変換されるため、JITコンパイラによってバイトコードがマシン固有の命令へ実行時変換されるため、多くの用途で低オーバーヘッドな実行が可能です(性能はプログラム構成や用途に依存します)。

保守性では、eBPFがカーネルモジュールを大きくリードします。カーネルモジュールがカーネル内部の構造に直接依存するのに対し、eBPFはヘルパー関数を介してカーネル機能を利用し、CO-REなどの技術で可搬性を高めているため、カーネル更新にも追従しやすい設計です(機能互換性の確認は必要です)。

可搬性も同様です。CO-RE(Compile Once, Run Everywhere)という仕組みを使えば、コンパイル済みのeBPFプログラムを異なるカーネルバージョン環境で再利用できます。カーネルバージョンごとの再ビルドが前提のカーネルモジュールと比べ、配布や運用がはるかに柔軟です。

主用途は、両者の棲み分けを示しています。eBPFは観測(オブザーバビリティ)、ネットワーキング、セキュリティといった「カーネルの出来事を安全にフックする」領域で威力を発揮します。一方、新しいハードウェア向けデバイスドライバのように、カーネルの深部構造そのものを扱う領域は、引き続きカーネルモジュールの守備範囲です。eBPFはカーネルモジュールの完全な置き換えではなく、安全性と可搬性が求められるユースケースでの「第一選択肢」になった、と捉えるのが正確でしょう。

この違いを押さえておけば、「なぜ各社はカーネルモジュールではなくeBPFを選んだのか」という今回のテーマの核心への答えも見えてきます。次章では、eBPFで具体的に何ができるのか、3大ユースケースを見ていきます。

eBPFで何ができる?——オブザーバビリティ・セキュリティ・ネットワーキングの3大ユースケース

eBPFの仕組みがわかったところで、次に気になるのは「実際に何に使えるのか」という点でしょう。eBPFのユースケースは多岐にわたりますが、代表的なものは次の3つに集約されます。

  • オブザーバビリティ:低オーバーヘッドできめ細かなカーネルレベルの観測
  • セキュリティ:ランタイムのポリシー強制と攻撃の未然防止
  • ネットワーキング:ロードバランシングやKubernetesのデータプレーン高速化

以下、それぞれのユースケースを具体的に見ていきます。

オブザーバビリティ:カーネルレベルを低オーバーヘッドで観測する

従来、システムの内部挙動を調べるには、アプリケーションに計装(instrumentation)を追加するか、straceのような重いツールを使うしかありませんでした。前者はコード変更の手間と対応言語の制約があり、後者はトレース対象の動作そのものを大幅に遅くしてしまう問題があります。

eBPFを使うと、システムコール・ファイルI/O・ネットワーク通信といったカーネルレベルのイベントを、JITコンパイルされたネイティブ同等の速度でフックし、必要な統計だけをMaps経由で取り出せます。本番環境にそのまま適用できるレベルの低オーバーヘッドで、プロセスの実行、ブロックI/Oのレイテンシ分布、TCPの再送状況など、「これまでカーネルの外からは見えなかった情報」を取得できるのです。

この特性は商用オブザーバビリティ基盤でも活用されています。New Relicをはじめ、さまざまなオブザーバビリティプラットフォームがeBPFを利用し、アプリケーションのコードを一切変更せず(zero-instrumentation)にサービス間の通信やレイテンシを自動検出しています。具体的なツール(bpftrace、BCC、eBPF Exporterなど)は後のセクションで詳しく比較します。

セキュリティ:実行時ポリシー強制と攻撃の未然防止

セキュリティ分野では、eBPFは単なる「監視」を超えて、**ランタイム強制(runtime enforcement)**に使われる点が特徴です。コンテナやプロセスのふるまいをカーネルレベルで監視し、不正なファイルアクセスや危険なシステムコール実行を検知した段階で、リアルタイムにブロックできます。

代表的なのがCiliumのサブプロジェクトであるTetragonです。プロセス実行・ネットワーク通信・ファイルアクセスをeBPFでキャプチャし、ポリシー違反をカーネル空間で直接強制します。カーネルレベルで強制するため、ユーザ空間のエージェントを狙うTOCTOU(Time-Of-Check-Time-Of-Use)攻撃の影響を受けにくい、という技術的な強みもあります。

「不正な検知ログを後から解析する」のではなく「カーネルが実行そのものを止める」。この差が、ゼロデイ攻撃やコンテナ脱走への対策として評価されている理由です。

ネットワーキング:ロードバランシングからkube-proxy置換まで

eBPFの名前にも残る「パケットフィルタ」の血統が最も色濃いのが、ネットワーキング用途です。カーネル内でパケット処理と転送ロジックを直接動かせるため、ユーザ空間を経由する従来方式より高効率なロードバランシングやトラフィック制御が実現できます。

中でも象徴的なのが、Kubernetesのデータプレーンです。Cilium(CNCFプロジェクト)はeBPFベースのデータプレーンにより、eBPFハッシュテーブルを使った分散ロードバランシングを実装し、kube-proxyを完全に置き換えられます。さらにL3〜L7のネットワークポリシー、アイデンティティベースのセキュリティモデル、Ingress/Egress Gateway、帯域管理、Service Mesh機能まで提供する、クラウドネイティブネットワーキングの代表的ソリューションになっています。

このアプローチはクラウドベンダーにも採用されています。AWSのEKS標準CNI(VPC CNI)はeBPFを活用したネットワーキングを実装し、AzureもAKS向けにCiliumベースのマネージドCNI(Azure CNI Powered by Cilium)を提供しています。

3大ユースケースまとめ

ユースケース できること 代表例
オブザーバビリティ 低オーバーヘッドなカーネルレベル観測・トレーシング bpftrace、BCC、New Relic eBPF
セキュリティ ランタイム監視とリアルタイム強制、TOCTOU耐性 Tetragon
ネットワーキング 高効率ロードバランシング、kube-proxy置換、L3-L7ポリシー Cilium、VPC CNI(AWS)

3つのユースケースは独立しておらず、たとえばCiliumはネットワーキングとオブザーバビリティを、Tetragonはセキュリティとオブザーバビリティを兼ね備えるなど、実際のツールは複数領域をまたいでいます。次のセクションでは、これらのツールを個別に比較し、選び方の指針を示します。

主要ツール徹底比較——bpftrace/BCC/Cilium/Tetragon

eBPFで「何ができるか」がわかったところで、次の疑問は「実際にはどのツールを使えばいいのか」でしょう。結論から言うと、単発のトラブルシューティングならbpftrace、継続的な観測基盤ならBCC系ツールとeBPF Exporter、KubernetesのネットワーキングならCilium、KubernetesのセキュリティならTetragon——という使い分けが基本になります。

まず主要ツールを1つずつ紹介し、そのあと比較表と選び方の指針をまとめます。

bpftraceとは?——ワンライナーで書ける高レベルトレーシング言語

bpftraceは、Linux向けの高レベルなトレーシング言語です。awk、C、そして先達であるDTraceやSystemTapの影響を受けた簡潔な構文でeBPFプログラムを記述でき、LLVMをバックエンドにバイトコードへコンパイルし、カーネルの各種フックポイント(kprobe・uprobe・tracepoint)にアタッチします(公式ドキュメントではカーネル4.x以降を対応範囲としています)。

最大の特徴は「ワンライナー」で書ける手軽さです。1行のコマンドで「全システムコールの呼び出し回数を集計する」「特定プロセスのファイルオープンを追う」といった観測ができ、対話的にトラブルシューティングを進められます。スクリプトをファイルに保存すれば、定型監視に使い回すことも可能です。「まずeBPFに触れてみたい」人にとって、最も入り口として適したツールと言えるでしょう。

BCCとは?——PythonでeBPFプログラムを組むフレームワーク

BCC(BPF Compiler Collection)は、eBPFプログラムを埋め込んだPythonプログラムを書けるフレームワークです。Pythonコード内に記述したC風のeBPFコードを実行時にバイトコードとして生成・ロードするため、集計ロジックや出力整形まで含めた本格的なプロファイリング/トレーシングツールを自分で構築できます。

また、BCC(およびlibbpf-tools)にはbiolatency(ブロックI/Oレイテンシ)やexecsnoop(プロセス実行の監視)といった定番ツール群が同梱されています。「自分で書かなくても、まず定番ツールを使いたい」という場合にもBCCは有用です。bpftraceより記述量は増えますが、柔軟性と拡張性で勝る、中級者以上向けの選択肢です。

Ciliumとは?——eBPFデータプレーンを持つKubernetes CNI

ここまでの2つが「観測」寄りだったのに対し、Ciliumはネットワーキングが主戦場です。CNCFプロジェクトであり、eBPFベースのデータプレーンを持つ、KubernetesのCNI(コンテナネットワークインターフェース)です。

L3のフラットネットワーク構成に加え、L3〜L7のネットワークポリシーとアイデンティティベースのセキュリティモデルを提供します。象徴的な機能が、eBPFハッシュテーブルによる分散ロードバランシングで、kube-proxyを完全に置き換えられる点です。さらにIngress/Egress Gateway、帯域管理、Service Mesh機能まで備えており、単なるCNIを超えた、クラウドネイティブネットワーキングの統合ソリューションになっています。AWSやAzureのマネージドCNIにも採用されている、実績のある選択肢です。

Tetragonとは?——Kubernetes対応のセキュリティ観測とランタイム強制

TetragonはCiliumのサブプロジェクトで、CNCFプロジェクトとして提供されるKubernetes対応のセキュリティ・オブザーバビリティツールです。プロセス実行・ネットワーク通信・ファイルアクセスをeBPFでキャプチャし、その結果をJSONログとgRPCエンドポイントで公開します。

最大の特長は、単なる監視ではなくランタイム強制(runtime enforcement)ができる点です。eBPFでポリシーとフィルタリングをカーネル内で直接適用するため、低オーバーヘッドかつリアルタイムにポリシー違反をブロックできます。カーネルレベルで強制するため、ユーザ空間のエージェントを狙うTOCTOU(Time-Of-Check-Time-Of-Use)攻撃の影響を受けないという技術的な強みも持ちます。導入はHelm 1コマンドで完了します。

eBPF Exporterとは?——自作eBPFメトリクスをPrometheusに連携

eBPF Exporter(cloudflare/ebpf_exporter)は、Cloudflareが開発・公開しているPrometheus Exporterです。自作したeBPFコードから、通常はカーネルの外から取得できないメトリクスをPrometheus形式でエクスポートできます。コンセプトは「bcc tools as prometheus metrics」——BCC系ツールで見ている情報をそのまま監視基盤に乗せる、という発想です。

libbpfベースで実装されており、たとえばブロックI/Oレイテンシ(biolatency)の分布をPrometheusメトリクス化し、Grafanaで可視化するような構成が組めます。「eBPFで取ったデータを既存の監視スタックにつなげたい」場合の定番です。

Pixieとは?——K8s自動計装のオブザーバビリティ(プロジェクト状況に注意)

Pixieは、eBPFベースのKubernetes自動計装型オブザーバビリティツールです。アプリケーションのコードを変更せずに、クラスター内のサービス間通信やレイテンシを自動的に可視化できます。

ただし、PixieはCNCF Sandboxプロジェクトで、2023年にNew Relicへ寄贈された経緯があり、プロジェクトの状況が変化している可能性に注意が必要です。採用を検討する場合は、公式リポジトリで最新の開発状況を必ず確認してください。

ツール比較表——bpftrace/BCC/Cilium/Tetragon/eBPF Exporter/Pixie

主要ツールの位置づけを比較表にまとめました。

ツール 分類 主な用途 向いている環境 特徴
bpftrace 高レベルトレーシング言語 トラブルシューティング、単発の観測 Linuxホスト(カーネル4.x以降) ワンライナーで手軽に書ける。awk/DTrace系の構文
BCC Pythonフレームワーク プロファイリング、トレーシング、定番ツール利用 Linuxホスト biolatencyやexecsnoopなどの定番ツール群を同梱。柔軟性が高い
Cilium CNI/ネットワーキング K8sネットワーキング、L3-L7ポリシー Kubernetes eBPFデータプレーンでkube-proxyを完全置換可能。CNCFプロジェクト
Tetragon セキュリティ/観測 ランタイム強制、K8sセキュリティ監視 Kubernetes カーネルレベル強制でTOCTOU耐性。Helm 1コマンドで導入
eBPF Exporter Prometheus Exporter 自作eBPFメトリクスの監視基盤連携 Linuxホスト/K8s Cloudflare開発、libbpfベース
Pixie 自動計装オブザーバビリティ K8sのサービス間通信の自動可視化 Kubernetes コード変更不要。ただしプロジェクト状況の変化に注意

どのツールを選べばいい?——選び方の指針

ツール選びで迷ったら、次の2つの軸で判断するのが実践的です。

軸1:どのレイヤで観測したいか

  • ホスト単体・今すぐ原因を知りたい → bpftraceのワンライナー
  • 継続的にプロファイリングしたい/定番ツールを使いたい → BCC(libbpf-tools)
  • 取得したメトリクスを監視基盤につなぎたい → eBPF Exporter + Prometheus + Grafana

軸2:Kubernetes環境かどうか

  • K8sのネットワーキング・ポリシーが主関心 → Cilium
  • K8sのセキュリティ監視・ランタイム強制が主関心 → Tetragon
  • K8sを低負荷で丸ごと観測したい(SaaSでよい) → 商用のeBPFオブザーバビリティ基盤も選択肢

なお、これらは排他ではありません。実際の現場では「ホスト側はbpftraceで突発調査、メトリクスはeBPF Exporter、K8sはCilium+Tetragon」といった組み合わせで運用されることも珍しくありません。

次のセクションでは、これらのツールを「今日から」実際に試す手順を、ステップバイステップで解説します。

今日から始めるeBPFオブザーバビリティ——ステップバイステップガイド

仕組みとツールの全体像が見えたところで、次は実践です。ここからは、手元のLinuxマシンでのワンライナー体験から始めて、Kubernetesクラスタへの導入、Prometheus/Grafanaでの可視化、さらに商用基盤の活用まで、6つのステップで段階的に進めます。すべてを一度に導入する必要はありません。Step 1〜2だけでも、eBPFの「体感」は十分に得られます。

Step 1: 環境を確認する(カーネル4.x以降・root/CAP_BPF)

まず前提となる環境を確認しましょう。eBPF利用の最小要件は機能・ツールごとに異なります(bpftraceはカーネル4.x以降、リングバッファなど新しめの機能やTetragon等のツールはより新しいカーネルを推奨)。できれば5.x以降の新しいカーネルを使うと、利用できるヘルパー関数や機能が充実し、ツールとの互換性も高まります。

# カーネルバージョンの確認
uname -r
# 出力例: 6.1.0-18-amd64

次に権限です。eBPFプログラムのロードには特権が必要で、具体的にはroot、またはCapabilityのCAP_BPFを持っている必要があります。これは検証器(Verifier)がプログラムロード時の最初のチェックとして特権を要求するためです。

# rootでない場合は、CAP_BPFを持っているか確認
capsh --print | grep cap_bpf

はじめて試す段階では、本番環境ではなく検証用のLinuxマシンやVM、コンテナを用意するのが安全です。ツールのインストールと動作確認が済んでから、段階的に本番へ展開しましょう。

Step 2: bpftraceのワンライナーで初めてのトレース

環境が整ったら、bpftraceで最初のトレースを体験します。bpftraceはeBPF用の高レベルトレーシング言語で、awkやC、DTraceの影響を受けた記法で、ワンライナー(1行プログラム)から使い始められます。多くのディストリビューションでパッケージが提供されています。

# Debian/Ubuntu系の例
sudo apt install bpftrace

定番の「最初の一撃」は、システムコールの呼び出し回数をプローブごとに集計するワンライナーです。

sudo bpftrace -e 'tracepoint:syscalls:sys_enter_* { @[probe] = count(); }'

この1行で、全システムコールの入口(sys_enter_*)にフックし、呼び出された回数を集計(count())して表示します。数十秒動かしてCtrl+Cで止めると、頻繁に呼ばれているシステムコールのランキングが表示されるはずです。カーネルの再起動もソース変更もなしに、カーネル内部のイベントを数えられた——これがeBPFオブザーバビリティの体験です。

Step 3: BCC/libbpf-toolsの定番ツールを使う

ワンライナーに慣れたら、BCC(Pythonフレームワーク)やlibbpf-toolsに同梱されている定番ツール群に手を伸ばします。これらは「何を計測するか」があらかじめ設計された完成品であり、自分でプログラムを書かなくても実用的な情報を取り出せます。

特によく使われる3つを紹介します。

# ブロックI/Oのレイテンシ分布をヒストグラム表示
sudo biolatency

# 実行されたプロセスをリアルタイムに一覧表示
sudo execsnoop

# プロセスごとのTCP送受信トラフィックを表示
sudo tcptop
  • biolatency:ディスクI/Oのレイテンシ分布を可視化します。「ストレージが遅いのか、どこが遅いのか」という問いに、ミリ秒単位の分布で答えてくれます。
  • execsnoop:新しく実行されるプロセスを次々と表示します。短命なプロセスや、不正なスクリプト実行の検知にも有効です。
  • tcptop:プロセス単位のTCP通信量を表示します。「どのプロセスが帯域を食っているのか」という調査に強力です。

たとえば夜間バッチの遅延調査なら、biolatencyでストレージレイテンシの分布を見て、execsnoopでバッチ期間中に想定外のプロセスが起きていないか確認する——こうした調査フローが、追加の計装なしで組み立てられます。

Step 4: Kubernetes環境ならTetragonを導入する

Kubernetesを運用しているなら、次の一手はTetragon(CNCFプロジェクト)の導入です。TetragonはKubernetes対応のセキュリティ・オブザーバビリティツールで、Helmを使って数コマンドでデプロイできます。

# Helmリポジトリの追加
helm repo add cilium https://helm.cilium.io

# kube-systemネームスペースにTetragonをインストール
helm install tetragon cilium/tetragon -n kube-system

インストールすると、プロセス実行・ネットワーク通信・ファイルアクセスがeBPFによってキャプチャされ、JSONログとgRPCエンドポイント経由で取り出せるようになります。既定のポリシーライブラリから観測を始められる点も、最初の導入ハードルを下げてくれます。

得られたイベントは、たとえば次のように確認できます。

# Tetragonのイベントログを確認(kubectl rolloutでPodの起動を待ってから)
kubectl logs -n kube-system -l app.kubernetes.io/name=tetragon \
  -c export-stdout -f | jq

セキュリティ観測からランタイム強制まで、カーネルレベルで一貫して扱える点がTetragonの強みです。まずは観測(監視)モードで運用し、ふるまいのベースラインを掴んでから強制ポリシーへ段階的に移行するのが現実的な進め方でしょう。

Step 5: eBPF Exporter + Prometheus + Grafanaで可視化する

「継続的にメトリクスを収集し、ダッシュボードで見たい」という段階に来たら、eBPF Exporter(cloudflare/ebpf_exporter)の出番です。Cloudflareが開発・公開しているPrometheus Exporterで、自作のeBPFプログラムから、通常はカーネルの外から取得できないメトリクスをPrometheus形式でエクスポートできます。「bcc tools as prometheus metrics」を掲げており、代表例としてbiolatency(ブロックI/Oレイテンシ)のメトリクス化があります。

設定はYAMLで記述します。biolatencyをエクスポートする設定のイメージは次のとおりです。

programs:
  - name: biolatency
    metrics:
      histograms:
        - name: block_io_latency_seconds
          help: Block I/O latency histogram
          table: io_latency
          bucket_type: log2
          bucket_min: 0
          bucket_max: 26
          labels:
            - name: disk
              size: 32
              decoders:
                - name: string

Exporterを起動したら、Prometheusのスクレイプ設定に追加します。

scrape_configs:
  - job_name: ebpf_exporter
    static_configs:
      - targets: ['localhost:9435']

あとはGrafanaでPrometheusをデータソースに指定し、ヒストグラムを可視化するだけです。これで「イベント発生時に都度トレースする」から「常時メトリクスを蓄積して傾向を見る」オブザーバビリティ運用へ進めます。

Step 6: 商用基盤(New Relic eBPF等)でコード変更ゼロの自動計装

最後は、管理コストを外部化したい場合の選択肢です。New Relic eBPF(旧称eAPM)のような商用のeBPFオブザーバビリティ基盤を検討します。

New Relic eBPFの特徴はzero-instrumentation——アプリケーションコードに一切手を入れずに、カーネルレベルのオブザーバビリティを得られる点です。Helmコマンド1つでKubernetesワークロードにeBPFエージェントをデプロイすると、ランタイム・フレームワーク・言語を問わず全サービスを自動検出します。TCP/DNSレイテンシや再送をアプリへの影響と紐付けるNetwork View、Cassandra/gRPC/HTTP/MySQL/PostgreSQL/Redisなどの主要プロトコル対応も魅力で、必要になれば完全なAPMエージェントへの移行パスも用意されています。

自前でeBPFスタックを構築・運用するリソースが確保できないチームや、複数環境を横断して観測したい組織にとって、現実的な選択肢となるでしょう。

導入チェックリスト

最後に、これから始める人が踏むべき手順をチェックリストにまとめます。

  • [ ] カーネルが4.x以降であることを確認した(uname -r)
  • [ ] rootまたはCAP_BPFの権限があることを確認した
  • [ ] 検証環境でbpftraceのワンライナーが動くことを確認した
  • [ ] biolatency/execsnoopなどの定番ツールで必要な情報が取れるか確認した
  • [ ] Kubernetes環境ならTetragonをHelmで導入し、イベントログを確認した
  • [ ] 継続計測が必要なメトリクスをeBPF Exporter + Prometheus + Grafanaで可視化した
  • [ ] 運用リソースと相談し、商用基盤(New Relic eBPF等)の採用を検討した

重要なのは「小さく始めて段階的に広げる」ことです。Step 2のワンライナーが5分で試せるのに対し、Step 5の可視化基盤構築には設計と運用の検討が必要です。まずは手元でeBPFの価値を体感し、必要に応じてステップを進めてください。

次のセクションでは、こうした取り組みが実際にどのような現場で採用されているのか、ケーススタディとして紹介します。

ケーススタディ——eBPFはどこで使われているのか

ここまでeBPFの仕組み、ツール、導入ステップを見てきました。最後に「eBPFは実際にどこで使われているのか」をケーススタディとして確認しましょう。結論から言うと、eBPFはすでに実験技術の段階を脱し、大手SaaSベンダー、3大クラウド、CDN事業者、CNCFエコシステムのいずれにも組み込まれています。あなたが今日使っているインフラのどこかで、eBPFが動いている可能性は十分にあります。

New Relic——zero-instrumentationのAPMとして

最初の事例は、この記事でも何度か登場したNew Relicです。同社は「New Relic eBPF」(旧称:eAPM)というカーネルレベルのオブザーバビリティ機能を商用製品として提供しています。

ポイントは、アプリケーション側に計装コードを1行も入れずに観測できるzero-instrumentationという設計です。具体的には次のような運用が実現します。

  • Helmコマンド1つでKubernetesワークロードにeBPFエージェントをデプロイできる
  • ランタイム・フレームワーク・プログラミング言語を問わず、稼働中のサービスを自動検出する
  • TCP/DNSレイテンシやパケット再送をアプリケーションへの影響と紐付けるNetwork Viewで、ネットワーク層とアプリ層の障害を相関分析できる
  • Cassandra、gRPC、HTTP/2、MongoDB、MySQL、PostgreSQL、Redisなどの主要プロトコルに対応する
  • 必要に応じて、完全なAPMエージェントへの移行パスも用意されている

言語ごとにエージェントを導入しコードに手を入れる従来型APMの運用コストを、カーネルレベルの一元計装で解消した好例です。「どの言語で書かれたサービスか」を気にせず観測できるのは、多言語サービスが混在するマイクロサービス環境で特に効きます。

クラウド3社——AWS・Azure・GCPでの採用

eBPFは3大クラウドのマネージドサービスにも組み込まれています。自分でeBPFプログラムを書かなくても、クラウドの基盤機能を使うだけで恩恵を受けているケースです。

  • AWS: EKSの標準CNIであるVPC CNIにはeBPFを活用したネットワーキングが実装されています。また、脅威検出サービスのGuardDutyが提供するEKS Runtime Monitoringでは、eBPFベースのランタイム監視が使われています。
  • Microsoft Azure: AKS向けに、eBPFデータプレーンを持つCiliumをベースにした「Azure CNI Powered by Cilium」をマネージドCNIとして提供しています。
  • Google Cloud(GKE): CNIのデータプレーンにeBPFを活用した構成が提供されており、DatadogやGrafana Labsなど主要なオブザーバビリティベンダーの製品群もeBPFを利用しています。

注目すべきは、これらが「eBPFを使っている」とユーザーに意識させない形で提供されている点です。ロードバランシング、ネットワークポリシー、ランタイムセキュリティといった機能の裏側で、eBPFが低オーバーヘッドなカーネルレベル処理を担っています。ebpf.ioが「多くの重要なソフトウェアインフラストラクチャの中核」と表現する通り、eBPFはすでにインフラの前提条件になりつつあります。

Cloudflare——ebpf_exporterの開発・公開

CDNとセキュリティで世界規模のトラフィックを処理するCloudflareも、eBPFを活用する代表例です。同社は自社の計測ニーズのためにebpf_exporterを開発し、オープンソースとして公開しています。

ebpf_exporterは、自作のeBPFプログラムから「通常はカーネルから取得できないメトリクス」をPrometheus形式でエクスポートするツールです。「bcc tools as prometheus metrics」(BCCツールをPrometheusメトリクスとして使う)をコンセプトに、libbpfベースで実装されています。Step 5で紹介したbiolatency(ブロックI/Oレイテンシ)の可視化も、この組み合わせの典型例です。

大規模トラフィックを運用する事業者が、自社の観測課題を解決するために書いたコードを公開し、コミュニティがそれを使える——eBPFエコシステムの健全な成長サイクルを示す事例と言えます。

Cilium / Tetragon——CNCFエコシステムでの標準化

最後は、オープンソース側の事例です。eBPFベースのネットワーキング・セキュリティ・オブザーバビリティソリューションであるCiliumは、CNCF(Cloud Native Computing Foundation)にホストされるプロジェクトとして急速に採用を拡大しています。

Ciliumのデータプレーンは、eBPFハッシュテーブルを活用した分散ロードバランシングでkube-proxyを完全置換できることが特徴です。L3のフラットネットワーク、L3〜L7のネットワークポリシー、アイデンティティベースのセキュリティモデル、Ingress/Egress Gateway、帯域管理、Service Meshまで、Kubernetesネットワーキングに必要な機能をeBPFで一貫して実装しています。最新バージョンはCilium公式のGitHub Releasesで確認してください(執筆確認時点ではv1.20.x系)。

そのサブプロジェクトであるTetragonも、CNCFプロジェクトとしてKubernetes向けのセキュリティ・オブザーバビリティとランタイム強制を担っています。プロセス実行・ネットワーク通信・ファイルアクセスをeBPFでキャプチャし、JSONログとgRPCエンドポイントで公開。カーネルレベルでポリシーを強制するため、TOCTOU(Time-Of-Check to Time-Of-Use)攻撃の影響を受けない点が評価されています。前述のAzure CNI Powered by Ciliumのように、クラウドベンダーがCiliumを採用する例も出ており、OSSとクラウドの両面で採用が広がっています。

ケーススタディのまとめ

提供元 製品・機能 eBPFの活用領域
New Relic New Relic eBPF(旧eAPM) zero-instrumentationなオブザーバビリティ
AWS VPC CNI / GuardDuty ネットワーキング・ランタイムセキュリティ
Microsoft Azure Azure CNI Powered by Cilium マネージドCNI(ネットワーキング)
Google Cloud / その他ベンダー GKEのCNI・Datadog等の製品 ネットワーキング・オブザーバビリティ
Cloudflare ebpf_exporter カスタムメトリクスの収集・公開
CNCF(Ciliumコミュニティ) Cilium / Tetragon CNI・kube-proxy置換・ランタイム強制

※(注)クラウド各社の採用状況は執筆時点の情報です。詳細な構成や対応範囲は各社の公式ドキュメントで最新情報を確認してください。

この表から読み取れるのは、eBPFの用途が「オブザーバビリティ」「セキュリティ」「ネットワーキング」の3領域にまたがって商用・OSSの双方で採用されているという構図です。特定ベンダーのプロプライエタリな技術ではなく、Linuxカーネルという共通基盤の上に築かれたオープンな技術として、業界全体で投資が続いています。「今日から始める」価値のある技術だという根拠は、まさにここにあります。

次のセクションでは、eBPFを始めるにあたってよくある疑問をFAQ形式でまとめます。

よくある質問(FAQ)

Q. eBPFを使うのにカーネルの再ビルドや再起動は必要ですか?

A. 不要です。 これがeBPF最大の利点のひとつです。eBPFプログラムは、C言語風のコードをLLVM/clangでeBPFバイトコードにコンパイルし、bpfシステムコールを使って実行中のカーネルへ直接ロードします。カーネルのソースコード改変も、カーネルモジュールのロードも、マシンの再起動も必要ありません。ロードしたプログラムは即座にイベント駆動で動き始め、不要になればその場でアンロードできます。

Q. eBPFは安全ですか?カーネルを落としたりしませんか?

A. Verifier(検証器)がロード時に不正なメモリアクセスや非終端実行などを検査するため、安全性が高い設計です(「安全だが意図まで正しい」ことは保証しません)。 すべてのeBPFプログラムはロード時に検証器を通過する必要があります。検証器は「プログラムが必ず完了すること(無限ループの禁止)」「境界外メモリアクセスの禁止」「未初期化変数の使用禁止」「プログラムサイズと複雑さの上限」などを静的に解析します。さらにJITコンパイル後のプログラムメモリは読み取り専用で保護され、スペクター系脆弱性への緩和策やJITスプレー攻撃防止の定数隠蔽といったハードニングも施されます。

ただし一点だけ注意があります。検証器が保証するのは「安全に実行できるか」であって、「プログラムが何をするか」ではありません。悪意のある管理者が特権を持っていれば、情報収集目的のeBPFプログラムをロードすることは技術的に可能です。eBPFのロードにはroot権限またはCAP_BPFが必要なため、特権の管理がそのままセキュリティ境界になります。

Q. どのカーネルバージョンからeBPFを使えますか?

A. 基本的にはLinuxカーネル4.x以降、できれば5.x以降を推奨します。 高レベルトレーシング言語のbpftraceはカーネル4.x以降に対応しています。ただし、eBPFはカーネルのバージョンごとに機能追加が続いており、利用できるフックポイントやヘルパー関数、マップの種類はバージョンによって異なります。たとえばリングバッファ(BPF_MAP_TYPE_RINGBUF)のような比較的新しい機能は、古いカーネルでは利用できません。最近のディストリビューションであれば標準で5.x系以降が搭載されているため、特別な準備なしに始められるケースがほとんどです。

Q. eBPFはインタプリタ実行なので遅くないですか?

A. 多くの用途では、JITコンパイルによりネイティブコードに匹敵する速度で動作します。 eBPFのバイトコードは、ロード時にJITコンパイラによってマシン固有の命令セットへ実行時コンパイルされます。ebpf.ioの説明でも「ネイティブにコンパイルされたカーネルコードやカーネルモジュールと同等の実行速度」とされており、実際に本番環境のロードバランシング(Ciliumによるkube-proxy置換など)で採用されるほどです。低オーバーヘッドな観測を売りにするオブザーバビリティ製品がこぞってeBPFを採用しているのは、この速度面の信頼性があるからです。

Q. eBPFとカーネルモジュール(LKM)は何が違いますか?

A. 安全性と保守性の面で大きく異なります。 詳細は前述の比較表をご参照ください。要点を繰り返すと、カーネルモジュールは検証なしでカーネル空間で動くためバグひとつでカーネルクラッシュ(システム全体の停止)につながるのに対し、eBPFはVerifierが事前に安全性を検証します。また、カーネルモジュールはカーネルバージョンが変わるたびに再ビルドや修正が必要になりがちですが、eBPFはカーネルが提供するヘルパー関数を経由してカーネルとやり取りし、CO-REなどの技術で可搬性を高めているため、カーネル更新への追従コストが低い傾向があります。一方でデバイスドライバのようにハードウェアを直接制御する用途にはカーネルモジュールが今も適しており、両者は使い分ける関係にあります。

Q. Kubernetes環境で一番手軽にeBPFを始めるには?

A. TetragonをHelmで導入するのが最短ルートです。 次の2コマンドで導入できます。

helm repo add cilium https://helm.cilium.io/
helm install tetragon cilium/tetragon -n kube-system

TetragonはCNCFプロジェクトで、Kubernetes向けのセキュリティ・オブザーバビリティとランタイム強制を提供します。導入するとポリシーライブラリの既定ポリシーでプロセス実行・ネットワーク通信・ファイルアクセスの観測をすぐに開始でき、JSONログとgRPCエンドポイントで結果を取得できます。カーネルレベルでポリシーを強制するためTOCTOU(Time-Of-Check to Time-Of-Use)攻撃の影響を受けない点も実用上の利点です。

「まずは軽く試したい」だけであれば、Kubernetesクラスター外のLinuxマシンでbpftraceのワンライナーから始めるのもよい選択です。たとえば bpftrace -e 'tracepoint:syscalls:sys_enter_* { @[probe] = count(); }' の一撃でシステムコールの統計が取れます。本格的な可視化が必要になったら、eBPF ExporterでPrometheusメトリクスとしてエクスポートしGrafanaでダッシュボード化する流れが定番です。

参考文献・出典(主張別の出典台帳)

本記事の主要な主張と対応する一次資料・公式文書は以下の通りです。

本文の主張 情報源
eBPFの定義・「カーネルを安全にプログラマブルにする」説明・速度表現 ebpf.io「What is eBPF?」 https://ebpf.io/what-is-ebpf/
Verifier/JIT/Maps/ヘルパー関数の仕組み・フックポイント Linuxカーネル公式ドキュメント BPF section https://docs.kernel.org/bpf/
カーネルモジュール(LKM)との比較 Linuxカーネルモジュール概要 https://docs.kernel.org/admin-guide/modules.html
bpftraceの構文・対応カーネル bpftrace公式ドキュメント https://www.bpftrace.org/
BCCのツール群 BCC GitHub https://github.com/iovisor/bcc
Ciliumの機能・kube-proxy置換・バージョン Cilium公式 https://docs.cilium.io/(バージョンはGitHub Releasesで確認)
Tetragonのインストール・ポリシー Tetragon公式 https://tetragon.io/(namespace作成などの前提は公式インストールガイド参照)
eBPF Exporter GitHub https://github.com/cloudflare/ebpf_exporter
AWS VPC CNI(ネットワークポリシー機能のeBPF利用) AWS EKS公式ドキュメント https://docs.aws.amazon.com/eks/latest/userguide/pods-intercept.html
Azure CNI Powered by Cilium Microsoft Azure公式ドキュメント https://learn.microsoft.com/azure/aks/azure-cni-powered-by-cilium
New Relic eBPF(zero-instrumentation) New Relic公式ドキュメント https://docs.newrelic.com/
Pixie(CNCF Sandbox・New Relic寄贈) CNCF Pixie https://www.cncf.io/projects/pixie/

※ ツールの対応カーネル・機能要件は公式ドキュメントを最新版でご確認ください。

まとめ——eBPFは「カーネルを安全に拡張する」広く採用が進む技術になった

この記事の要点を振り返ります。

  • eBPFは、Linuxカーネルを再起動なしで安全に拡張する技術です。 カーネルのソースコード改変(年単位のレビューが必要)にも、壊れやすいカーネルモジュール(バグひとつでシステム全体をクラッシュさせうる)にも頼らず、bpfシステムコールでロードしたプログラムが即座にイベント駆動で動き始めます。
  • 安全性と速度は「4大要素」で両立されています。 Verifier(検証器)が無限ループや境界外アクセスを事前に排除し、JITコンパイラがネイティブコードと同等の実行速度を提供し、Mapsがユーザ空間とのデータ共有を可能にし、ヘルパー関数がカーネル機能へのアクセス経路を提供します。
  • もはや「未来の技術」ではなく、大手クラウドや商用製品で採用が進む技術です。 3大クラウドのネットワーキング基盤(EKSのVPC CNI、Azure CNI Powered by Cilium、GKE)、CNCFエコシステム(Cilium、Tetragon)、そしてNew Relicをはじめとする商用オブザーバビリティ製品にまで採用されています。Linux/Kubernetes運用者にとって、eBPFへの理解が求められる場面が増えています。

ひとつだけ忘れないでほしい注意点があります。Verifierが保証するのは「安全に実行できるか」であって「プログラムが何をするか」ではありません。eBPFのロードにはroot権限またはCAP_BPFが必要なため、特権の管理がそのままセキュリティ境界になります。強力な技術であるぶん、権限の設計は慎重に行いましょう。

次のアクション——今日から始める最短ルート

理解は「動かしてみる」ことで深まります。環境に合わせて、次の一歩を選んでください。

  1. 定番ツールで実務観測を始めたい(単体Linuxマシン): BCC / libbpf-toolsの biolatency(ブロックI/Oレイテンシ)や execsnoop(プロセス実行の監視)を試してください。障害調査や性能分析にすぐ役立ちます。
  2. 可視化まで作り込みたい: CloudflareのeBPF Exporterで独自メトリクスをPrometheusに送り、Grafanaでダッシュボード化しましょう。
  3. コード変更ゼロでアプリ全体を見たい: New Relic eBPFのような商用基盤の導入を検討する価値があります。Helmコマンド1つで、言語・ランタイム・フレームワークを問わず全サービスを自動検出できます。

Kubernetesクラスターがある: TetragonをHelmで導入しましょう。2コマンドでプロセス実行・ネットワーク通信・ファイルアクセスの観測が始まります。

helm repo add cilium https://helm.cilium.io/
helm install tetragon cilium/tetragon -n kube-system

まず5分で体験したい(単体Linuxマシン): bpftraceをインストールし、次のワンライナーを実行してみましょう。

bpftrace -e 'tracepoint:syscalls:sys_enter_* { @[probe] = count(); }'

システムコールの統計がリアルタイムで集計される様子に、「カーネルの中を覗いている」感覚を掴めるはずです。

どのルートを選ぶにしても、最初のハードルは「ワンライナー1行」です。カーネルは再起動不要、カーネルの知識がなくても大丈夫。まずはあなたの環境で、eBPFの一撃を試してみてください。

関連記事