troubleshoot-ssi について
Kubernetes 上の Datadog Single Step Instrumentation(SSI)を調査するスキルで、計装やトレースが見つからない場合の診断に向いています。クラスター状態と Datadog バックエンドの診断を組み合わせ、観測結果に沿って調査を進めます。
主な機能
- 01Pod の注入と Webhook 状態の確認
- 02トレースとトレーサーテレメトリーの照会
- 03バックエンドの注入エラー確認
- 04診断結果に基づく原因分析
活用シーン
- 01計装されていない Pod の調査
- 02Datadog トレース欠落の診断
- 03SSI 検証失敗後の調査
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ datadog-labs/ agent-skills --skill troubleshoot-ssiインストール後、Claude Code で/troubleshoot-ssiを入力して読み込まれたか確認します。
詳細
Kubernetes での APM SSI のトラブルシューティング
トリガー
ユーザーが以下を行う意向を示した場合に、このスキルを呼び出します。
- Pod がインストルメントされない理由をデバッグする
- Datadog にトレースが表示されない理由を調査する
- Admission Webhook または init コンテナーの注入エラーを診断する
verify-ssiで失敗したチェックに対応する- 特定のサービスまたは Pod にトレースがないと報告する
以下の場合は、このスキルを呼び出さないでください。
- SSI がまだ有効になっていない場合 — 先に
enable-ssiを実行します
前提条件
- クラスターを対象に kubectl が設定されていること —
kubectl config current-context
pup-cli:確認、インストール、認証
Claude が実行
pup --version
見つからない場合は、OS に応じてインストールします。
Claude が実行
if [[ "$(uname)" == "Darwin" ]]; then
brew tap datadog-labs/pack && brew install pup
else
PUP_VERSION=$(curl -s https://api.github.com/repos/datadog-labs/pup/releases/latest | grep '"tag_name"' | cut -d'"' -f4)
curl -L "https://github.com/datadog-labs/pup/releases/download/${PUP_VERSION}/pup_linux_amd64.tar.gz" | tar xz -C /usr/local/bin pup
chmod +x /usr/local/bin/pup
fi
pup --version
認証を確認します。
pup auth status
認証されていない場合:
Claude が実行
pup auth login
OAuth 用のブラウザータブが開きます。そこでログインを完了してください。コマンドが終了すると、Claude は処理を続行します。
ブラウザーを利用できない場合:export DD_APP_KEY=<your-app-key>。
作業前に解決するコンテキスト
| 変数 | 解決方法 |
|---|---|
AGENT_NAMESPACE | Datadog Agent がインストールされている Namespace |
APP_NAMESPACE | トレースが欠落しているアプリケーションの Namespace |
CLUSTER_NAME | kubectl config current-context または datadog-agent.yaml 内の spec.global.clusterName |
SERVICE_NAME | Deployment の tags.datadoghq.com/service ラベル。あるいはユーザーに確認します |
ENV | Deployment の tags.datadoghq.com/env ラベル。あるいはユーザーに確認します |
POD_NAME | kubectl get pods -n <APP_NAMESPACE> — ユーザーが指定した Pod を使用します |
DEPLOYMENT_NAME | Deployment マニフェストの metadata.name を確認するか、ユーザーに確認します |
APP_LABEL | Deployment マニフェストの spec.selector.matchLabels.app を確認します |
SSI の仕組み — ドメイン知識
調査を始める前にお読みください。既知の問題だけでなく、新たな障害を考察するためのメンタルモデルを示します。
インジェクションの流れ:
- Admission webhook(Cluster Agent によって登録)が Pod の作成をインターセプトします
- Webhook が Pod 仕様を変更し、
datadog-lib-<language>-initinit コンテナを追加します - Init コンテナがトレーサーライブラリをダウンロードし、共有ボリュームに配置します
- ライブラリの
.soファイルを指すLD_PRELOAD環境変数が設定されます - アプリケーションプロセスは起動時に
LD_PRELOADを介してライブラリを自動的に読み込みます
各診断レイヤーで確認できること:
- pup — Datadog のバックエンドが受信した内容を確認できます。クラスター側のインジェクション失敗は確認できません。pup にサービスのトレーサーテレメトリーが表示されない場合、トレーサーはインジェクションされていない(クラスター側の問題。kubectl の init コンテナチェックで確認)か、インジェクションされたもののまだ報告できていない(接続、DD_SITE、API キー、またはテレメトリーの遅延)かのどちらかです。クラスター側の問題だと決めつけず、kubectl でも確認してください。
- kubectl — クラスターの状態を確認できます。データが Datadog に届いたかどうかは確認できません。kubectl に init コンテナが表示される一方で pup にトレースが表示されない場合、問題はインジェクション後にあります。
正常な状態:
pup fleet tracers listに、対象サービスが想定される言語でアクティブとして表示されますkubectl get pod -o jsonpath='{.spec.initContainers[*].name}'にdatadog-lib-<language>-initが含まれます
既知のサイレント障害 — これらが発生しても SSI はエラーを出しません:
- 既存の ddtrace または OTel による計装 — SSI が検出し、サイレントに自身を無効化します
- サポートされていないランタイムバージョン — サイレントにスキップされます
admission.datadoghq.com/enabled: "false"アノテーション — webhook が Pod を完全にスキップします- SSI の有効化後に Pod が再起動されていない — インジェクションは起動時に行われるため、既存の Pod は計装されないまま稼働し続けます
- Agent の namespace 内にある Pod — SSI は自身の namespace を計装しません
考察の手がかり:
- Init コンテナがない → webhook が実行されていない → 確認項目:namespace の対象設定、pod-selector、オプトアウトアノテーション、webhook の登録、Pod の再起動
- Init コンテナがあるがトレースがない →
pup fleet tracers listにサービスが表示されるか確認します:表示されない → トレーサーが報告していない(Agent の接続、DD_SITE の不一致、API キー、送信トラフィックのブロック、またはトレーザーが読み込まれていない — 既存の ddtrace/OTel、サポートされていないランタイム);表示される → テレメトリーは報告されているが、スパンが届いていない(トラフィックがない、サンプリング、取り込み/保持フィルター)
ステップ 1:トリアージ
7 つすべてを同時に実行し、実行中の診断としてユーザーに提示してください。以降の対応は、ここで確認した内容に基づいて進めます。Pod 名がわかったら、kubectl get pod <POD_NAME> -n <APP_NAMESPACE> -o jsonpath='{.spec.nodeName}' で <NODE_HOSTNAME> を特定してください。まだ Pod の情報がない場合は、まず --hostname を付けずに pup コマンドを実行してください。
Claude が実行するコマンド
pup traces search --query "service:<SERVICE_NAME>" --from 1h --limit 5
pup fleet tracers list --filter "service:<SERVICE_NAME>"
pup apm troubleshooting list --hostname <NODE_HOSTNAME> --timeframe 1h
pup apm service-library-config get --service-name <SERVICE_NAME> --env <ENV>
kubectl get pod <POD_NAME> -n <APP_NAMESPACE> \
-o jsonpath='{.spec.initContainers[*].name}'
kubectl describe pod <POD_NAME> -n <APP_NAMESPACE> | grep -A 10 "Events:"
kubectl get mutatingwebhookconfigurations | grep datadog
最後のコマンドで、Admission Controller webhook がクラスター全体に登録されていることを確認します。これは SSI インジェクションが機能するための前提条件であり、ほかの大半のサービスが計装されている場合でも確認が必要です(webhook 設定の一部に差異があると、一部の Pod がサイレントにスキップされる可能性があります)。
pup apm troubleshooting list は、Datadog のバックエンドがクラスターから受信したインジェクションエラーを表示します。これらは、kubectl describe だけでは確認できない場合がある、クラスター側の変更失敗を示します。pup apm service-library-config get は、トレーサーが動作しているランタイム SDK 設定を表示します。想定外の値は、UST/設定伝播の問題を示します。この表示には、各 SDK のすべての設定が一覧表示されるわけではありません。そのため、値が見つからない場合は、設定が伝播しなかったと結論づける前に、verify-ssi のステップ 3 にあるコマンドで Pod の環境変数を確認してください。
調査結果の提示(必須)
最終回答が成果物です。調査の経過をそのまま記載するものではありません。このスキルで実行した、または該当するすべての診断について、目的と結果を必ず記載してください。避けるべき失敗は次の3つです。
-
チェックを実行したのに、結果を報告しないこと。 調査中に
kubectl get mutatingwebhookconfigurations、名前空間のadmission.datadoghq.com/mutate-podsラベルのチェック、その他のコマンドを実行した場合は、コマンドと結果を回答に記載してください。実行したチェックを結果に反映しなければ、読者には何も伝わりません。特に、名前空間のラベルチェックと Webhook チェックは、必ず明示してください。 -
必須の2つの pup 診断を省略すること。 診断ごとに、影響を受けるサービスごとに、次の2つのコマンドを必ず明記してください。これらは必須のトリアージ出力であり、省略できません。
pup apm troubleshooting list --hostname <NODE_HOSTNAME>— Datadog がノードから受信したインジェクションエラーを表示しますpup apm service-library-config get --service-name <SERVICE_NAME> --env <ENV>— トレーサーの実行時 SDK 設定を表示します
pupが利用可能な場合は、これらのコマンドを実行してください。利用できない場合は、ユーザーに実行を推奨してください。これらの代わりにpup traces searchを使用しないでください。これは別のチェックであり、手順書の要件を満たしません。<ENV>が不明な場合は、想定した値を明記し、その値でコマンドを実行してください。 -
最初に見つかった根本原因の調査で止めること。 複数のサービスに影響がある場合は、それぞれを個別に調査して報告してください。原因が異なる可能性があるため、サービスごとに修正方法を提示してください。
ステップ 2:仮説を立てる
調査を始める前に、トリアージの結果に基づいて、優先順位を付けた仮説を明示してください。この手順を省略しないでください。
同じ名前空間で複数のサービスに影響があるとユーザーから報告された場合は、それぞれを個別に診断してください。 2 つの Pod でインジェクションが失敗していても、その原因はまったく異なる場合があります(片方はオプトアウトアノテーション、もう片方は名前空間ラベルの欠落、さらにもう片方は ddtrace がすでに存在している、など)。共通の根本原因があると決めつけず、各サービスの Pod 仕様、アノテーション、ランタイムを個別に調査し、サービスごとに調査結果を提示してください。
| トリアージのシグナル | 有力な仮説 |
|---|---|
| トレースが届いている + サービスが tracers list に表示されている | どちらのシグナルもサービス単位のため、部分的なロールアウトでは、これらが有効でも、ユーザーが指定した特定の Pod はインスツルメントされていない可能性があります。まず、この Pod がインスツルメントされていることを確認してください(トリアージ時の kubectl チェックで init コンテナが存在するか、または admission.datadoghq.com/status: injected アノテーションがあるかを確認します)。インスツルメントされている場合は、UI フィルターまたは時間範囲の問題が考えられます。その旨をユーザーに伝えて、終了してください |
| トレースが届いていない + この Pod に init コンテナがない | この Pod ではインジェクションが行われていません。名前空間の対象設定、Webhook、Pod セレクター、オプトアウトアノテーション、Pod が再起動されていない(部分的なロールアウト)などを調査してください。Pod ごとの init コンテナ確認が決定的な判断基準です。部分的なロールアウトでは、ほかの Pod からの情報によってサービスが tracers list に表示され続けることがあるため、サービス単位の肯定的なシグナルによって、この Pod がインスツルメントされていない事実を見落とさないでください |
| トレースが届いていない + サービスが tracers list に表示されていない + init コンテナがある | トレーサーはインジェクションされていますが、レポートしていません。tracers list はテレメトリーから生成されるため、正しくインジェクションされた Pod でも、レポートできない場合やレポート前の場合は表示されません。Agent への接続、DD_SITE の不一致、API キー、送信トラフィックのブロック、テレメトリーの遅延を調査してください。(実際のインジェクション失敗は、ここではなく、init コンテナの欠落、または init コンテナのエラーとして現れます。下記の CrashLoopBackOff の行を参照してください。) |
| トレースが届いていない + サービスが tracers list に表示されている + init コンテナがある | トレーサーはテレメトリーをレポートしています(つまり、Agent への接続、API キー、DD_SITE は機能しています)が、スパンは届いていません。トレース固有の原因を調査してください。トラフィックがない/アプリがまだリクエストを処理していない、サンプリングルール、取り込み/保持フィルター、trace-agent のレシーバーなどが考えられます |
| Pod のイベントに CrashLoopBackOff または init コンテナのエラーが表示されている | init コンテナの失敗です。既存の ddtrace とランタイムバージョンを確認してください |
| トレースは届いているが、サービス名/環境が誤っている | Deployment で UST ラベルが欠落しているか、誤って設定されています |
優先度の高い仮説を 1〜3 個、明示してください。例:「トリアージの結果から、最も可能性が高い原因は X です。理由は Y です。」
ステップ 3:調査する
仮説に関連するツールのみを使用してください。それぞれの観察結果をもとに、次のアクションを決めてください。
クラスター側の調査ツール
Pod は Agent と同じ名前空間にありますか? SSI は Datadog Agent と同じ名前空間にある Pod をインスツルメントしません。
kubectl get pods -n <AGENT_NAMESPACE>
SSI を有効にした後、Pod は再起動されましたか?
再起動する前に、必ずユーザーに確認してください。 ユーザーに次のように伝えてください:「SSI で Pod にインジェクションするには、Pod を再起動する必要があります。
<DEPLOYMENT_NAME>を<APP_NAMESPACE>で再起動します。実行してもよろしいですか?」確認が得られるまで待ってください。
Claude の実行
kubectl rollout restart deployment/<DEPLOYMENT_NAME> -n <APP_NAMESPACE>
kubectl wait --for=condition=Ready pod -l app=<APP_LABEL> -n <APP_NAMESPACE> --timeout=120s
Claude の実行
# Primary — authoritative and immediate: confirm the freshly-restarted pods carry the init container.
# Label-scoped, not by <POD_NAME>: a rolling restart replaces the old pod with new-suffixed ones.
kubectl get pod -l app=<APP_LABEL> -n <APP_NAMESPACE> \
-o jsonpath='{.items[0].spec.initContainers[*].name}'
# Secondary — eventual: the service reappears here once the restarted pod reports telemetry
# (subject to a propagation delay of a minute or more, and only if the pod serves traffic)
pup fleet tracers list --filter "service:<SERVICE_NAME>"
kubectl の init コンテナの確認結果は、再起動後の信頼できるシグナルです。その init コンテナが表示された時点で、Pod への注入が行われています。tracers list はテレメトリーに基づくため反映が遅れます。再起動直後の空の結果を「注入されなかった」と判断しないでください。
名前空間に Admission Controller のオプトインラベルが付いていますか?
Admission Controller が mutateUnlabelled: false で実行されている場合、admission.datadoghq.com/mutate-pods=true という明示的なラベルが付いた名前空間でのみ注入が行われます。このラベルがない名前空間では、その中のすべての Pod で SSI が通知なくスキップされます。これは、クラスター内のほとんどのサービスにはインスツルメンテーションが適用されているのに、ある名前空間のサービスだけ適用されていない場合によくある原因です。
kubectl get namespace <APP_NAMESPACE> -o jsonpath='{.metadata.labels}'
kubectl get namespace <APP_NAMESPACE> --show-labels
修正方法:名前空間にラベルを付けてから、影響を受けるデプロイメントを再起動し、Pod の再作成時に AC が変更を適用するようにします。
kubectl label namespace <APP_NAMESPACE> admission.datadoghq.com/mutate-pods=true
名前空間のターゲット設定によって Pod が除外されていますか?
kubectl get datadogagent datadog -n <AGENT_NAMESPACE> -o yaml | grep -A 15 instrumentation
修正方法:datadog-agent.yaml の enabledNamespaces を更新します。
Claude の実行
kubectl apply -f datadog-agent.yaml
podSelector ターゲットによって Pod が除外されていますか?
podSelector を含む targets が設定されている場合、セレクターに一致するラベルを持つ Pod のみがインスツルメント化されます。アプリの Pod のラベルがいずれかのターゲットに一致するか確認します:
kubectl get datadogagent datadog -n <AGENT_NAMESPACE> -o yaml | grep -A 20 targets
kubectl get pod <POD_NAME> -n <APP_NAMESPACE> --show-labels
修正方法:Pod テンプレートに一致するラベルを追加するか、podSelector の対象を広げてから、適用して再起動します。
Pod のアノテーションでオプトアウトされている、または AC による注入成功を示すアノテーションがありませんか? 確認するアノテーションは次の 2 つです:
admission.datadoghq.com/enabled: "false"— 明示的なオプトアウトです。AC は Pod をスキップします。admission.datadoghq.com/status: injected— 変更が成功した後に AC が設定します。稼働中の Pod にこれがない場合、AC が一度も変更を適用していないことを示す確かな証拠です。
kubectl get pod <POD_NAME> -n <APP_NAMESPACE> -o jsonpath='{.metadata.annotations}'
kubectl get pod <POD_NAME> -n <APP_NAMESPACE> -o yaml | grep -A 10 annotations
修正方法:Deployment の Pod テンプレートからオプトアウトのアノテーションを削除してから、適用して再起動します。
稼働中の Pod に、想定される DD_* 環境変数がありますか?
SSI は Pod に変更を適用する際、DD_SERVICE、DD_ENV、DD_VERSION、DD_TRACE_*、および LD_PRELOAD をコンテナの環境変数に注入します。これらがない場合は変更が実行されなかったことを確認でき、想定外の値がある場合は UST ラベルの不一致または ddTraceConfigs の問題が考えられます。
kubectl exec -n <APP_NAMESPACE> <POD_NAME> -- env | grep -E '^(DD_|LD_PRELOAD)'
kubectl describe pod <POD_NAME> -n <APP_NAMESPACE> | grep -E 'DD_|LD_PRELOAD'
Claude の実行
kubectl apply -f <your-app-deployment.yaml>
再起動する前にユーザーに確認してください。 ユーザーに「この変更を反映するには、
<APP_NAMESPACE>内の<DEPLOYMENT_NAME>を再起動する必要があります。進めてもよろしいですか?」と伝え、確認を待ちます。
Claude の実行
kubectl rollout restart deployment/<DEPLOYMENT_NAME> -n <APP_NAMESPACE>
アプリに既存のカスタムインスツルメンテーションがありますか? 既存のトレーサーコードが検出されると、SSI は通知なく無効になります。ソースファイルを検索します:
- Python:
import ddtrace、ddtrace.patch_all() - Node.js:
require('dd-trace')、DD.init() - Java:
GlobalTracer.register(、dd-java-agent - .NET:
Tracer.Instance、DD.Trace - Ruby:
require 'ddtrace'、Datadog.configure - PHP:
DDTrace\
依存関係マニフェストも確認します:requirements.txt、package.json、Gemfile、pom.xml。
修正方法:import またはパッケージを削除し、イメージを再ビルドしてクラスターに再読み込みし、Pod を再起動します。
ベースイメージは Alpine(musl libc)ですか?
K8s SSI は LD_PRELOAD を Pod の環境変数として注入します。/etc/ld.so.preload には依存しないため、musl/Alpine イメージはサポートされています。これは Kubernetes SSI の妨げにはなりません。
ランタイムのバージョンはサポートされていますか?
kubectl exec -n <APP_NAMESPACE> <POD_NAME> -- python --version
kubectl exec -n <APP_NAMESPACE> <POD_NAME> -- node --version
kubectl exec -n <APP_NAMESPACE> <POD_NAME> -- java -version
SSI の互換性マトリックスで確認します。
Admission Webhook は登録されていますか?
kubectl get mutatingwebhookconfigurations | grep datadog
kubectl get pods -n <AGENT_NAMESPACE> -l app=datadog-cluster-agent
kubectl logs -n <AGENT_NAMESPACE> -l app=datadog-cluster-agent --tail=100
注入時にエラーが発生しましたか? まずノードのホスト名を取得してから、Datadog に問い合わせて注入エラーを確認します:
kubectl get pod <POD_NAME> -n <APP_NAMESPACE> -o jsonpath='{.spec.nodeName}'
pup apm troubleshooting list --hostname <NODE_HOSTNAME> --timeframe 1h
Agent は Datadog にデータを送信していますか?
kubectl exec -n <AGENT_NAMESPACE> \
$(kubectl get pod -n <AGENT_NAMESPACE> -l app=datadog-agent -o name | head -1) \
-- agent status | grep -A 5 "APM Agent"
Datadog 側の調査ツール
トレーサーはレポートを送信していますか?
pup fleet tracers list --filter "service:<SERVICE_NAME>"
APM はサービスを認識していますか?
pup apm services list --env <ENV>
サービスで実行されている SDK の設定は何ですか?
トレーサーに設定されている環境変数(例:DD_TRACE_ENABLED、DD_SERVICE、DD_ENV、サンプリングルール)が表示されます。enable-ssi で ddTraceConfigs が設定されていない場合、出力が空でも問題ありません。出力があり、設定内容と一致しない場合は、変更が反映されていないことを示します。
pup apm service-library-config get --service-name <SERVICE_NAME> --env <ENV>
トレースは到着していますか?
pup traces search --query "service:<SERVICE_NAME>" --from 1h --limit 10
トレーサーはどのエージェントに接続していますか? トレーサーと Agent の接続に問題が疑われる場合に使用してください。
pup fleet agents list --filter "hostname:<NODE_HOSTNAME>"
pup fleet agents tracers <AGENT_KEY> --filter "service:<SERVICE_NAME>"
ステップ 4:結論を出す前に振り返る
修正を適用する前に、次の質問に答えてください。
- 仮説を裏付ける証拠は何ですか?
- 仮説に反する証拠はありますか?また、それを確認しましたか?
- まだ検討していない、より単純な説明はありませんか?
結論が成り立たない場合は、新しい仮説を立ててステップ 2 に戻ります。3 つすべての質問に対して結論を説明できるまで、検証を繰り返してください。
ステップ 5:修正する
確認済みの根本原因に対する修正を適用します。コードまたは Dockerfile の変更が必要な場合は、再ビルドして再読み込みします。
Claude が実行
docker build -f <DOCKERFILE_PATH> -t <IMAGE_NAME> <BUILD_CONTEXT>
[DECISION: cluster type]
- kind(ローカル):イメージをクラスターに読み込みます
Claude が実行
kind load docker-image <IMAGE_NAME> --name <CLUSTER_NAME>
- レジストリベース:スキップします。次回のデプロイ時にイメージが取得されます
再起動する前にユーザーの確認を取ってください。 ユーザーに「修正を適用するため、
<APP_NAMESPACE>内の<DEPLOYMENT_NAME>を再起動する必要があります。進めてもよろしいですか?」と伝え、確認を待ちます。
Claude が実行
kubectl rollout restart deployment/<DEPLOYMENT_NAME> -n <APP_NAMESPACE>
kubectl wait --for=condition=Ready pod -l app=<APP_LABEL> -n <APP_NAMESPACE> --timeout=120s
ステップ 6:検証する
トリアージを再実行し、修正が機能したことを確認します。
Claude が実行
pup traces search --query "service:<SERVICE_NAME>" --from 1h --limit 5
pup fleet tracers list --filter "service:<SERVICE_NAME>"
トレースが到着している場合は、解決済みです(サービスが pup fleet tracers list に再表示されるまで 1 分ほどかかる場合があります。再起動直後にトレーサーの一覧が空でも、テレメトリーの遅延によるものであり、失敗ではありません)。この時点で自動的に onboarding-summary に進み、ユーザーに許可を求めないでください。
ERROR:トレースが到着していません。新しいトリアージデータを使い、仮説を更新してステップ 2 に戻ります。
セキュリティ上の制約
- 生の API キーをファイルやチャットメッセージに書き込まないでください
- ユーザーの確認なしに
kubectl deleteを実行しないでください admissionControllerの設定を直接変更しないでください- レジストリへの
docker pushは、必ずユーザーの確認を得てから実行してください