テック技報最新号へ →
インフラ

Kubernetes: Pod が Running / Ready にならないときの切り分け手順

@yosshi_ · 2026-10-24
#infra#kubernetes#troubleshooting#probe#kubectl

kubectl get pod の STATUS 列だけ見て原因を決めると外しやすい。-o yaml(Conditions とコンテナの終了状態)→ describe(Events)→ logs の順に見て、どの段階で止まっているかを先に決める。

まず知っておくこと

  • STATUS 列と status.phase は別物。CrashLoopBackOff と表示されていても、再起動対象のコンテナが残っていれば phase は Running のまま
    bash
    kubectl get pod crashloop -o jsonpath='{.status.phase}'   # → Running
  • 健全かどうかは READY 列・RESTARTS 列・Conditions(PodScheduled → PodReadyToStartContainers → Initialized → ContainersReady → Ready)で見る。どこで False になっているかで段階がわかる

手順

  1. kubectl get pod <pod> -o yaml で status.conditions と containerStatuses の state / lastState(終了コード・reason)を見る
  2. kubectl describe pod <pod> の Events で Reason を見る
  3. 起動しているなら kubectl logs <pod> -c <container> --tail=100、落ちているなら --previous で直前の実行のログを見る
  4. ノード側が怪しければ kubectl describe node <node> で MemoryPressure / DiskPressure / PIDPressure と、Requests / Limits の集計を見る(集計は実使用量ではない)

Event Reason から当たりをつける

Reasonよくある原因
FailedSchedulingリソース不足、Affinity / Taint 不一致、PVC が未バインド
Failed(ErrImagePull)→ BackOff(ImagePullBackOff)後者は「再試行待ち」の表示。原因は直前の失敗メッセージにある
Failed(CreateContainerConfigError)存在しない ConfigMap / Secret のキーを参照している
BackOff(CrashLoopBackOff)アプリが終了を繰り返している。--previous のログと終了コードを見る
UnhealthyProbe の失敗(設定ミスか、アプリの実装か)
FailedCreatePodSandBoxランタイムや CNI の失敗
FailedMount / FailedAttachVolumeボリューム

イメージ取得の失敗メッセージは、文言で次の確認先が決まる。

メッセージ確認するもの
not found名前・タグ・push 状況・権限
no such hostレジストリ名、ノードの DNS
timeout / connection refusedProxy・Firewall・ノードからの到達性
unauthorized / 401 / 403imagePullSecrets、Secret の namespace
x509証明書の期限・CA・ノードの信頼設定
429 / 5xxレート制限、ミラーや Proxy

起動直後に落ちるときは、exec format error(イメージとノードの CPU アーキテクチャ違い)、permission denied(実行権限・実行ユーザー)、read-only file system(readOnlyRootFilesystem)も典型。

Probe の考え方

  • Readiness が失敗しても再起動はしない。Service の転送先(EndpointSlice)から外れるだけ。kubectl get endpointslices -l kubernetes.io/service-name=<svc> -o yaml で確認する
  • Liveness / Startup の連続失敗は、コンテナの停止と再起動につながる。起動が遅いアプリは Startup Probe を付けるか、timeoutSeconds・periodSeconds・failureThreshold を合わせる
  • Probe の path が正しいかは kubectl port-forward pod/<pod> 8080:80 してから同じ path を叩いて確かめる
  • DB や外部 API まで見る「deep health check」を Liveness に入れない。共有 DB の一時障害で全 Pod が一斉に再起動し、再接続の集中で復旧がさらに遅れる。Readiness に入れても全 Pod が転送先から外れる。依存先の障害はアプリ側で扱い、DB が要るリクエストだけ 503(必要なら Retry-After)を返す設計も検討する

その他の小技

  • ConfigMap / Secret を環境変数で渡している場合、更新しても既存 Pod には反映されない。kubectl exec <pod> -- printenv KEY で確認し、kubectl rollout restart deployment/<name> で作り直す
  • ServiceAccount の権限不足は kubectl rolesum <sa> -n <ns>(kubectl-rolesum プラグイン)で、持っている権限を一覧できる
  • ログだけで原因がわからなければ、同じイメージと入力で docker run してローカルで再現するか試す。再現しなければ環境差(環境変数・リソース制限・ネットワーク)を疑う

関連

出典

X の元の投稿を開く