kubectl logs と describe を極める:効率的なPodデバッグ手法

このガイドでは、Kubernetesのデバッグに不可欠なコマンド「kubectl logs」と「kubectl describe」のエキスパートテクニックを解説します。効率的なトラブルシューティングに必要な重要なフラグ(-f、--tail、-c、--previous)を学びます。describeの「Events」セクションを解釈してスケジューリングや設定の問題を診断する方法、logsを使用してクラッシュするPodやマルチコンテナPodからランタイムエラーを抽出する方法を詳述し、デバッグワークフローを加速します。

kubectl logs と describe を極める:効率的なPodデバッグ手法

KubernetesのPodが失敗したとき、kubectl describekubectl logs は通常、次にどこを見るべきかを教えてくれます。describe はKubernetesが何をしようとしたかを説明します。logs はコンテナが失敗の前、最中、または後に書き込んだ内容を示します。

これらのコマンドは、Kubernetes Podの状態と履歴に対して、異なるものの補完的なビューを提供します。kubectl describe は、Podのメタデータ、ステータス、環境変数、そして重要なことに、システムイベントの履歴を提供します。kubectl logs は、コンテナ化されたアプリケーション自体によって生成された標準出力(stdout)と標準エラー出力(stderr)ストリームを提供します。

コツは、それらを正しい順序で使用することです。Podがスケジュールされなかった場合、ログは役に立ちません。Podが起動して終了した場合、イベントはクラッシュしたことだけを伝えるかもしれません。アプリケーションログは通常、その理由を説明します。


3ステップPodデバッグワークフロー

コマンドの詳細に入る前に、典型的なデバッグワークフローを理解しておくと役立ちます。

  1. ステータスの確認: kubectl get pods を使用して、障害状態(PendingCrashLoopBackOffImagePullBackOff など)を特定します。
  2. コンテキストとイベントの取得: kubectl describe pod を使用して、状態遷移がなぜ発生したかを理解します(例:スケジューラの失敗、liveness probeの失敗、ボリュームのマウント失敗)。
  3. アプリケーション出力の検査: kubectl logs を使用して、アプリケーションのランタイム動作を調べます(例:設定エラー、データベース接続障害、スタックトレース)。

1. kubectl describe:システムトリアージツール

kubectl describe は、Podの動作がおかしいときに最初に実行すべきコマンドです。アプリケーションの出力は表示されませんが、Kubernetes自体がPodについて記録した重要なメタデータと履歴を提供します。

基本的な使い方

基本的な使用法はPod名のみが必要です。

kubectl describe pod my-failing-app-xyz789

デフォルトの名前空間にいない場合は、明示的に名前空間を使用します。

kubectl describe pod my-failing-app-xyz789 -n payments

デプロイメントまたはラベルしかわからない場合は、最初にPodを見つけます。

kubectl get pods -n payments -l app=checkout -o wide

出力の主要セクション

describe の出力を確認するときは、これらの重要なセクションに焦点を当てます。

A. ステータスと状態

上部の Status フィールドを確認し、次にPod内の個々のコンテナ状態を確認します。これにより、コンテナが RunningWaiting、または Terminated のいずれであるか、およびその状態の理由がわかります。

フィールド 一般的なステータス/理由 意味
Status Pending Podがスケジュールされるのを待っているか、リソースが不足しています。
Reason ContainerCreating コンテナランタイムがイメージをプルしているか、セットアップを実行しています。
State Waiting / Reason: CrashLoopBackOff コンテナが起動と終了を繰り返しています。
State Terminated / Exit Code コンテナの実行が完了しました。ゼロ以外の終了コードは通常、エラーを示します。

B. コンテナ設定

このセクションでは、環境変数、リソース要求/制限、ボリュームマウント、liveness/readiness probeが、適用したマニフェストと一致して正しく定義されていることを確認します。

C. Events セクション(重要)

出力の下部にある Events セクションは、間違いなく最も価値のある部分です。これは、KubernetesコントロールプレーンがPodに対して行ったことの時系列ログを提供し、警告やエラーも含まれます。

Events で明らかになる一般的なエラー:

  • スケジューリングの問題: Warning FailedScheduling: スケジューラが適切なノードを見つけられなかったことを示します(例:リソース制約、ノードのテイント、アフィニティルール)。
  • イメージプル失敗: Warning Failed: ImagePullBackOff: イメージ名が間違っている、タグが存在しない、またはKubernetesがプライベートレジストリからプルするための認証情報を欠いていることを示します。
  • ボリュームエラー: Warning FailedAttachVolume: 外部ストレージの接続に関する問題を示します。

ヒント: Events セクションがクリーンでコンテナが起動している場合、問題は多くの場合アプリケーション関連です。環境変数の誤り、マイグレーションの失敗、シークレットの欠落、到達不能な依存関係、または即座に終了するプロセスです。

2. kubectl logs:アプリケーション出力の検査

describe でPodが正常にスケジュールされ、コンテナが実行を試みたことが示された場合、次のステップは kubectl logs を使用して標準出力ストリームを確認することです。

基本的なログ取得とリアルタイムストリーミング

Pod内のプライマリコンテナの現在のログを表示するには:

# 現在の時点までのすべてのログを取得
kubectl logs my-failing-app-xyz789

# ログをリアルタイムでストリーミング(起動の監視に便利)
kubectl logs -f my-failing-app-xyz789

マルチコンテナPodの処理

サイドカーパターンやその他のマルチコンテナ設計を利用するPodの場合、-c または --container フラグを使用して、表示するコンテナのログを指定する必要があります。

# Pod内の 'sidecar-proxy' コンテナのログを表示
kubectl logs my-multi-container-pod -c sidecar-proxy

# メインアプリケーションコンテナのログをストリーミング
kubectl logs -f my-multi-container-pod -c main-app

再起動するコンテナのデバッグ(--previous

最も一般的なデバッグシナリオの1つは、CrashLoopBackOff 状態です。コンテナが再起動すると、kubectl logs現在の(失敗した)試行の出力のみを表示します。これには、クラッシュ前の起動メッセージしか含まれていないことがよくあります。

終了の原因となった実際のエラーを含む、以前の終了したインスタンスのログを表示するには、--previous フラグ(-p)を使用します。

# 以前のクラッシュしたコンテナインスタンスのログを表示
kubectl logs my-crashloop-pod --previous

# 必要に応じてコンテナ指定と組み合わせる
kubectl logs my-crashloop-pod -c worker --previous

出力の制限

大量のログの場合、全履歴を取得するのは遅かったり、圧倒されたりする可能性があります。--tail を使用して、出力を最後のN行に制限します。

# コンテナログの最後の50行のみを表示
kubectl logs my-high-traffic-app --tail=50

タイムスタンプと時間枠を追加することもできます。

kubectl logs my-high-traffic-app --tail=100 --timestamps
kubectl logs my-high-traffic-app --since=10m

デプロイメントの場合、最近の kubectl バージョンでは、ワークロード名を介してログを取得できます。

kubectl logs deploy/checkout-api -n payments --tail=100

それが広すぎる場合は、ラベルセレクターを使用します。

kubectl logs -n payments -l app=checkout --all-containers=true --tail=50

3. 高度な診断のためのテクニックの組み合わせ

効果的なデバッグには、多くの場合、describe と特定の logs コマンドを迅速に切り替えることが含まれます。

ケーススタディ:Liveness Probeの失敗の診断

Podが Running 状態でスタックしているが、断続的に再起動して混乱を引き起こしていると想像してください。

ステップ1: システムビューを確認するために describe をチェック。

kubectl describe pod web-server-dpl-abc

出力のEventsセクションに次のように表示されます。

Type     Reason      Age   From               Message
----     ------      ----  ----               -------
Warning  Unhealthy   2s    kubelet, node-a01  Liveness probe failed: HTTP GET http://10.42.0.5:8080/health failed: 503 Service Unavailable

ステップ1からの結論: コンテナは実行中ですが、Liveness Probeが503エラーで失敗しており、Kubernetesがコンテナを再起動しています。

ステップ2: アプリケーションコンテキストを確認するために logs をチェック。

ここで、アプリケーションが503ステータス(アプリケーションレベルの障害)を返す理由を調査します。

kubectl logs web-server-dpl-abc --tail=200

ログ出力に次のように表示されます。

2023-10-26 14:01:15 ERROR Database connection failure: Timeout connecting to DB instance 192.168.1.10

最終結論: PodはLiveness Probeの失敗により再起動しており、アプリケーションがデータベースに接続できないためにProbeが失敗しています。問題は、コンテナ自体ではなく、外部ネットワーキングまたはデータベース設定です。

ケーススタディ:ログのないPending Pod

Pending 状態のPodは、まだコンテナが起動していないため、有用なコンテナログがないことがよくあります。

kubectl get pod report-worker-6f9c7b9b7d-f2q8m -n analytics

出力:

NAME                                  READY   STATUS    RESTARTS   AGE
report-worker-6f9c7b9b7d-f2q8m        0/1     Pending   0          4m

直接 describe に進みます。

kubectl describe pod report-worker-6f9c7b9b7d-f2q8m -n analytics

Eventsに次のように表示される可能性があります。

Warning  FailedScheduling  default-scheduler  0/6 nodes are available: 6 Insufficient memory.

それはアプリケーションのバグではありません。Podがスケジューラが配置できる以上のメモリを要求しています。次のステップは、デプロイメントの要求、クラスター容量、ノードのテイント、およびオートスケーラーの動作を検査することです。

kubectl get deploy report-worker -n analytics -o yaml
kubectl top nodes

ケーススタディ:ImagePullBackOff

ImagePullBackOff の場合、コンテナイメージが起動しなかったため、ログは通常空です。describe が有用なエラーを提供します。

kubectl describe pod api-7dfb9c8b7f-bd2p9 -n staging

一般的なイベントメッセージには、存在しないイメージタグ、プライベートレジストリに対する認証失敗、またはレジストリに到達する際のDNS/ネットワーク問題が含まれます。修正は、タグを修正するのと同じくらい簡単かもしれません。

kubectl set image deploy/api api=registry.example.com/api:2026-05-24 -n staging

または、イメージプルシークレットを確認する必要があるかもしれません。

kubectl get secret regcred -n staging
kubectl describe serviceaccount default -n staging

ケーススタディ:静かなアプリケーションを持つマルチコンテナPod

サイドカーは、間違ったコンテナを見るとシグナルを隠す可能性があります。最初にコンテナ名をリストします。

kubectl get pod checkout-84f7c9d7bf-px5mx -n payments \
  -o jsonpath='{.spec.containers[*].name}{"\n"}'

次に、各コンテナを意図的に検査します。

kubectl logs checkout-84f7c9d7bf-px5mx -n payments -c checkout --tail=100
kubectl logs checkout-84f7c9d7bf-px5mx -n payments -c envoy --tail=100

アプリのログが静かだが、プロキシのログがアップストリーム接続の失敗を示している場合、PodはKubernetesの観点からは正常である可能性がありますが、トラフィックはサービスメッシュまたはプロキシ設定を介して依然として失敗します。

ベストプラクティスと警告

プラクティス コマンド 根拠
常に以前のログを確認する kubectl logs --previous CrashLoopBackOff の診断に必要です。重大なエラーはほとんどの場合、前回の実行にあります。
コンテナを指定する kubectl logs -c <name> マルチコンテナPodでの曖昧さを回避し、意図しないサイドカーからのログ取得を防ぎます。
バルク操作にラベルを使用する kubectl logs -l app=frontend -f セレクターに一致する複数のPodから同時にログをストリーミングできます(ローリングアップデートに便利)。
警告: ログローテーション N/A Kubernetesノードはログローテーションを実行します。ノードの設定された保持ポリシー(多くの場合、数日またはサイズベース)より古いログは削除され、kubectl logs では利用できなくなります。長期的な保持には、外部の集中ログソリューション(例:Fluentd、Loki、Elastic Stack)を使用してください。

これらのコマンドが教えてくれないこと

kubectl logs は、ノードによって保持されているコンテナのstdoutとstderrのみを表示します。アプリケーションがコンテナ内のファイルに書き込む場合、kubectl logs は何も表示しない可能性があります。これはkubectlの問題ではなく、ロギング設計の問題です。

kubectl describe はKubernetesオブジェクトの状態と最近のイベントを表示しますが、イベントは永続的な監査ログではありません。古いイベントは期限切れになります。長時間の調査の場合は、関連する出力をインシデントノートにコピーしてください。

どちらのコマンドもメトリクスに代わるものではありません。CPUスロットリング、メモリプレッシャー、またはダウンストリームレイテンシがユーザーから見える問題を引き起こしている間、Podは実行中で正常にログを記録している可能性があります。describelogs の後によく使用されるコマンドは次のとおりです。

kubectl top pod -n payments
kubectl top node
kubectl get events -n payments --sort-by=.lastTimestamp

KubernetesがPodを作成または実行し続けることができなかった場合は、最初に describe を使用します。Podは実行中だがアプリケーションの動作がおかしい場合は、最初に logs を使用します。プラットフォームの症状とアプリケーションの症状を分離できるまで、それらを切り替えて使用します。

再利用可能なデバッグフロー

プレッシャーがかかっているときは、毎回同じフローを使用します。

kubectl get pod <pod> -n <namespace> -o wide
kubectl describe pod <pod> -n <namespace>
kubectl logs <pod> -n <namespace> --all-containers=true --tail=100
kubectl logs <pod> -n <namespace> --all-containers=true --previous --tail=100
kubectl get events -n <namespace> --sort-by=.lastTimestamp

順序が重要です。get pod -o wide は、ノード、Pod IP、再起動回数、および経過時間を教えてくれます。describe は、スケジューリング、イメージ、ボリューム、プローブ、およびコンテナ状態の詳細を教えてくれます。現在のログは、実行中のコンテナが現在何をしているかを示します。以前のログは、すでに発生したクラッシュをキャッチします。イベントは、同じ問題が名前空間全体で発生しているかどうかを示します。

デプロイメントの場合は、ロールアウトチェックを追加します。

kubectl rollout status deploy/<name> -n <namespace>
kubectl describe deploy/<name> -n <namespace>
kubectl get rs -n <namespace> -l app=<label>

デバッグしているPodが、ロールアウト中の古いReplicaSetからのものである場合があります。デプロイメントを修正しても、終了中の古いPodからログを読み続けると、30分間間違った問題を追いかける可能性があります。

再起動を正しく解釈する

RESTARTS 列は手がかりであり、診断ではありません。ノードドレイン後の再起動回数 1 は無害かもしれません。毎分増加する再起動回数は、進行中の障害です。describe を使用して最後の状態を確認します。

Last State:     Terminated
  Reason:       Error
  Exit Code:    1
  Started:      Sun, 24 May 2026 10:14:02 +0800
  Finished:     Sun, 24 May 2026 10:14:07 +0800

終了コード 1 は通常、プロセスが一般的なアプリケーションエラーで終了したことを意味します。137 は多くの場合、プロセスが強制終了されたことを意味し、一般的にはメモリ制限を超えたためですが、Reason フィールドとノード/コンテナランタイムコンテキストで確認する必要があります。143 は、正常終了中にプロセスがSIGTERMを受信したときによく表示されます。すべての非ゼロ終了コードを同じ種類の障害として扱わないでください。

メモリが疑われる場合は、次の項目を探します。

Reason:       OOMKilled
Exit Code:    137

次に、コンテナ制限と実際の使用量を比較します。

kubectl describe pod <pod> -n <namespace> | rg -A5 'Limits|Requests'
kubectl top pod <pod> -n <namespace>

metrics-serverがインストールされていない場合、kubectl top は機能しません。その場合は、プラットフォームのメトリクスシステムまたはノードレベルのツールを使用してください。