Skip to content
Published on

eBPF完全ガイド2025:カーネルプログラミング、Observability、ネットワーキング、セキュリティの革命

Authors

TL;DR

  • eBPFはLinuxカーネルの安全(あんぜん)なプログラミング環境(かんきょう)。カーネルコード変更(へんこう)なしにトレーシング/ネットワーキング/セキュリティ機能(きのう)を追加(ついか)
  • 3大活用(だいかつよう)分野(ぶんや):Observability(Pixie/Parca)、Networking(Cilium/XDP)、Security(Falco/Tetragon)
  • CO-RE:一度(いちど)コンパイルすれば様々(さまざま)なカーネルバージョンで実行(じっこう) — デプロイ負担(ふたん)を排除(はいじょ)
  • bpftrace:DTraceのような高水準(こうすいじゅん)言語(げんご)で即席(そくせき)トレーシング
  • XDP:ネットワークカードレベルでパケット処理(しょり) — Cloudflareがdocsで使用(しよう)(毎秒(まいびょう)1千万(せんまん)+ パケット)

1. eBPFとは何か?

1.1 一行(いちぎょう)定義(ていぎ)

eBPFはオペレーティングシステムカーネルを修正(しゅうせい)せずにカーネル内部(ないぶ)でサンドボックス化(か)されたプログラムを実行(じっこう)できる技術(ぎじゅつ)である。

伝統的(でんとうてき)にカーネル機能(きのう)を拡張(かくちょう)するには2つの方法(ほうほう)しかありませんでした:

  1. カーネル自体(じたい)にコード追加(ついか) → 貢献(こうけん)が難(むずか)しく、マージされてもユーザーは新(あたら)しいカーネルバージョンを待(ま)たなければならない
  2. カーネルモジュールのロード → 誤(あやま)って書(か)くとシステムクラッシュの危険(きけん)。カーネルABI変更(へんこう)に脆弱(ぜいじゃく)

eBPFは第三(だいさん)の道(みち)を提示(ていじ)します — カーネル内(ない)で安全(あんぜん)にカスタムコードを実行(じっこう)

1.2 どのように安全性(あんぜんせい)を保証(ほしょう)するか?

eBPFプログラムはカーネルにロードされる前(まえ)、**BPF Verifier(検証器(けんしょうき))**の静的(せいてき)解析(かいせき)を通過(つうか)しなければなりません:

  • 終了(しゅうりょう)保証(ほしょう):無限(むげん)ループ禁止(きんし)(バックワードジャンプ制限(せいげん))
  • メモリ安全性(あんぜんせい):すべてのポインタアクセスを追跡(ついせき)、境界(きょうかい)検査(けんさ)
  • 関数(かんすう)呼(よ)び出(だ)し制限(せいげん):許可(きょか)されたヘルパー関数(かんすう)のみ呼(よ)び出(だ)し可能(かのう)
  • スタックサイズ:最大(さいだい)512バイト
  • 命令(めいれい)数(すう):100万(まん)以下(いか)(カーネル5.2+)

検証器(けんしょうき)通過(つうか)後(ご)、JITコンパイラがネイティブマシンコードに変換(へんかん)してほぼネイティブ速度(そくど)で実行(じっこう)されます。

1.3 cBPFからeBPFへの進化(しんか)

特性(とくせい)cBPF (1992)eBPF (2014~)
用途(ようと)パケットフィルタリングのみ汎用(はんよう)カーネルプログラミング
レジスタ2個(こ)(32ビット)11個(こ)(64ビット)
命令(めいれい)22個(こ)100+
ヘルパー関数(かんすう)なし200+
マップなし30+ 種類(しゅるい)
JIT一部(いちぶ)アーキテクチャほとんどのアーキテクチャ

tcpdumpが使用(しよう)したcBPFは単純(たんじゅん)なパケットフィルタでしたが、eBPFは小型(こがた)仮想(かそう)マシンに進化(しんか)しました。


2. eBPFアーキテクチャ深層(しんそう)分析(ぶんせき)

2.1 コンポーネント概要(がいよう)

┌─────────────────────────────────────────────┐
ユーザー空間(くうかん) (User Space)│  ┌──────────┐  ┌──────────┐  ┌──────────┐  │
│  │ bpftool  │  │ bpftrace │  │ Cilium   │  │
│  └────┬─────┘  └────┬─────┘  └────┬─────┘  │
│       │             │             │         │
│       └─────────────┼─────────────┘         │
│                     │ bpf() syscall          │
└─────────────────────┼───────────────────────┘
┌─────────────────────────────────────────────┐
カーネル空間(くうかん) (Kernel Space)│  ┌─────────────────────────────────────┐   │
│  │  BPF Verifier                       │   │
│  └──────────────┬──────────────────────┘   │
│                 ▼                            │
│  ┌─────────────────────────────────────┐   │
│  │  JIT Compiler                       │   │
│  └──────────────┬──────────────────────┘   │
│                 ▼                            │
│  ┌─────────────────────────────────────┐   │
│  │  Hooks: kprobe, tracepoint, XDP,    │   │
│  │  perf_event, socket, cgroup, LSM    │   │
│  └─────────────────────────────────────┘   │
└─────────────────────────────────────────────┘

2.2 主要(しゅよう)フック種類(しゅるい)

eBPFプログラムは様々(さまざま)なカーネルイベントにアタッチできます:

フック種類(しゅるい)説明(せつめい)例(れい)
kprobe / kretprobeカーネル関数(かんすう)進入(しんにゅう)/終了(しゅうりょう)do_sys_open呼(よ)び出(だ)し追跡(ついせき)
uprobe / uretprobeユーザー空間(くうかん)関数(かんすう)OpenSSLのSSL_read追跡(ついせき)
tracepointカーネル静的(せいてき)追跡(ついせき)ポイントsched:sched_switch
perf_eventハードウェア/ソフトウェアカウンタCPUサイクル、キャッシュミス
XDPネットワークドライバDDoSフィルタリング
TC (Traffic Control)トラフィックシェーピングQoS、ロードバランシング
LSMセキュリティポリシーファイルアクセス制御(せいぎょ)

2.3 BPF Maps — 核心(かくしん)データ構造(こうぞう)

eBPFプログラムとユーザー空間(くうかん)間(かん)のデータ共有(きょうゆう)はBPF Mapsを通(つう)じて行(おこな)われます:

マップ種類(しゅるい)用途(ようと)
BPF_MAP_TYPE_HASH一般(いっぱん)的(てき)なキー値(ち)保存(ほぞん)
BPF_MAP_TYPE_ARRAY配列(はいれつ)(インデックスベース)
BPF_MAP_TYPE_PERF_EVENT_ARRAYユーザー空間(くうかん)へのイベントストリーミング
BPF_MAP_TYPE_RINGBUFより効率的(こうりつてき)なイベントストリーミング
BPF_MAP_TYPE_LRU_HASHLRUキャッシュ
BPF_MAP_TYPE_LPM_TRIE最長(さいちょう)プレフィックス一致(いっち)

3. 開発(かいはつ)ツール比較(ひかく)

3.1 BCC (BPF Compiler Collection)

  • 言語(げんご):BPFはC、ユーザー空間(くうかん)はPython/Lua
  • 長所(ちょうしょ):豊富(ほうふ)なツール(bcc-toolsパッケージに100+ツール)
  • 短所(たんしょ):コンパイラ依存性(いぞんせい)(実行(じっこう)時(じ)にLLVM必要(ひつよう))、大(おお)きなバイナリ

3.2 bpftrace — DTraceの後継者(こうけいしゃ)

  • 言語(げんご):高水準(こうすいじゅん)awkのようなDSL
  • 用途(ようと):即席(そくせき)トレーシング、デバッグ
  • 長所(ちょうしょ):1行(ぎょう)で強力(きょうりょく)な分析(ぶんせき)
# プロセス別(べつ)システムコール呼(よ)び出(だ)し回数(かいすう)
bpftrace -e 'tracepoint:syscalls:sys_enter_* { @[comm] = count(); }'

# 1秒(びょう)以上(いじょう)かかるread()システムコール追跡(ついせき)
bpftrace -e '
kprobe:vfs_read { @start[tid] = nsecs; }
kretprobe:vfs_read /@start[tid]/ {
    $duration = nsecs - @start[tid];
    if ($duration > 1000000000) {
        printf("%s pid %d took %d ms\n", comm, pid, $duration / 1000000);
    }
    delete(@start[tid]);
}'

3.3 libbpf + CO-RE — 本番(ほんばん)標準(ひょうじゅん)

  • CO-RE:BTFでカーネル構造体(こうぞうたい)情報(じょうほう)を埋(う)め込(こ)み → 様々(さまざま)なカーネルバージョンで動作(どうさ)
  • 長所(ちょうしょ):小(ちい)さなバイナリ、コンパイラ依存性(いぞんせい)なし、高速(こうそく)起動(きどう)
  • 短所(たんしょ):学習(がくしゅう)曲線(きょくせん)

3.4 ツール比較(ひかく)表(ひょう)

ツール学習(がくしゅう)曲線(きょくせん)性能(せいのう)デプロイ容易性(よういせい)適切(てきせつ)な用途(ようと)
BCC中(ちゅう)中(ちゅう)難(むずか)しい学習(がくしゅう)、一回性(いっかいせい)分析(ぶんせき)
bpftrace易(やさ)しい高(たか)い中(ちゅう)即席(そくせき)トレーシング
libbpf + CO-RE難(むずか)しい非常(ひじょう)に高(たか)い易(やさ)しい本番(ほんばん)ツール開発(かいはつ)
Aya (Rust)難(むずか)しい非常(ひじょう)に高(たか)い易(やさ)しいRustエコシステム統合(とうごう)

4. eBPFの3大(だい)活用(かつよう)分野(ぶんや)

4.1 Observability — 観測性(かんそくせい)

eBPFはアプリケーションコード変更(へんこう)なしにシステム動作(どうさ)を深(ふか)く観察(かんさつ)します。

Pixie — Kubernetes Native Observability

  • New Relicが買収(ばいしゅう)したオープンソースプロジェクト
  • サイドカーなしですべてのPodのHTTP/gRPC/MySQLリクエスト自動(じどう)追跡(ついせき)
  • BPFコードがOpenSSLのSSL_read/SSL_writeにuprobeをアタッチして暗号化(あんごうか)前(まえ)のデータをキャプチャ

Parca — Continuous Profiling

  • 本番(ほんばん)で24/7 CPUプロファイリング
  • オーバーヘッド1%未満(みまん)
  • Polar Signalsが開発(かいはつ)したオープンソース

4.2 Networking — ネットワーキング

Cilium — eBPFベースK8sネットワーキングの標準(ひょうじゅん)

  • CNCF Graduatedプロジェクト
  • kube-proxyを完全(かんぜん)に置換(ちかん) — iptables代(か)わりにeBPFでサービスルーティング
  • L7ポリシー(HTTP、gRPC、Kafka)サポート
  • Hubble:Ciliumベースネットワークオブザーバビリティ

XDP — 超高速(ちょうこうそく)パケット処理(しょり)

XDPはネットワークドライバレベルでパケットを処理(しょり)します — カーネルネットワークスタックを通過(つうか)しません。

  • Cloudflare:DDoS防御(ぼうぎょ)にXDP使用(しよう) — 毎秒(まいびょう)1千万(せんまん)+ パケットフィルタリング
  • Facebook Katran:L4ロードバランサー — 単一(たんいつ)サーバーで200Gbps処理(しょり)

4.3 Security — セキュリティ

Falco — ランタイムセキュリティ監視(かんし)

  • CNCF Incubating
  • システムコールとK8sイベントを追跡(ついせき)して異常(いじょう)行動(こうどう)検知(けんち)
  • ルールベース(Sysdigフィルタ言語(げんご))

Tetragon — Ciliumチームの次世代(じせだい)セキュリティ

  • eBPFベースセキュリティオブザーバビリティ + ランタイム強制(きょうせい)
  • システムコールだけでなくLSMフックも活用(かつよう)
  • **リアルタイム遮断(しゃだん)**可能(かのう)(Falcoは検知(けんち)のみ)

5. 実践(じっせん):bpftraceでデバッグする

5.1 シナリオ:ディスクI/Oが急(きゅう)に遅(おそ)くなった

# 1. どのプロセスがディスクI/Oを引(ひ)き起(お)こしているか?
sudo bpftrace -e '
tracepoint:block:block_rq_issue {
    @[comm] = count();
}
interval:s:5 {
    print(@);
    clear(@);
}'

5.2 シナリオ:未知(みち)のファイルが開(ひら)かれている

sudo bpftrace -e '
tracepoint:syscalls:sys_enter_openat {
    printf("%s opened: %s\n", comm, str(args->filename));
}'

6. CO-RE:一度(いちど)コンパイル、どこでも実行(じっこう)

6.1 問題(もんだい):カーネルバージョンごとに構造体(こうぞうたい)が異(こと)なる

伝統的(でんとうてき)なBCCは実行(じっこう)時点(じてん)でカーネルヘッダを使用(しよう)してコンパイルしました。しかしコンテナではホストカーネルヘッダにアクセスしにくく、コンパイル時間(じかん)も長(なが)かったです。

6.2 解決策(かいけつさく):BTF + CO-RE

BTF:カーネルが自分(じぶん)の構造体(こうぞうたい)情報(じょうほう)を/sys/kernel/btf/vmlinuxに公開(こうかい)します。

CO-RE:コンパイラが構造体(こうぞうたい)フィールドアクセスを「シンボリック」に表現(ひょうげん)し、ローダーがランタイムにBTF情報(じょうほう)で再配置(さいはいち)します。

効果(こうか):一度(いちど)ビルドした.oファイルが5.4から6.5まですべてのカーネルで動作(どうさ)。


7. 本番(ほんばん)事例(じれい)

7.1 Netflix — bpftraceで性能(せいのう)デバッグ

NetflixのBrendan Greggは最(もっと)も影響力(えいきょうりょく)のあるeBPF擁護者(ようごしゃ)です。Netflixは数万(すうまん)個(こ)のEC2インスタンスでBCCとbpftraceを活用(かつよう)して:

  • off-CPU分析(ぶんせき):プロセスがなぜ止(と)まっているか追跡(ついせき)
  • TCP再送信(さいそうしん)追跡(ついせき):マイクロサービス間(かん)ネットワーク問題(もんだい)診断(しんだん)
  • ファイルシステム遅延(ちえん)時間(じかん):どのファイルが遅(おそ)いか即時(そくじ)識別(しきべつ)

7.2 Cloudflare — XDPでDDoS防御(ぼうぎょ)

  • 2017年(ねん)導入(どうにゅう)後(ご)持続的(じぞくてき)に拡張(かくちょう)
  • L4Drop:毎秒(まいびょう)数千万(すうせんまん)パケットの悪性(あくせい)トラフィックをネットワークドライバレベルで遮断(しゃだん)
  • iptables対比(たいひ)10倍(ばい)以上(いじょう)の効率(こうりつ)
  • CPU使用量(しようりょう)削減(さくげん)でインフラコスト30%削減(さくげん)

7.3 Meta (Facebook) — すべての場所(ばしょ)でeBPF

  • Katran:L4ロードバランサー(XDPベース)
  • DCCPプロファイリング:データセンター全般(ぜんぱん)の性能(せいのう)分析(ぶんせき)

7.4 Google — Ciliumを利用(りよう)したGKE Dataplane V2

  • GKE Dataplane V2はCiliumベース
  • iptablesベースkube-proxyを完全(かんぜん)に置換(ちかん)
  • クラスタ規模(きぼ)が大(おお)きくなっても一定(いってい)の性能(せいのう)

8. eBPFの限界(げんかい)と挑戦(ちょうせん)

8.1 検証器(けんしょうき)の制約(せいやく)

  • 命令(めいれい)数(すう)制限(せいげん)(現在(げんざい)100万(まん))
  • ループ制限(せいげん)(BPF_LOOPヘルパーで緩和(かんわ)された)
  • スタックサイズ512バイト — 大(おお)きな構造体(こうぞうたい)操作(そうさ)が困難(こんなん)

8.2 カーネルバージョン依存性(いぞんせい)

  • 一部(いちぶ)の機能(きのう)は最新(さいしん)カーネル必要(ひつよう)
  • CO-REがほとんど解決(かいけつ)するが、新(あたら)しいヘルパー関数(かんすう)は依然(いぜん)としてカーネル依存的(いぞんてき)

8.3 デバッグの難(むずか)しさ

  • printf("デバッグ")は不可能(ふかのう) — bpf_printk()のみ使用(しよう)(遅(おそ)い)
  • ランタイムエラー分析(ぶんせき)が困難(こんなん)
  • 検証器(けんしょうき)エラーメッセージが難解(なんかい)

9. eBPFの未来(みらい)

9.1 BPF in Windows

MicrosoftがeBPF for Windowsを開発(かいはつ)中(ちゅう)。Windowsでも同(おな)じeBPFプログラム実行(じっこう)可能(かのう) → 真(しん)のクロスプラットフォームカーネルプログラミング。

9.2 sched_ext — スケジューラをeBPFで

カーネル6.12+で導入(どうにゅう)。CPUスケジューラ自体(じたい)をeBPFで作成(さくせい)可能(かのう) → ワークロード別(べつ)カスタムスケジューリング。


10. eBPF始(はじ)める — 学習(がくしゅう)ロードマップ

Week 1:基礎(きそ)

  • bpftool prog list — システムにロードされたBPFプログラム確認(かくにん)
  • bpftraceインストール後(ご)bpftrace/toolsを見(み)て回(まわ)る
  • 「Linux Observability with BPF」(O'Reilly)1-3章(しょう)読(よ)む

Week 2-3:BCC

  • bcc-toolsパッケージインストール
  • execsnoopopensnooptcptopのようなツール使用(しよう)
  • BCCチュートリアルで初(はじ)めてのBPFプログラム作成(さくせい)

Week 4-6:libbpf + CO-RE

  • libbpf-bootstrapクローン
  • 簡単(かんたん)なトレーシングツール作成(さくせい)(例(れい):システムコールカウンタ)
  • BTFとCO-REマクロに慣(な)れる

Week 7+:実践(じっせん)プロジェクト

  • 自分(じぶん)の本番(ほんばん)環境(かんきょう)に適用(てきよう)
  • Cilium、Falco、Pixieのうち一(ひと)つを深(ふか)く学習(がくしゅう)
  • カンファレンス:eBPF Summit、KubeCon(eBPF Day)

クイズ

1. eBPFプログラムが安全(あんぜん)と保証(ほしょう)される理由(りゆう)は何(なん)ですか?

答(こた)え:カーネルにロードされる前(まえ)、BPF Verifierが静的(せいてき)解析(かいせき)を実行(じっこう)します。無限(むげん)ループ禁止(きんし)、メモリアクセス検証(けんしょう)、許可(きょか)されたヘルパー関数(かんすう)のみ呼(よ)び出(だ)し、命令(めいれい)数(すう)制限(せいげん)などを確認(かくにん)します。検証(けんしょう)を通過(つうか)するとJITコンパイラがネイティブマシンコードに変換(へんかん)してほぼネイティブ速度(そくど)で実行(じっこう)されます。

2. CO-RE(Compile Once, Run Everywhere)が解決(かいけつ)する問題(もんだい)は?

答(こた)え:伝統的(でんとうてき)なBCCは実行(じっこう)時点(じてん)でカーネルヘッダでコンパイルする必要(ひつよう)がありました。これはLLVM依存性(いぞんせい)、長(なが)い起動(きどう)時間(じかん)、コンテナ環境(かんきょう)での困難(こんなん)を引(ひ)き起(お)こしました。CO-REはBTF(BPF Type Format)を活用(かつよう)してコンパイラが構造体(こうぞうたい)フィールドアクセスを「シンボリック」に表現(ひょうげん)し、ローダーがランタイムにBTF情報(じょうほう)で再配置(さいはいち)します。一度(いちど)ビルドした.oファイルが様々(さまざま)なカーネルバージョンで動作(どうさ)します。

3. XDPがiptablesより速(はや)い理由(りゆう)は?

答(こた)え:XDPはネットワークドライバ水準(すいじゅん)でパケットを処理(しょり)します。パケットがカーネルネットワークスタック(skb割(わ)り当(あ)て、conntrackなど)を通過(つうか)する前(まえ)に処理(しょり)するためオーバーヘッドが非常(ひじょう)に少(すく)ないです。Cloudflareは単一(たんいつ)サーバーで毎秒(まいびょう)1千万(せんまん)+ パケットを処理(しょり)し、iptables対比(たいひ)10倍(ばい)以上(いじょう)効率的(こうりつてき)です。

4. Ciliumがkube-proxyをどのように置換(ちかん)しますか?

答(こた)え:kube-proxyはiptablesまたはIPVSルールでService ClusterIPをバックエンドPodにルーティングします。クラスタが大(おお)きくなるとiptablesルールが数千個(すうせんこ)に増(ふ)え性能(せいのう)が低下(ていか)します。CiliumはeBPFプログラムがソケット作業(さぎょう)とパケット処理(しょり)で直接(ちょくせつ)バックエンドを選択(せんたく)するためiptablesルールが必要(ひつよう)ありません。結果的(けっかてき)に一定(いってい)の性能(せいのう)を維持(いじ)しCPU使用量(しようりょう)が低(ひく)いです。

5. bpftraceとlibbpfの違(ちが)いはいつ何(なに)を使用(しよう)すべきですか?

答(こた)えbpftraceは即席(そくせき)トレーシングとデバッグに適(てき)しています。DTraceのような高水準(こうすいじゅん)DSLで1行(ぎょう)で強力(きょうりょく)な分析(ぶんせき)が可能(かのう)です。libbpf + CO-REは本番(ほんばん)ツール開発(かいはつ)に適(てき)しています。小(ちい)さなバイナリ、コンパイラ依存性(いぞんせい)なし、高速(こうそく)起動(きどう)、様々(さまざま)なカーネル互換性(ごかんせい)を提供(ていきょう)します。個人(こじん)デバッグはbpftrace、デプロイするツールはlibbpfで作成(さくせい)するのが一般的(いっぱんてき)です。


参考(さんこう)資料(しりょう)