Kubernetes Pod障害のトラブルシューティング:包括的なガイド
Kubernetes Podは、エコシステムにおける最小のデプロイ可能な単位であり、アプリケーションを動かすコンテナを実行します。Podが失敗すると、サービスの可用性と信頼性に直接影響します。Pod障害を迅速かつ正確に診断することは、Kubernetes管理者や開発者にとって不可欠なスキルです。
このガイドでは、最も一般的なPod障害シナリオを診断するための構造化された段階的なアプローチを提供します。検査に使用される必須のkubectlコマンド、さまざまなPodステータスの解釈、およびアプリケーションを安定した実行状態に復元するための実行可能な解決策について説明します。
Pod診断の3つの柱
トラブルシューティングは、障害のあるPodに関する利用可能なすべての情報を収集するために、3つの主要なkubectlコマンドを使用することから始まります。
1. 初期ステータスチェック (kubectl get pods)
最初のステップは常に、Podとそのコンテナの現在の状態を判断することです。STATUS列とREADY列に特に注意してください。
kubectl get pods -n my-namespace
Podステータスの解釈
| ステータス | 意味 | 初期の対応 |
|---|---|---|
| Running | Podは正常で、すべてのコンテナが実行中です。 | (readiness probeが失敗していない限り、おそらく問題なし) |
| Pending | PodはKubernetesによって受け入れられましたが、コンテナはまだ作成されていません。 | スケジューリングイベントまたはイメージプルステータスを確認してください。 |
| CrashLoopBackOff | コンテナが起動し、クラッシュし、Kubeletが繰り返し再起動を試みています。 | アプリケーションログを確認してください (kubectl logs --previous)。 |
| ImagePullBackOff | Kubeletが必要なコンテナイメージをプルできません。 | イメージ名、タグ、およびレジストリの認証情報を確認してください。 |
| Error | ランタイムエラーまたは起動コマンドの失敗によりPodが終了しました。 | ログとdescribeイベントを確認してください。 |
| Terminating/Unknown | Podがシャットダウン中であるか、Kubeletホストが応答しません。 | ノードのヘルスを確認してください。 |
2. 詳細な調査 (kubectl describe pod)
ステータスがRunning以外の場合、describeコマンドは、スケジューリングの決定、リソース割り当て、コンテナの状態を詳述する重要なコンテキストを提供します。
kubectl describe pod [POD_NAME] -n my-namespace
出力の以下のセクションに注目してください。
- Containers/Init Containers:
State(特にWaitingまたはTerminated) とLast State(障害理由がよく記録される箇所。例:Reason: OOMKilled) を確認します。 - Resource Limits:
LimitsとRequestsが正しく設定されていることを確認します。 - Events: これは最も重要なセクションです。イベントは、スケジューリングの失敗、ボリュームマウントの問題、イメージプルの試行など、ライフサイクル履歴を示します。
ヒント:
Eventsセクションに「0/N nodes available」のようなメッセージが表示される場合、Podはリソース不足 (CPU、メモリ) またはアフィニティルールが満たされていないためにスケジュールに失敗している可能性が高いです。
3. ログの確認 (kubectl logs)
ランタイムアプリケーションの問題については、ログがプロセスが終了した理由を説明するスタックトレースやエラーメッセージを提供します。
# 現在のコンテナログを確認
kubectl logs [POD_NAME] -n my-namespace
# Pod内の特定のコンテナのログを確認
kubectl logs [POD_NAME] -c [CONTAINER_NAME] -n my-namespace
# CrashLoopBackOffに不可欠: 以前に失敗した実行のログを確認
kubectl logs [POD_NAME] --previous -n my-namespace
一般的なPod障害シナリオと解決策
ほとんどのPod障害は、いくつかの認識可能なパターンに分類され、それぞれにターゲットを絞った診断アプローチが必要です。
シナリオ1: CrashLoopBackOff
これは最も頻繁なPod障害です。コンテナは正常に起動していますが、コンテナ内のアプリケーションがすぐに終了している (ゼロ以外の終了コードで) ことを意味します。
診断:
1. kubectl logs --previousを使用して、トレースバックまたは終了理由を表示します。
2. kubectl describeを使用して、Last StateセクションのExit Codeを確認します。
一般的な原因と修正:
- 終了コード 1/2: 一般的なアプリケーションエラー、設定ファイルの欠落、データベース接続の失敗、または不正な入力によるアプリケーションのクラッシュ。
- 修正: アプリケーションコードをデバッグするか、マウントされているConfigMaps/Secretsを確認します。
- 依存関係の欠落: エントリポイントスクリプトに必要なファイルや環境が存在しない。
- 修正: Dockerfileとイメージビルドプロセスを確認します。
シナリオ2: ImagePullBackOff / ErrImagePull
これは、KubeletがPod定義で指定されたコンテナイメージを取得できない場合に発生します。
診断:
1. kubectl describeのEventsセクションで特定のエラーメッセージ (例: 404 Not Foundまたはauthentication required) を確認します。
一般的な原因と修正:
- タイプミスまたは間違ったタグ: イメージ名またはタグが間違っている。
- 修正: DeploymentまたはPod仕様のイメージ名を修正します。
- プライベートレジストリへのアクセス: クラスターがプライベートレジストリ (Docker Hub、GCR、ECRなど) からプルするための認証情報を持っていない。
- 修正: 適切な
imagePullSecretがPod仕様で参照されており、そのSecretがnamespaceに存在することを確認します。
- 修正: 適切な
# プルシークレットを使用するためのPod仕様の例
spec:
containers:
...
imagePullSecrets:
- name: my-registry-secret
シナリオ3: Pendingステータス (スタック)
PodがPendingステータスのままになるのは、通常、ノードにスケジュールできないか、リソース (PersistentVolumeなど) を待っていることを示しています。
診断:
1. kubectl describeを実行し、Eventsセクションを確認します。
一般的な原因と修正:
- リソースの枯渇: クラスターに、Podの
requestsを満たすのに十分なCPUまたはメモリを持つノードがない。- 修正: クラスターサイズを増やすか、Podのリソース要求を減らします (可能な場合)。
- イベントメッセージの例:
0/4 nodes are available: 4 Insufficient cpu.
- ボリュームバインディングの問題: Podが、基となる
PersistentVolume(PV) にバインドできないPersistentVolumeClaim(PVC) を必要としている。- 修正: PVCのステータス (
kubectl get pvc) を確認し、StorageClassが機能していることを確認します。
- 修正: PVCのステータス (
シナリオ4: OOMKilled (メモリ不足により強制終了)
これは通常CrashLoopBackOffステータスになりますが、根本原因は特定されています。コンテナがその仕様で定義された制限よりも多くのメモリを使用したため、ホストオペレーティングシステム (Kubelet経由) が強制的に終了させたものです。
診断:
1. kubectl describe -> Last State -> Reason: OOMKilled を確認します。
修正:
- 制限の増加: Pod仕様のメモリ
limitを増やし、より多くの余裕を与えます。 - アプリケーションの最適化: アプリケーションをプロファイルして、メモリフットプリントを削減します。
- リクエストの設定: スケジューリングの信頼性を向上させるために、
requestsが実際の定常状態の使用量に近い値に設定されていることを確認します。
resources:
limits:
memory: "512Mi" # この値を増やします
requests:
memory: "256Mi"
将来の障害を防ぐ: ベストプラクティス
堅牢なアプリケーションには、一般的なデプロイの落とし穴を防ぐための慎重な設定が必要です。
LivenessおよびReadinessプローブを使用する
プローブを適切に実装することで、Kubernetesはコンテナのヘルスをインテリジェントに管理できます。
- Livenessプローブ: コンテナが実行を継続するのに十分なヘルス状態にあるかを判断します。livenessプローブが失敗した場合、Kubeletはコンテナを再起動します (ソフトロックを解決する)。
- Readinessプローブ: コンテナがトラフィックを処理する準備ができているかを判断します。readinessプローブが失敗した場合、Podはサービスエンドポイントから削除され、コンテナが回復する間、失敗したリクエストを防ぎます。
リソース制限とリクエストを強制する
常にコンテナのリソース要件を定義してください。これにより、Podが過剰なリソースを消費するのを防ぎ (ノードの不安定化につながる)、スケジューラが十分な容量を持つノードにPodを配置できることが保証されます。
セットアップにInitコンテナを利用する
メインアプリケーションが起動する前にPodが依存関係のチェックやデータセットアップを必要とする場合 (例: データベース移行の完了を待つ)、Initコンテナを使用します。Initコンテナが失敗した場合、Podはそれを繰り返し再起動し、セットアップエラーをアプリケーションのランタイムエラーから明確に分離します。
結論
Kubernetes Podのトラブルシューティングを習得するには、kubectl get、kubectl describe、およびkubectl logsの出力に大きく依存する体系的なアプローチが不可欠です。Podステータスを体系的に分析し、イベント履歴を読み解き、一般的な終了コードを理解することで、CrashLoopBackOff、ImagePullBackOff、およびリソース関連の障害を迅速に診断し解決し、一貫したアプリケーションの稼働時間を確保できます。