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

- Name
- Youngju Kim
- @fjvbn20031
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つの方法(ほうほう)しかありませんでした:
- カーネル自体(じたい)にコード追加(ついか) → 貢献(こうけん)が難(むずか)しく、マージされてもユーザーは新(あたら)しいカーネルバージョンを待(ま)たなければならない
- カーネルモジュールのロード → 誤(あやま)って書(か)くとシステムクラッシュの危険(きけん)。カーネル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_HASH | LRUキャッシュ |
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パッケージインストールexecsnoop、opensnoop、tcptopのようなツール使用(しよう)- 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で作成(さくせい)するのが一般的(いっぱんてき)です。
参考(さんこう)資料(しりょう)
- ebpf.io — 公式(こうしき)サイト
- Linux Observability with BPF — David Calavera, Lorenzo Fontana
- BPF Performance Tools — Brendan Gregg
- libbpf-bootstrap — CO-RE開始(かいし)テンプレート
- bcc-tools — 100+ BPFツール
- bpftrace — DTraceのような高水準(こうすいじゅん)トレーシング
- Cilium Documentation
- Falco Documentation
- Brendan Gregg's eBPF page
- Awesome eBPF
- eBPF Summit — 年次(ねんじ)カンファレンス
- KubeCon eBPF Day — Ciliumチーム発表(はっぴょう)