mcpField
D
debug-buttercup

debug-buttercup

github.com/trailofbitsクラウド・DevOps7.9k3.5k 回インストール今日更新
リポジトリ

debug-buttercup について

Debug Buttercupは、`crs` Kubernetesネームスペース内のButtercup障害を調べる運用者向けのトラブルシューティングスキルです。Pod、イベント、ログから始める手順を示し、Redisキュー、リソース逼迫、テレメトリー、デプロイ設定の確認も扱います。

主な機能

  1. 01Podの状態とKubernetesイベントの確認
  2. 02コンテナログと再起動原因の分析
  3. 03Redisの状態とキュー滞留の調査
  4. 04Podとノードのリソース逼迫の確認
  5. 05テレメトリー、ストレージ、Helm設定の検証
  6. 06診断スナップショット収集スクリプトの実行

活用シーン

  1. 01`crs`での再起動ループやOOMの調査
  2. 02Redis障害による連鎖再起動の特定
  3. 03キュー滞留やタスク処理停止の診断
  4. 04実際のPod設定とHelm値の照合

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/trailofbits/skills --skill debug-buttercup

インストール後、Claude Code で/debug-buttercupを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

agents/
openai.yaml
assets/
trail-of-bits-mark.svg
references/
failure-patterns.md
scripts/
diagnose.sh

詳細

Buttercup のデバッグ

使用する状況

  • crs 名前空間の Pod が CrashLoopBackOff、OOMKilled、または再起動を繰り返している
  • 複数のサービスが同時に再起動する(カスケード障害)
  • Redis が応答しない、または AOF 警告が表示される
  • キューが増加しているが、タスクが進行していない
  • ノードに DiskPressure、MemoryPressure、または PID 圧力が発生している
  • build-bot が Docker デーモンに接続できない(DinD の障害)
  • スケジューラーが停止し、タスクの状態が進まない
  • ヘルスチェックのプローブが予期せず失敗する
  • デプロイされた Helm の値が、実際の Pod 設定と一致しない

使用しない状況

  • Buttercup のデプロイまたはアップグレード(Helm とデプロイガイドを使用してください)
  • crs Kubernetes 名前空間外の問題のデバッグ
  • 障害の症状を伴わないパフォーマンスチューニング

名前空間とサービス

すべての Pod は crs 名前空間で実行されます。主なサービスは次のとおりです。

レイヤーサービス
インフラredis, dind, litellm, registry-cache
オーケストレーションscheduler, task-server, task-downloader, scratch-cleaner
ファジングbuild-bot, fuzzer-bot, coverage-bot, tracer-bot, merger-bot
分析patcher, seed-gen, program-model, pov-reproducer
インターフェースcompetition-api, ui

トリアージのワークフロー

必ずトリアージから始めてください。まず次の 3 つのコマンドを実行します。

# 1. Pod status - look for restarts, CrashLoopBackOff, OOMKilled
kubectl get pods -n crs -o wide

# 2. Events - the timeline of what went wrong
kubectl get events -n crs --sort-by='.lastTimestamp'

# 3. Warnings only - filter the noise
kubectl get events -n crs --field-selector type=Warning --sort-by='.lastTimestamp'

次に、対象を絞り込みます。

# Why did a specific pod restart? Check Last State Reason (OOMKilled, Error, Completed)
kubectl describe pod -n crs <pod-name> | grep -A8 'Last State:'

# Check actual resource limits vs intended
kubectl get pod -n crs <pod-name> -o jsonpath='{.spec.containers[0].resources}'

# Crashed container's logs (--previous = the container that died)
kubectl logs -n crs <pod-name> --previous --tail=200

# Current logs
kubectl logs -n crs <pod-name> --tail=200
過去の問題と継続中の問題

再起動回数が多くても、必ずしも問題が継続中とは限りません。再起動回数は Pod の稼働期間を通じて累積します。必ず次の点を区別してください。

  • --tail はログバッファーの末尾を表示しますが、そこに古いメッセージが含まれている場合があります。問題が現在も発生していることを確認するには、--since=300s を使用してください。
  • ログ出力に --timestamps を付けると、サービス間のイベントを照合しやすくなります。
  • describe pod の Last State のタイムスタンプを確認し、直近のクラッシュが実際にいつ発生したかを把握してください。
カスケードの検出

多数の Pod がほぼ同時に再起動した場合は、個々の Pod を調査する前に、共通の依存先の障害を確認してください。最もよくあるカスケードは、Redis が停止し -> すべてのサービスで ConnectionError/ConnectionRefusedError が発生し -> 大量の再起動に至るケースです。複数の --previous ログで同じエラーがないか確認してください。すべてに redis.exceptions.ConnectionError と記録されている場合は、個々のサービスではなく Redis をデバッグしてください。

ログ分析

# All replicas of a service at once
kubectl logs -n crs -l app=fuzzer-bot --tail=100 --prefix

# Stream live
kubectl logs -n crs -l app.kubernetes.io/name=redis -f

# Collect all logs to disk (existing script)
bash deployment/collect-logs.sh

リソース圧力

# Per-pod CPU/memory
kubectl top pods -n crs

# Node-level
kubectl top nodes

# Node conditions (disk pressure, memory pressure, PID pressure)
kubectl describe node <node> | grep -A5 Conditions

# Disk usage inside a pod
kubectl exec -n crs <pod> -- df -h

# What's eating disk
kubectl exec -n crs <pod> -- sh -c 'du -sh /corpus/* 2>/dev/null'
kubectl exec -n crs <pod> -- sh -c 'du -sh /scratch/* 2>/dev/null'

Redis のデバッグ

Redis はシステムの基盤です。Redis が停止すると、すべてに影響が波及します。

# Redis pod status
kubectl get pods -n crs -l app.kubernetes.io/name=redis

# Redis logs (AOF warnings, OOM, connection issues)
kubectl logs -n crs -l app.kubernetes.io/name=redis --tail=200

# Connect to Redis CLI
kubectl exec -n crs <redis-pod> -- redis-cli

# Inside redis-cli: key diagnostics
INFO memory          # used_memory_human, maxmemory
INFO persistence     # aof_enabled, aof_last_bgrewrite_status, aof_delayed_fsync
INFO clients         # connected_clients, blocked_clients
INFO stats           # total_connections_received, rejected_connections
CLIENT LIST          # see who's connected
DBSIZE               # total keys

# AOF configuration
CONFIG GET appendonly     # is AOF enabled?
CONFIG GET appendfsync   # fsync policy: everysec, always, or no

# What is /data mounted on? (disk vs tmpfs matters for AOF performance)
kubectl exec -n crs <redis-pod> -- mount | grep /data
kubectl exec -n crs <redis-pod> -- du -sh /data/
キューの確認

Buttercup は Redis ストリームとコンシューマーグループを使用します。キュー名は次のとおりです。

キューストリームキー
ビルドfuzzer_build_queue
ビルド出力fuzzer_build_output_queue
クラッシュfuzzer_crash_queue
確認済みの脆弱性confirmed_vulnerabilities_queue
ダウンロードタスクorchestrator_download_tasks_queue
準備完了タスクtasks_ready_queue
パッチpatches_queue
インデックスindex_queue
インデックス出力index_output_queue
トレース済みの脆弱性traced_vulnerabilities_queue
POV リクエストpov_reproducer_requests_queue
POV レスポンスpov_reproducer_responses_queue
タスク削除orchestrator_delete_task_queue
# Check stream length (pending messages)
kubectl exec -n crs <redis-pod> -- redis-cli XLEN fuzzer_build_queue

# Check consumer group lag
kubectl exec -n crs <redis-pod> -- redis-cli XINFO GROUPS fuzzer_build_queue

# Check pending messages per consumer
kubectl exec -n crs <redis-pod> -- redis-cli XPENDING fuzzer_build_queue build_bot_consumers - + 10

# Task registry size
kubectl exec -n crs <redis-pod> -- redis-cli HLEN tasks_registry

# Task state counts
kubectl exec -n crs <redis-pod> -- redis-cli SCARD cancelled_tasks
kubectl exec -n crs <redis-pod> -- redis-cli SCARD succeeded_tasks
kubectl exec -n crs <redis-pod> -- redis-cli SCARD errored_tasks

コンシューマーグループ:build_bot_consumers、orchestrator_group、patcher_group、index_group、tracer_bot_group。

ヘルスチェック

Pod は /tmp/health_check_alive にタイムスタンプを書き込みます。ライブネスプローブはファイルの鮮度を確認します。

# Check health file freshness
kubectl exec -n crs <pod> -- stat /tmp/health_check_alive
kubectl exec -n crs <pod> -- cat /tmp/health_check_alive

Pod が再起動ループに陥っている場合、メインプロセスがブロックされている(例:Redis の応答待ち、I/O の停止)ため、ヘルスチェックファイルが古くなっている可能性があります。

テレメトリ(OpenTelemetry/Signoz)

すべてのサービスは OpenTelemetry 経由でトレースとメトリクスをエクスポートします。Signoz がデプロイされている(global.signoz.deployed: true)場合は、UI を使ってサービス間の分散トレースを確認してください。

# Check if OTEL is configured
kubectl exec -n crs <pod> -- env | grep OTEL

# Verify Signoz pods are running (if deployed)
kubectl get pods -n platform -l app.kubernetes.io/name=signoz

トレースは、タスク処理の遅延の診断、パイプライン内でボトルネックとなっているサービスの特定、スケジューラー -> build-bot -> fuzzer-bot の流れにおけるイベントの照合に特に役立ちます。

ボリュームとストレージ

# PVC status
kubectl get pvc -n crs

# Check if corpus tmpfs is mounted, its size, and backing type
kubectl exec -n crs <pod> -- mount | grep corpus_tmpfs
kubectl exec -n crs <pod> -- df -h /corpus_tmpfs 2>/dev/null

# Check if CORPUS_TMPFS_PATH is set
kubectl exec -n crs <pod> -- env | grep CORPUS

# Full disk layout - what's on real disk vs tmpfs
kubectl exec -n crs <pod> -- df -h

CORPUS_TMPFS_PATH は、global.volumes.corpusTmpfs.enabled: true の場合に設定されます。これは fuzzer-bot、coverage-bot、seed-gen、merger-bot に影響します。

デプロイ設定の検証

動作が期待と異なる場合は、Helm の値が実際に反映されていることを確認してください。

# Check a pod's actual resource limits
kubectl get pod -n crs <pod-name> -o jsonpath='{.spec.containers[0].resources}'

# Check a pod's actual volume definitions
kubectl get pod -n crs <pod-name> -o jsonpath='{.spec.volumes}'

Helm の値テンプレートに誤り(キー名の誤りなど)があると、チャートのデフォルト値に暗黙的にフォールバックします。デプロイされたリソースが値テンプレートと一致しない場合は、キー名の不一致を確認してください。

サービス別のデバッグ

サービスごとの詳しい症状、根本原因、修正方法については、references/failure-patterns.md を参照してください。

クイックリファレンス:

  • DinD:kubectl logs -n crs -l app=dind --tail=100 を実行し、Docker デーモンのクラッシュやストレージドライバーのエラーを確認します
  • Build-bot:ビルドキューの深さ、DinD への接続、コンパイル中の OOM を確認します
  • Fuzzer-bot:コーパスのディスク使用量、CPU スロットリング、クラッシュキューの滞留を確認します
  • Patcher:LiteLLM への接続、LLM のタイムアウト、パッチキューの深さを確認します
  • Scheduler:中央の頭脳です。kubectl logs -n crs -l app=scheduler --tail=-1 --prefix | grep "WAIT_PATCH_PASS\|ERROR\|SUBMIT" を実行します

診断スクリプト

自動トリアージのスナップショットを実行します。

bash {baseDir}/scripts/diagnose.sh

すべての Pod の最近のログも出力するには、--full を渡します。

bash {baseDir}/scripts/diagnose.sh --full

これにより、Pod のステータス、イベント、リソース使用状況、Redis の健全性、キューの深さを一度に収集できます。

コメント