Home / ネットワーク・IT / パソコン スマホ 周辺機器 / 【2026年最新版】KubernetesでPodがCrashLoopBackOffになる原因と対処法【完全ガイド】

【2026年最新版】KubernetesでPodがCrashLoopBackOffになる原因と対処法【完全ガイド】

※本ページにはプロモーション(広告)が含まれています

【2026年最新版】KubernetesでPodがCrashLoopBackOffになる原因と対処法【完全ガイド】

KubernetesクラスターでPodが起動→クラッシュ→再起動を繰り返す「CrashLoopBackOff」状態になってしまった——そんな状況で困っていませんか?本記事では、CrashLoopBackOffの原因特定から、リソース制限・Probe設定・ConfigMap/Secretの設定ミス・イメージタグの問題まで、実践的な対処法を完全解説します。

この記事でわかること

  • CrashLoopBackOffとは何か・どんな状態か
  • kubectl logs / describe pod でのログ確認と原因特定
  • resource limits(CPU/メモリ)の適切な設定方法
  • Liveness/Readiness Probeの調整による誤検知の解消
  • ConfigMap・Secretの設定ミスの特定と修正
  • コンテナイメージタグの問題と解決
  • 依存サービス(データベース等)の起動順序問題

CrashLoopBackOffとは何か

CrashLoopBackOffとは、KubernetesのPodが以下のサイクルを繰り返している状態です。

  1. Podが起動(Running状態になる)
  2. コンテナ内のプロセスがエラーで終了(exit code 0以外)
  3. KubernetesがPodを再起動(バックオフ遅延付き)
  4. また起動して失敗し、再起動を繰り返す

「BackOff」の部分は、再起動のたびに待機時間が指数関数的に増加すること(10秒 → 20秒 → 40秒 → 最大5分)を示します。

# Podの状態確認
kubectl get pods -n namespace-name

# 出力例
NAME                      READY   STATUS             RESTARTS   AGE
my-app-7d8f9b5c4-xk2m9   0/1     CrashLoopBackOff   5          8m

RESTARTS カウントが増え続け、STATUS が CrashLoopBackOff になっているのが特徴です。

ステップ1: kubectl logs / describe pod で原因を特定する

ログを確認する(最重要)

# 現在のPodのログを確認
kubectl logs my-app-7d8f9b5c4-xk2m9 -n namespace-name

# 前回クラッシュしたコンテナのログ(--previous フラグ)
kubectl logs my-app-7d8f9b5c4-xk2m9 -n namespace-name --previous

# ログをリアルタイムで追う
kubectl logs -f my-app-7d8f9b5c4-xk2m9 -n namespace-name

# 複数コンテナがある場合はコンテナ名を指定
kubectl logs my-app-7d8f9b5c4-xk2m9 -c container-name -n namespace-name

重要: CrashLoopBackOffでは、Podが終了してから次の起動まで時間があります。--previous フラグで前回クラッシュ時のログを見ることが特に重要です。

kubectl describe pod でイベントを確認

kubectl describe pod my-app-7d8f9b5c4-xk2m9 -n namespace-name

出力の最下部にある「Events」セクションに重要な情報が含まれています。

Events:
  Type     Reason     Age               From               Message
  ----     ------     ----              ----               -------
  Normal   Scheduled  10m               default-scheduler  Successfully assigned default/my-app to node01
  Normal   Pulling    10m               kubelet            Pulling image "my-app:latest"
  Normal   Pulled     10m               kubelet            Successfully pulled image "my-app:latest"
  Normal   Created    10m (x3 over 9m)  kubelet            Created container my-app
  Normal   Started    10m (x3 over 9m)  kubelet            Started container my-app
  Warning  BackOff    2m (x8 over 8m)   kubelet            Back-off restarting failed container

exit code から原因を推定する

Exit Code 意味 よくある原因
1 アプリケーションエラー 設定ミス、DB接続失敗、コードのバグ
2 シェル組み込みコマンドの誤用 entrypointスクリプトのエラー
126 コマンドが実行不可 権限不足、実行ファイルが存在しない
127 コマンドが見つからない entrypointのパスが誤っている
137 OOMKill(メモリ不足で強制終了) memory limitが低すぎる
143 SIGTERMで終了 Liveness Probeによる強制再起動

原因1: resource limits(リソース制限)の問題

OOMKillによるCrashLoopBackOff

memory limitが低すぎると、コンテナがメモリを使いすぎた際にOOM Killer(Out of Memory Killer)に強制終了されます。exit code 137 が特徴です。

# OOMKillを確認
kubectl describe pod my-app-7d8f9b5c4-xk2m9 | grep -i oom

# または Events セクションで
# Reason: OOMKilling  Message: Memory limit reached.

resource limits の適切な設定

# deployment.yaml の resource 設定例
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  template:
    spec:
      containers:
      - name: my-app
        image: my-app:1.0.0
        resources:
          requests:
            memory: "128Mi"   # 最低限必要なメモリ(スケジューリングに使用)
            cpu: "250m"       # 最低限必要なCPU(250ミリコア = 0.25コア)
          limits:
            memory: "512Mi"   # 上限メモリ(超えるとOOMKill)
            cpu: "500m"       # 上限CPU(超えるとスロットリング、終了はしない)

ベストプラクティス:

  • まず limits なしでデプロイし、実際のメモリ使用量を kubectl top pods で計測
  • 計測値の1.5〜2倍を limits.memory に設定
  • requestslimits を極端に乖離させない(QoS ClassがBurstableになる)

実際のリソース使用量を確認する

# metrics-server が必要
kubectl top pods -n namespace-name
kubectl top nodes

原因2: Liveness/Readiness Probe の設定ミス

Liveness Probeによる誤検知

Liveness Probeが厳しすぎると、アプリが起動中(初期化処理中)にKubernetesがコンテナを異常と判断して強制再起動します。これがCrashLoopBackOffの一因になります。

# Probe設定の確認
kubectl describe pod my-app-7d8f9b5c4-xk2m9 | grep -A 10 "Liveness\|Readiness"

Probe設定の改善例

containers:
- name: my-app
  livenessProbe:
    httpGet:
      path: /healthz
      port: 8080
    # 最初のチェックまでの待機時間(デフォルト0秒 → 30秒に増やす)
    initialDelaySeconds: 30
    # チェック間隔(デフォルト10秒)
    periodSeconds: 10
    # タイムアウト(デフォルト1秒 → 5秒に増やす)
    timeoutSeconds: 5
    # 失敗と判定するまでの連続失敗回数(デフォルト3回)
    failureThreshold: 3
    # 成功判定の連続成功回数(Livenessは1が推奨)
    successThreshold: 1

  readinessProbe:
    httpGet:
      path: /ready
      port: 8080
    initialDelaySeconds: 10
    periodSeconds: 5
    timeoutSeconds: 3
    failureThreshold: 3
    successThreshold: 1

  # Kubernetes 1.18+ ではStartup Probeを使用(起動時間が長いアプリに最適)
  startupProbe:
    httpGet:
      path: /healthz
      port: 8080
    # 最大で failureThreshold × periodSeconds 秒待機(ここでは300秒)
    failureThreshold: 30
    periodSeconds: 10

Startup Probe の活用: 起動に時間がかかるアプリ(Java Spring Boot、データ移行処理など)では、Startup Probeを使うことでLiveness Probeが起動中に誤検知するのを防げます。

原因3: ConfigMap・Secretの設定ミス

よくある設定ミスパターン

  • 参照しているConfigMap/Secretが存在しない
  • キー名のスペルミス
  • Secretの値がBase64エンコードされていない
  • 名前空間が異なる

ConfigMap/Secret の確認コマンド

# ConfigMapの一覧確認
kubectl get configmap -n namespace-name

# ConfigMapの内容確認
kubectl describe configmap app-config -n namespace-name

# Secretの一覧確認
kubectl get secret -n namespace-name

# Secretの内容確認(値はBase64エンコードされて表示される)
kubectl get secret app-secret -o yaml -n namespace-name

# Secretの値をデコードして確認
kubectl get secret app-secret -o jsonpath='{.data.DATABASE_URL}' | base64 --decode

PodのEnvから設定値が正しく渡されているか確認

# Podが起動中(Running)の瞬間に環境変数を確認
kubectl exec my-app-pod -- env

# デバッグ用に一時的にsleepするコンテナでオーバーライド
kubectl run debug-pod --image=my-app:1.0.0 --command -- sleep 3600 -n namespace-name
kubectl exec -it debug-pod -- /bin/sh
# コンテナ内で環境変数や設定ファイルを確認

存在しないConfigMapを参照している場合の対処

# ConfigMapが存在しない場合のエラー例(kubectl describe より)
# Warning  Failed  kubelet  Error: configmap "app-config" not found

# ConfigMapを作成する
kubectl create configmap app-config \
  --from-literal=DATABASE_HOST=db.example.com \
  --from-literal=APP_ENV=production \
  -n namespace-name

# または YAMLファイルから適用
kubectl apply -f configmap.yaml -n namespace-name

原因4: コンテナイメージタグの問題

ImagePullBackOff と CrashLoopBackOff の違い

イメージ自体が取得できない場合は ImagePullBackOff、イメージ取得後に起動に失敗する場合は CrashLoopBackOff になります。

latest タグの問題

:latest タグは常に最新のイメージを指しますが、意図しないバージョンのイメージがデプロイされることがあります。

# NG: latestタグは本番環境に不向き
image: my-app:latest

# OK: 特定のバージョンタグを使用
image: my-app:1.2.3

# OK: イメージのSHA256ダイジェストで固定
image: my-app@sha256:abc123...

imagePullPolicy の設定

containers:
- name: my-app
  image: my-app:1.0.0
  # Always: 毎回レジストリから取得(latestタグの場合はデフォルト)
  # Never: ローカルキャッシュのみ使用
  # IfNotPresent: ローカルにない場合のみ取得(バージョンタグの場合はデフォルト)
  imagePullPolicy: IfNotPresent

プライベートレジストリの認証問題

# レジストリ認証のSecretを作成
kubectl create secret docker-registry regcred \
  --docker-server=registry.example.com \
  --docker-username=user \
  --docker-password=password \
  --docker-email=user@example.com \
  -n namespace-name

# Deploymentに imagePullSecrets を追加
spec:
  template:
    spec:
      imagePullSecrets:
      - name: regcred
      containers:
      - name: my-app
        image: registry.example.com/my-app:1.0.0

原因5: 依存サービスの起動順序問題

データベース接続エラーによるCrashLoopBackOff

アプリがデータベースに接続を試み、DBが起動していない(またはReadyでない)場合に接続エラーで終了することがあります。

Init Containers を使った起動順序制御

spec:
  # Init Containerはメインコンテナ起動前に完了する必要がある
  initContainers:
  - name: wait-for-db
    image: busybox:1.35
    # DBが応答するまでループしてチェック
    command: ['sh', '-c',
      'until nc -z db-service 5432; do echo waiting for database; sleep 2; done']

  containers:
  - name: my-app
    image: my-app:1.0.0

アプリ側での接続リトライ実装

Kubernetesのベストプラクティスとして、アプリ自体が接続リトライロジックを実装することが推奨されています。Init Containerに依存するよりも、アプリが接続失敗を適切にハンドリングしてリトライする設計が理想的です。

よく使うデバッグコマンド集

# Podの詳細情報(Events含む)
kubectl describe pod  -n 

# 前回のクラッシュログ
kubectl logs  --previous -n 

# リアルタイムログ
kubectl logs -f  -n 

# Deploymentのロールアウト状態
kubectl rollout status deployment/my-app -n 

# Deploymentの変更履歴
kubectl rollout history deployment/my-app -n 

# 1つ前のバージョンにロールバック
kubectl rollout undo deployment/my-app -n 

# 特定バージョンにロールバック
kubectl rollout undo deployment/my-app --to-revision=2 -n 

# Podの環境変数確認(コンテナ内で実行)
kubectl exec  -- env -n 

# 起動に失敗するPodをデバッグ用コマンドでオーバーライド
kubectl debug pod/ -it --copy-to=debug-pod --container=my-app -- /bin/sh -n 

# Nodeのリソース使用状況確認
kubectl top nodes
kubectl top pods -n 

Deployment設定のデバッグフロー

確認ステップ コマンド 確認ポイント
1. Pod状態確認 kubectl get pods RESTARTS数、STATUS
2. ログ確認 kubectl logs --previous エラーメッセージ
3. イベント確認 kubectl describe pod OOMKill、Probe失敗
4. リソース確認 kubectl top pods memory/CPU使用量
5. ConfigMap/Secret確認 kubectl get configmap,secret 存在確認、キー名
6. ロールバック kubectl rollout undo 直前のバージョンで動作確認
🛒

この記事に関連するおすすめ商品

Kubernetes完全ガイド(書籍)

約3,800円〜

Pod・Deployment・Service設計から本番運用まで体系的に解説

🛒 Amazonで探す

Docker/コンテナ技術 入門書

約2,500円〜

コンテナ化の基礎からKubernetesへの発展まで丁寧に解説

🛒 Amazonで探す

ミニPC(Kubernetesクラスター自作用)

約25,000円〜

自宅Kubernetesクラスター構築に最適な省電力ミニPC

🛒 Amazonで探す

※ 価格は変動します。最新価格はリンク先でご確認ください

よくある質問(FAQ)

Q1. CrashLoopBackOffのPodに kubectl exec で入って調査できますか?

コンテナがクラッシュして停止状態のため、通常の kubectl exec は使えません。代わりに kubectl debug コマンドでデバッグ用コンテナをPodにサイドカーとして追加できます(Kubernetes 1.18以降)。または、Deploymentのコマンドを一時的に sleep infinity に変更してデプロイし、起動状態で調査する方法も有効です。

Q2. RESTARTSが増え続けているがエラーログが空の場合はどうすれば良いですか?

アプリが起動直後にシグナルを受け取って即終了している可能性があります。kubectl describe pod の Events で exit code を確認し、137(OOMKill)や143(SIGTERM)であれば、それぞれリソース増量やLiveness Probe設定を見直してください。

Q3. 本番環境でCrashLoopBackOffが発生した場合、どうやって早急に復旧しますか?

最初は kubectl rollout undo deployment/app-name で直前の安定バージョンにロールバックしてサービスを復旧し、その後でゆっくり原因調査することを推奨します。調査より復旧を優先するのが鉄則です。

Q4. HelmチャートをアップグレードしたらCrashLoopBackOffになりました

helm rollback [release-name] [revision] で直前のリビジョンに戻してください。helm history [release-name] でリビジョン一覧を確認できます。変更差分は helm diff upgrade プラグインで事前確認する運用を推奨します。

Q5. 特定のNodeでのみCrashLoopBackOffになる場合は?

Nodeの問題(ディスク不足、カーネルバージョンの差異、Nodeのリソース逼迫)が疑われます。kubectl describe node [node-name] でNodeの状態を確認し、問題のあるNodeを kubectl cordon [node-name] でスケジューリング対象から除外して調査してください。

Q6. CrashLoopBackOff状態のPodが自動的に回復することはありますか?

クラッシュの原因が一時的なもの(依存サービスの一時的な停止、ネットワークの瞬断)であれば、バックオフ待機後の再起動で自然に回復することがあります。ただし設定やコードの問題が原因の場合は手動修正が必要です。

Q7. Horizontal Pod Autoscaler(HPA)とCrashLoopBackOffの関係は?

CrashLoopBackOff状態のPodはReady状態にならないため、HPAのスケールアップ対象にはなりません。HPAがレプリカ数を増やしても全Podが同じ理由でCrashLoopBackOffになることが多く、まず根本原因の解消を優先してください。

まとめ

KubernetesのCrashLoopBackOff問題は、適切なデバッグ手順を踏むことで確実に原因を特定し解決できます。対処の優先順位をまとめます。

  1. ログ確認(最優先): kubectl logs --previous でクラッシュ時のログを確認
  2. イベント確認: kubectl describe pod でOOMKill、Probe失敗、ConfigMap不存在などを確認
  3. exit code から原因推定: 137=OOMKill、143=SIGTERM、1=アプリエラー
  4. リソース調整: memory limitを実際の使用量に基づいて適切に設定
  5. Probe設定見直し: initialDelaySecondsを増やし、Startup Probeを活用
  6. ConfigMap/Secret確認: 参照しているリソースが存在し、キー名が正しいか確認
  7. ロールバック: 本番障害は調査前にまずロールバックで復旧

体系的なデバッグ手順を確立することで、次回以降のCrashLoopBackOff発生時も素早く対応できます。定期的なProbe設定のレビューとリソース使用量のモニタリングで予防的な運用を心がけてください。

Check Also

【2026年最新版】CPUがサーマルスロットリングで性能低下する原因と対処法【完全ガイド】

【2026年最新版】CPUがサ …