# Linux eBPF Tracing Technology [[Yuuki Tsubouchi]] による eBPF トレーシング技術の体系的解説(2021-12-28)。BPF の基礎から開発ツールチェーン・本番実装ワークフローまでを網羅する。本 vault における [[go-conntracer-bpf]] の技術的背景にあたる一次資料。 ## 要旨 eBPF(extended Berkeley Packet Filter)は、Linux カーネルで**安全にサンドボックス化されたプログラムをカーネル再コンパイルなしに実行**できる汎用実行エンジンである。カーネルおよびアプリケーションのイベントに応じてフックポイントで小さなプログラムを実行する仕組みで、可観測性(テレメトリ)とカーネル挙動の拡張(ネットワーク・セキュリティ)の両方に使われる。 ## アーキテクチャコンポーネント | コンポーネント | 役割 | |---|---| | BPF VM | 独自バイトコードを解釈・ネイティブ命令へ変換 | | Verifier | 終了性・メモリアクセスを事前検査(安全性保証) | | JIT コンパイラ | カーネル再起動なしにバイトコードをマシンコードへ変換 | | BPF Maps | カーネル-ユーザ空間間のデータ共有(array/hashmap/ring buffer) | | ヘルパー関数 | カーネル機能へのアクセスを提供する安定 API | ## イベントソース ### 動的計装 - **Kprobe** (2004 年〜): 任意のカーネル関数へ動的アタッチ - **Uprobe** (2012 年〜): ユーザ空間関数へ動的アタッチ ### 静的計装 - **tracepoints**: カーネルイベントの静的計装点(カーネルバージョン間で安定) - **USDT** (User-level Statically Defined Tracing): アプリケーション定義の静的計装点。アプリ側の対応が必要 - **PMC / perf_events**: ハードウェアパフォーマンスカウンタ ## 開発ツールチェーン ### [[BCC]] (BPF Compiler Collection) - 2015 年開発開始。70+ のパフォーマンス分析ツールを内包 - Python/Lua/C++ フロントエンド対応。**ラピッドプロトタイピング**向け - 2020 年以降、Python ツール群の libbpf ベースへの移行を推奨 ### [[bpftrace]] - 2017 年開発開始。**アドホックなトレーシング特化**のスクリプト言語 - カーネルとユーザ空間のコードを分離せずに書ける。探索・デバッグに最適 ### [[libbpf]] + CO-RE - CO-RE (Compile Once - Run Everywhere): BTF(BPF Type Format)とランタイム再配置によりカーネルバージョン横断のポータビリティを実現 - **本番実装**向け。安定性とポータビリティを両立 ## 推奨開発ワークフロー ``` 1. ツール定義 — 既存ツールとの重複を避け、観測できていないギャップを特定 2. ターゲット探索 — available_filter_functions / tplist / funccount / biostacks で計装点を発見 3. BCCプロトタイプ — カーネル・ユーザ空間コードを組み合わせた高速イテレーション 4. libbpf+CO-RE — 安定性・ポータビリティを確保した本番実装へ移行 ``` ## CO-RE の仕組み CO-RE はコンパイル時に再配置情報を BTF に埋め込み、実行時に接続先カーネルの BTF メタデータと照合する。これにより、カーネルのデータ構造が異なるバージョン間でも単一バイナリをそのまま動作させられる。 ## 並行性の考慮 カーネル内 BPF プログラムは並行実行されるため、ユーザ空間とは異なる同期が必要: - **カーネル-ユーザ空間並行**: `BPF_LOOKUP_AND_DELETE_BATCH` などのアトミック API を使う - **スレッド間**: `__atomic_add_fetch()` による安全なカウンタ更新 ## 言語バインディング | 言語 | 主要ライブラリ | |---|---| | Go | `cilium/ebpf`(Pure Go)、`aquasecurity/libbpfgo`、`gobpf` | | Rust | `aya-rs`(libbpf 非依存)、`libbpf-rs`、`redbpf` | ## 歴史的経緯 | 年 | 出来事 | |---|---| | 1992 | classic BPF 誕生(パケットフィルタリング) | | 1997 | Linux Socket Filter 統合(kernel 2.1.8x) | | 2013 | eBPF 拡張の提案 | | 2014 | eBPF がカーネルに統合 | | 2015 | BCC フレームワーク開発開始 | | 2016 | Brendan Gregg "Linux BPF Superpowers" 発表 | | 2017 | bpftrace 開発開始 | | 2019 | CO-RE プロジェクト公表 | | 2020 | BCC Python ツール群の libbpf 移行推奨・CNCF 優先技術に認定 | | 2021 | Windows BPF サポート発表 | ## 観測可能性スタックでの位置づけ eBPF による BPF トレーシングは上位レイヤーの APM・分散トレーシングを補完し、**カーネルレベルの可観測性**を提供する。従来のアプローチ(procfs/sysfs)との違いは: - カーネル空間内での**細粒度フィルタリング・集約**(ユーザ空間への転送量を最小化) - 任意のフックポイントでの**カスタムロジック実行** - カーネルモジュールと異なり**安全性保証とポータビリティ**を兼備 ## 横断的知見 - **[[go-conntracer-bpf]] との接続**: 本 vault の [[go-conntracer-bpf]](カーネル内フローバンドリング)は libbpf を用いて実装されており、本記事の「BCC プロトタイプ → libbpf 本番実装」ワークフローの実践例にあたる - **[[動的インストルメンテーション]] との接続**: kprobe/uprobe は本記事で説明される「ソース改変なしにアタッチする」動的計装の基盤。[[eInfer]]・[[ProfInfer]] はこの仕組みを分散 LLM 推論の観測に応用している - **eBPF×AI との接続**: 本記事(2021)は eBPF の基礎技術を解説したもの。これを基盤として 2024 年以降に AI ワークロード観測への応用([[@2025__eBPF__eInfer - Unlocking Fine-Grained Tracing for Distributed LLM Inference with eBPF]]、[[@2026__arXiv__ProfInfer - An eBPF-based Fine-Grained LLM Inference Profiler]])が展開されている ## 関連 - 著者: [[Yuuki Tsubouchi]] - 概念: [[eBPF]] / [[動的インストルメンテーション]] - エンティティ: [[BCC]] / [[bpftrace]] / [[libbpf]] / [[go-conntracer-bpf]] - 応用先ソース: [[@2025__eBPF__eInfer - Unlocking Fine-Grained Tracing for Distributed LLM Inference with eBPF]] / [[@2026__arXiv__ProfInfer - An eBPF-based Fine-Grained LLM Inference Profiler]] / [[@2026__eunomia.dev__eBPF × AI-LLMs - The Convergence of System Observability and AI]]