Kubernetes(以下、k8s)を実務で運用していると、デプロイしたPodが正常に起動しない(Pending、Failed、CrashLoopBackOffなどの状態のままになる)事象に頻繁に遭遇します。本記事では、Podが起動しない原因を迅速に特定するための調査フロー、具体的なコマンド例、および実務で使えるチェックリストを提供します。
対象読者
- k8s環境でのアプリケーション運用・トラブルシューティングを担当するエンジニア
- Podが起動しない原因の特定に時間がかかっている方
1. 状況把握のための基本コマンド
まずは対象のNamespaceにおいて、どのPodがどのようなステータスになっているかを確認します。
# 全てのPodのステータスを確認する
kubectl get pods -n <namespace>
# 特定のPodの詳細情報を取得する(イベントログの確認に重要)
kubectl describe pod <pod-name> -n <namespace>
kubectl describe コマンドの出力最下部にある Events セクションには、スケジューリングの成否やコンテナイメージのプル状況、Liveness/Readinessプローブの失敗履歴など、起動失敗の直接的な原因が記録されていることが多いため、最初に確認してください。
2. ステータス別の原因と調査手順
Podのステータスに応じて、確認すべきポイントが異なります。
パターンA: Pending(スケジューリング・リソース不足)
Podが Pending のまま動かない場合、k8sクラスターがPodを配置するノードを決定できていません。
主な原因
-
リソース不足: ノードのCPUやメモリが不足している(
Insufficient cpu/Insufficient memory) -
ノードセレクター/アフィニティの不一致:
nodeSelectorやnodeAffinityの条件を満たすノードが存在しない -
Taints(許容値)の不一致: ノードに設定された Taint を Pod の
tolerationsが許容していない - PVC(PersistentVolumeClaim)のバインド待ち: 必要なPVが確保できていない
調査コマンド
# イベントからスケジューリング失敗の理由を確認する
kubectl describe pod <pod-name> -n <namespace> | grep -A 10 Events
# ノードのリソース使用状況を確認する
kubectl top nodes
パターンB: ContainerCreating または ImagePullBackOff(イメージ取得失敗)
コンテナイメージのダウンロードやコンテナの作成段階で停止している状態です。
主な原因
- イメージ名・タグの誤り: 指定したイメージやタグがレジストリに存在しない
-
認証エラー: プライベートレジストリからのプルに必要な
imagePullSecretsが設定されていない、またはシークレットの内容が誤っている - ネットワーク問題: ノードからコンテナレジストリへの通信が遮断されている
調査コマンド
# イメージプルに関するエラーメッセージを確認する
kubectl describe pod <pod-name> -n <namespace> | grep -E "Pulling|Failed|BackOff"
パターンC: CrashLoopBackOff または Error(起動後の異常終了)
コンテナは一度起動したものの、アプリケーションプロセスが異常終了し、再起動を繰り返している状態です。
主な原因
- アプリケーションのエラー: 設定ファイルの不足、DB接続エラー、構文エラーなどによるプロセスの異常終了
- 環境変数の不足・誤り: 起動に必要な環境変数が渡されていない
-
起動コマンド・引数の誤り:
commandやargsの指定が不適切 - Liveness/Readinessプローブの失敗: プローブの設定値(ポート、パス、タイムアウト)が不適切で、k8sから強制終了されている
調査コマンド
# コンテナの標準出力・標準エラー出力を確認する
kubectl logs <pod-name> -n <namespace>
# 複数コンテナがある場合はコンテナ名を指定する
kubectl logs <pod-name> -c <container-name> -n <namespace>
# 再起動を繰り返す前の(1つ前の世代の)ログを確認する
kubectl logs <pod-name> -n <namespace> --previous
3. 実務用トラブルシューティング・チェックリスト
Podが起動しない場合に、上から順に確認するためのチェックリストです。
| 確認順序 | 確認項目 | 該当ステータス | 確認コマンド・確認対象 |
|---|---|---|---|
| 1 | Podのイベントログにエラーがないか | すべて |
kubectl describe pod <pod-name> の Events
|
| 2 | ノードのリソース(CPU/メモリ)に空きはあるか | Pending |
kubectl top nodes または kubectl describe node
|
| 3 | PVCは正常にBoundされているか | Pending |
kubectl get pvc -n <namespace> |
| 4 | イメージ名やタグ、認証情報は正しいか | ImagePullBackOff |
マニフェストの image と imagePullSecrets
|
| 5 | アプリケーションのログにエラーが出力されていないか | CrashLoopBackOff |
kubectl logs <pod-name> --previous |
| 6 | Liveness/Readinessプローブの設定は適切か | CrashLoopBackOff |
マニフェストの livenessProbe / readinessProbe
|
4. 運用上の注意点と対策
resources.limits と resources.requests の適切な設定
requests(要求値)がノードの空き容量に対して大きすぎると、Podは Pending になります。一方で、limits(制限値)を低く設定しすぎると、起動時のCPUバーストやメモリ確保のタイミングで OOMKilled(Out Of Memoryによる強制終了)が発生します。
OOMKilled が発生しているかどうかは、以下のコマンドの Last State 部分で確認できます。
kubectl get pod <pod-name> -n <namespace> -o jsonpath='{.status.containerStatuses[*].lastState.terminated.reason}'
# 出力が "OOMKilled" の場合はメモリ割り当て(limits)の増量を検討してください
最新仕様の確認について
k8sはバージョンアップに伴い、APIの非推奨化(Deprecation)や仕様変更が行われます。特に Probe の挙動や SecurityContext の制約などはバージョンによって異なる場合があるため、トラブルシューティングの際は利用しているk8sクラスターのバージョンに対応した公式ドキュメントを必ず参照してください。
まとめ
Podが起動しないときは、焦らずに 「1. kubectl describe でイベントを確認する」、「2. kubectl logs(必要に応じて --previous)でアプリの挙動を確認する」 という2ステップを徹底することが早期解決への近道です。本記事のフローとコマンドを実務の一次対応にお役立てください。