MENU

bpftrace/BCCによる本番CPUホットスポット診断|eBPFトレーシング導入と副作用制御設計

目次

eBPFトレーシングが本番CPUホットスポット診断で選ばれる理由

従来のCPU性能調査ではperf topやstraceが使われてきましたが、情報粒度やプロセス停止の問題が運用上の制約になっていました。eBPF(extended Berkeley Packet Filter)はカーネル空間で検証済みのバイトコードを安全に実行する仕組みであり、アプリケーションを止めずに動的なトレースポイントをアタッチできます。

bpftraceはeBPFのフロントエンドとして高レベルな一行スクリプトを記述できる点が特徴で、BCC(BPF Compiler Collection)はPythonまたはC言語でより複雑なプログラムを組めるフレームワークです。本番環境のCPUホットスポット診断において、プロセスを止めずにスタックトレースをサンプリングできることが最大の利点です。

eBPFプログラムはカーネルのBPFベリファイアが実行前に安全性を検証します。無限ループや不正なメモリアクセスはロードを拒否されるため、カーネルパニックのリスクは本質的に低く設計されています。ただし本番での利用には後述する副作用リスクも存在するため、設計段階での考慮が必要です。

bpftrace と BCC の役割分担

両ツールは目的に応じて使い分けるのが実務的です。

  • bpftrace:アドホックな調査に向いています。インタラクティブな一行スクリプトや短いスクリプトファイル(.bt)で、カーネル・ユーザ空間の関数トレースやサンプリングプロファイリングができます。LLVM/Clang依存ですが、Ubuntu 22.04以降やRHEL 9系ではパッケージインストールで利用可能です。
  • BCC:継続的な監視・集計ツールの構築に向いています。profile・cpudist・runqlat・offcputimeなどの完成済みツール群があり、即座に使えます。2026年時点ではlibbpfベースのCO-RE対応バイナリへの移行も進んでいます。

簡潔に整理すると、「まず何が起きているかを把握する」段階ではbpftraceを使い、「定常的な指標収集や複雑な集計ロジックが必要」な段階ではBCCまたはlibbpfへ移るのが自然な流れです。

本番導入前チェックと副作用リスクの整理

本番サーバでeBPFトレーシングを有効にする前に、次の項目を確認します。

カーネルバージョンと設定の確認

bpftrace 0.20以降の全機能を使うにはLinuxカーネル5.8以上が推奨されます。BTF(BPF Type Format)を有効にするにはCONFIG_DEBUG_INFO_BTF=yが必要で、Ubuntu 22.04 LTS・RHEL 9系はデフォルトで有効です。以下のコマンドで確認できます。

uname -r
grep CONFIG_DEBUG_INFO_BTF /boot/config-$(uname -r)
ls /sys/kernel/btf/vmlinux

/sys/kernel/btf/vmlinuxが存在すればCO-RE対応(コンパイル済みeBPFバイナリを別カーネルでも動かせる仕組み)が利用可能です。

主な副作用リスク

eBPFは安全設計ですが、本番運用で見落としがちなリスクは以下の3点です。

  • CPU・メモリオーバーヘッド:プロファイルサンプリングの頻度(Hz)が高いほどオーバーヘッドが増加します。本番では99Hz程度が目安で、9999Hzのような高頻度は避けます。
  • kprobeのカーネル依存:関数名がカーネルバージョン間でリネームされると、kprobeのアタッチが失敗する場合があります。uprobeを使う場合も同様にシンボル変更に注意が必要です。
  • eBPFマップのメモリ消費:スタックトレースを収集するBPFマップはデフォルトのエントリ数上限に達すると情報欠落が生じます。長時間の収集を行う場合はマップサイズの設計が必要です。

bpftraceによるCPUホットスポットの特定手順

実際のワークフローを段階的に示します。以下では想定例として「特定プロセスでCPU使用率が高止まりしている」シナリオを使います。

ステップ1:システム全体のCPUプロファイリング

まずシステム全体でどのカーネル関数がCPU時間を消費しているかを確認します。

# 10秒間・99HzでカーネルスタックをサンプリングしてTop表示
bpftrace -e 'profile:hz:99 { @[kstack] = count(); } interval:s:10 { exit(); }'

出力はスタックトレースとヒット数のマップで返ります。上位に現れたスタックが現在のCPUホットスポットです。

ステップ2:特定プロセスのユーザ空間プロファイリング

カーネルスタックで目星がついたら、同じプロセスのユーザ空間スタックも確認します(想定例:PID 1234番)。

# PID 1234 のユーザ空間スタックを99Hzでサンプリング
bpftrace -e 'profile:hz:99 /pid == 1234/ { @[ustack] = count(); } interval:s:10 { exit(); }'

JVMやPython等のインタープリタ言語では、この時点でフレームポインタが正しく取得できない場合があります(後述の「よくあるつまずき」を参照)。

ステップ3:FlameGraphの生成

bpftraceの出力をFlameGraph用スクリプトに渡すことでフレームグラフを可視化できます。

bpftrace -e 'profile:hz:99 { @[kstack, ustack, comm] = count(); } interval:s:30 { exit(); }' \
  --output /tmp/profile.bt.out

# FlameGraph用に変換(stackcollapse-bpftrace.plが必要)
stackcollapse-bpftrace.pl /tmp/profile.bt.out | flamegraph.pl > /tmp/cpu_flamegraph.svg

BCCツールによる詳細分析

bpftraceでホットスポットの当たりがついたら、BCCの専用ツールでさらに掘り下げます。

profile:プロセス別CPU使用率の集計

# 30秒間プロファイリングしてフレームグラフ用データを出力
/usr/share/bcc/tools/profile -F 99 -f 30 | flamegraph.pl > /tmp/profile_flamegraph.svg

runqlat:実行待ち遅延の分布確認

CPUが忙しくてもスレッドが「実行待ち」に陥っている場合は、CPUホットスポットではなくスケジューラの問題です。runqlatでランキュー待ち時間の分布を確認します。

/usr/share/bcc/tools/runqlat 5

レイテンシ分布がミリ秒単位で広がっている場合、CPUコア数の不足またはCPUピニングの設定ミスを疑います。

offcputime:CPUオフ時間の追跡

CPUホットスポット調査では「CPUを使っている時間」だけでなく「CPUを使っていないのにレイテンシが高い時間(off-CPU)」の把握も重要です。

/usr/share/bcc/tools/offcputime -K 10 | flamegraph.pl > /tmp/offcpu_flamegraph.svg

on-CPU flamegraphとoff-CPU flamegraphを並べて見ることで、CPUバウンドかI/Oバウンドかを視覚的に判断できます。

副作用制御の設計とロールバック方針

本番でeBPFトレーシングを運用する場合、「いつでも即座に止められる」設計が前提になります。

プログラムのライフタイム管理

eBPFプログラムはロードしたプロセスが終了するとカーネルから自動的にアンロードされます。bpftraceをCtrl+Cまたはinterval:s:N { exit(); }で終了させれば、アタッチしたプローブもすべて解除されます。常駐型のBCCデーモンを書く場合は終了シグナルハンドラを必ず実装します。

オーバーヘッドの定量評価

トレーシング中はperf statやtopでトレーサ自身のCPU消費をモニタします。想定例として、99Hzのサンプリングプロファイルではシステム全体への追加CPU使用率は一般的に1%未満に収まるとされていますが、実環境では事前にステージングで計測することを推奨します。

権限の最小化

bpftraceおよびBCCツールはroot権限またはCAP_BPF+CAP_PERFMON権限が必要です。Linuxカーネル5.8以降ではCAP_BPFとCAP_PERFMONが分離されており、root以外のユーザに最小権限を付与できます。本番環境では専用のサービスアカウントに必要なケーパビリティだけを付与するのが望ましいです(想定例)。

# ケーパビリティの付与例(想定例)
setcap cap_bpf,cap_perfmon+ep /usr/bin/bpftrace

2026年現行環境との差分:BTF・CO-RE・ディストリビューション対応状況

主要ディストリビューションの対応状況

  • Ubuntu 22.04 LTS / 24.04 LTS:カーネル5.15以上・BTFデフォルト有効。bpftrace 0.19〜0.21がリポジトリで提供。BCC tools v0.26以降。
  • RHEL 9 / Rocky Linux 9 / AlmaLinux 9:カーネル5.14ベース・BTF有効。bpftraceとbcc-toolsがAppStreamから提供されています。
  • RHEL 8:カーネルが4.18ベースのためeBPF機能に制約が多く、bpftraceの一部機能が利用できません。perf recordとの組み合わせによる限定的な使い方が現実的です。
  • Debian 12 Bookworm:カーネル6.1・BTF有効。bpftrace 0.17がリポジトリ提供ですが機能は限定的です。最新版を使う場合はソースビルドまたはContainerizedバイナリを検討します。

BCCからlibbpfへの移行動向

BCCはPython実行時にClangでeBPFコードを動的コンパイルするアーキテクチャのため、本番サーバにLLVM/Clangを常駐させる必要があります。この構成を避けたい場合、CO-RE対応のlibbpfベースツール(bcc-libbpf-tools)への移行が選択肢になります。opensnoop-bpfccに対してlibbpf版のopensnoopが使えるかどうかはディストリビューションのパッケージ構成によります。

JVM・Pythonのスタック取得における注意点

JVMはデフォルトでフレームポインタを省略する最適化を行うため、bpftraceでのユーザ空間スタックが正しく取得できないことがあります。JDK 21以降では起動時に-XX:+PreserveFramePointerフラグを付与することで改善されます。PythonはCPython 3.12からPerf対応が改善されており、PYTHONPERFSUPPORT=1環境変数でperf/bpftraceのフレーム取得精度が向上します。

よくあるつまずき

  • 「failed to attach kprobe」エラー:対象の関数がインライン展開されているか、カーネルバージョン間でリネームされている場合に発生します。bpftrace -l 'kprobe:*関数名*'で利用可能なシンボルを確認します。
  • BTFが見つからない:コンテナ環境ではホストの/sys/kernel/btf/vmlinuxがマウントされていない場合があります。コンテナからbpftraceを使う際は--privilegedまたはBTFファイルのバインドマウントが必要です。
  • コンテナ内でのBCC動作不全:BCC動的コンパイルはカーネルヘッダをコンテナ内に必要とする場合があります。libbpf/CO-RE対応ツールはこの問題を回避できるため、コンテナ環境ではlibbpf版を優先します。

「コマンドは打てる。次は”現場で通用する型”を最短で身につけたい」——そんなあなたへ。

ネットの断片的なTipsをコピペするだけでは、体系的な運用スキルはなかなか積み上がりません。リナックスマスター.JPの無料メルマガ「リナマガ」では、現場で実際に使うLinuxサーバー運用の考え方を、順を追って実務目線でお届けしています。いま登録された方には、安全なサーバー構築の「型」をまとめた『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼント中です。

>> 図解60P『Linux入門マニュアル』を無料で受け取る
(メルマガ登録は10秒・いつでも解除OK)

※ 「独学の時間がもったいない」「プロから現場の技術を最短で学びたい」という本気の方には、2日で実務レベルが身につく初心者向けハンズオンセミナーもご用意しています。

PR・広告

新しいLinuxの教科書 第2版(Amazon)

コマンド操作から基本運用までを手を動かして学べる定番書。記事で触れた技術の土台固めに。

Amazonで見る

※ Amazonのアソシエイトとして、当サイトは適格販売により収入を得ています。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

目次