kubectl logs と describe を使いこなして効率的なPodデバッグを行う
Kubernetesのような分散環境でアプリケーションをデバッグするのは困難な場合があります。Podが起動しない、再起動ループに入る、または予期しない動作を示す場合、Kubernetesオペレーターのツールキットで最も重要な2つのツールは、kubectl describeとkubectl logsです。
これらのコマンドは、Kubernetes Podの状態と履歴について、異なるが補完的なビューを提供します。kubectl describeは、Podのメタデータ、ステータス、環境変数、そして最も重要なシステムイベントの履歴を提供します。kubectl logsは、コンテナ化されたアプリケーション自体によって生成された標準出力(stdout)と標準エラー(stderr)ストリームを提供します。
これらのコマンドに関連付けられたフラグとテクニックを習得することは、問題を迅速に診断および解決し、クラスター全体のトラブルシューティング効率を大幅に向上させるために不可欠です。
3段階のPodデバッグワークフロー
コマンドに入る前に、典型的なデバッグワークフローを理解しておくと役立ちます。
- ステータスを確認する:
kubectl get podsを使用して、障害状態(Pending、CrashLoopBackOff、ImagePullBackOffなど)を特定します。 - コンテキストとイベントを取得する:
kubectl describe podを使用して、状態遷移が発生した理由(例:スケジューラ障害、livenessプローブ障害、ボリュームのマウント失敗)を理解します。 - アプリケーション出力を確認する:
kubectl logsを使用して、アプリケーションの実行時動作(例:設定エラー、データベース接続障害、スタックトレース)を調べます。
1. kubectl describe: システムトリアージツール
Podの動作が悪い場合に最初に実行すべきコマンドはkubectl describeです。アプリケーションの出力は表示されませんが、Kubernetes自体がPodについて記録した重要なメタデータと履歴を提供します。
基本的な使い方
基本的な使い方は、Pod名のみが必要です。
kubectl describe pod my-failing-app-xyz789
出力の主要セクション
describeの出力をレビューする際は、これらの重要なセクションに焦点を当てます。
A. ステータスと状態
上部にあるStatusフィールドを見て、次にPod内の個々のコンテナの状態をレビューします。これにより、コンテナがRunning、Waiting、またはTerminatedのいずれであるか、そしてその状態の理由がわかります。
| フィールド | 一般的なステータス/理由 | 意味 |
|---|---|---|
Status |
Pending |
Podがスケジュールされるのを待っているか、リソースが不足しています。 |
Reason |
ContainerCreating |
コンテナランタイムがイメージをプルするか、セットアップを実行しています。 |
State |
Waiting / Reason: CrashLoopBackOff |
コンテナが開始され、繰り返し終了しています。 |
State |
Terminated / Exit Code |
コンテナの実行が完了しました。ゼロ以外の終了コードは通常、エラーを示します。 |
B. コンテナ設定
このセクションでは、環境変数、リソース要求/制限、ボリュームマウント、liveness/readinessプローブが正しく定義されており、適用したマニフェストと一致していることを確認します。
C. Eventsセクション(重要)
出力の最下部にあるEventsセクションは、おそらく最も価値のある部分です。KubernetesコントロールプレーンがPodに対して行ったことの時系列ログを提供し、警告やエラーも含まれます。
Eventsによって明らかになる一般的なエラー:
- スケジューリングの問題:
Warning FailedScheduling: スケジューラが適切なノードを見つけられなかったことを示します(例:リソース制約、ノードのtaint、アフィニティルールによる)。 - イメージプル失敗:
Warning Failed: ImagePullBackOff: イメージ名が間違っている、タグが存在しない、またはKubernetesがプライベートレジストリからプルするための認証情報を持っていないことを示します。 - ボリュームエラー:
Warning FailedAttachVolume: 外部ストレージへの接続に問題があることを示します。
ヒント:
Eventsセクションがクリーンな場合、問題は通常アプリケーション関連(実行時クラッシュ、初期化失敗、設定エラー)であるため、次にkubectl logsを使用することになります。
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
3. テクニックを組み合わせて高度な診断を行う
効果的なデバッグは、describeと特定のlogsコマンドを迅速に切り替えることがよくあります。
ケーススタディ:livenessプローブ障害の診断
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プローブが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プローブの失敗により再起動しており、プローブはアプリケーションがデータベースに接続できないために失敗しています。問題は、コンテナ自体ではなく、外部ネットワークまたはデータベースの設定です。
ベストプラクティスと警告
| プラクティス | コマンド | 理由 |
|---|---|---|
| 常に以前のログを確認する | 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 describeとkubectl logsは、Kubernetesでのデバッグに不可欠なコアコマンドです。describeをシステムステータスレポート(設定、イベント、スケジューリングエラーに焦点を当てる)として、logsをアプリケーション実行ストリーム(コードエラーと実行時動作に焦点を当てる)として扱うことで、ほとんどのPod障害の原因を体系的に絞り込み、クラスター内の平均復旧時間(MTTR)を大幅に短縮できます。