Kubernetes の CrashLoopBackOff エラー:原因と解決策

冒頭まとめ CrashLoopBackOff は、コンテナが落ちた原因の名前ではありません。落ちたコンテナを再び起動するまで、待たせている状態の名前です。この文字列自体は、kubelet のソースに定義された固定の値で、それ以上の意味を持ちません。原因は別の場所、直前に終了したときの情報に残っています。 待ち時間の決まり方は、ソースに明確に書かれています。初回は10秒で、以降は倍々に増え、上限は300秒です。起点になるのは、直前に終了したコンテナの終了時刻です。 もう1つ、知っておくと症状の見え方が説明できる値があります。待ち時間の記録は、600秒つまり10分のあいだ更新されなければ期限切れになります。言い換えると、10分以上持ちこたえたコンテナは、次に落ちたとき10秒から数え直します。逆に、9分ごとに落ち続けるコンテナは記録が消えないため、待ち時間が上限に張り付いたままになります。「同じように落ちているのに、片方は復旧が速く、片方は遅い」という現象は、たいていこの境目です。 したがって、見るべきものは3つに絞れます。直前の終了理由、終了コード、そして直前の出力です。この3つが揃えば、CrashLoopBackOff という表示は読み終わったも同然です。 エラーの概要 一覧では、状態の欄にこの文字列が出ます。再起動の回数が増え続けるのが特徴です。 NAME READY STATUS RESTARTS AGE my-app-7d9f8b6c-xk2p9 0/1 CrashLoopBackOff 6 (2m11s ago) 14m 詳細を見ると、待ち時間を含む記録が出ます。文言はソースに定義されているとおりの形です。 Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning BackOff 2m11s (x14 over 12m) kubelet Back-off restarting failed container my-app in pod my-app-7d9f8b6c-xk2p9 Last State: Terminated Reason: Error Exit Code: 1 Started: Wed, 29 Jul 2026 10:20:31 +0900 Finished: Wed, 29 Jul 2026 10:20:33 +0900 読むべきはこの下半分です。終了の理由と終了コード、そして開始から終了までの秒数です。上の例では2秒で落ちているので、起動処理のどこかで失敗していると分かります。 ...

2026年7月29日 · ErrorLog

Kubernetes の ImagePullBackOff エラー:原因と解決策

冒頭まとめ ImagePullBackOff は、イメージの取得に失敗した理由の名前ではありません。失敗したあと、次に取得を試みるまで待たせている状態の名前です。理由は別の名前で表されます。 kubelet のソースには、取得に関する状態名が5つ定義されています。待たせている状態、一般的な取得の失敗、イメージを調べられない場合、手元に無いのに取得しない方針になっている場合、そして名前を解釈できない場合です。この5つのどれが出ているかで、原因の範囲がほぼ決まります。最初に見るべきはここです。 待ち時間の決まり方は、コンテナの再起動と同じ形です。初回は10秒で倍々に増え、上限は300秒です。値は同じですが、記録は別に管理されています。 そして、この状態には決定的な性質が1つあります。諦めません。何度失敗しても、対象は待機中の扱いのまま残り続け、割り当てられた資源を確保し続けます。失敗を重ねたら異常として扱う、という仕組みが標準では用意されていません。人が気付いて手を入れるまで、そのままです。 最後に、取得の方針の既定値も押さえておきます。ソースの規則は単純で、タグが latest なら毎回取得し、それ以外なら手元にあるものを使います。タグを書かない場合はタグを latest とみなす処理が入るため、結果として毎回取得になります。一方、ダイジェストで指定した場合はタグが空のままなので、手元にあるものを使う方針になります。 エラーの概要 一覧では待機中の理由として表示されます。再起動の回数は増えません。コンテナが一度も起動していないためです。 NAME READY STATUS RESTARTS AGE my-app-6c4d8f9b5-2xq7w 0/1 ImagePullBackOff 0 4m12s 詳細を見ると、最初の失敗と、その後の待機が別々に記録されています。 Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Pulling 4m (x4 over 5m) kubelet Pulling image "example/my-app:1.0" Warning Failed 3m (x4 over 5m) kubelet Failed to pull image "example/my-app:1.0": ... Warning Failed 3m (x4 over 5m) kubelet Error: ErrImagePull Normal BackOff 30s (x12 over 4m) kubelet Back-off pulling image "example/my-app:1.0" Warning Failed 30s (x12 over 4m) kubelet Error: ImagePullBackOff 読むべきは、上から2行目の末尾です。ここに、取得を担う仕組みが返した文言がそのまま入ります。名前が見つからない、資格が無い、回数の上限に達した、といった内容が、その置き場の言葉で書かれています。ImagePullBackOff という表示だけを見ていても、この文言には辿り着きません。 ...

2026年7月29日 · ErrorLog

Kubernetes の OOMKilled エラー:原因と解決策

冒頭まとめ OOMKilled は、コンテナがメモリの都合で外から止められたことを示します。ただし、止めた理由は2通りあり、対処が正反対になります。 1つ目は、そのコンテナ自身に設定された上限を超えた場合です。この場合、超えたコンテナだけが止められます。機器に空きがあっても関係ありません。 2つ目は、機器全体のメモリが尽きた場合です。この場合、自分の上限を超えていないコンテナでも止められることがあります。誰が選ばれるかは、あらかじめ設定された優先度で決まります。 そして、この優先度を決めているのは上限ではありません。要求量です。kubelet のソースには計算式が定義されており、要求量を保証する種類なら最も殺されにくい値、上限も要求量も書かない種類なら最も殺されやすい値、その中間の種類なら「1000 から、要求量を機器のメモリ量で割った比率に1000を掛けた値を引いた数」になります。注釈には、要求量を超えて使うコンテナは実質的に最も殺されやすい値になり、優先的な対象になる、と書かれています。 ここが実務上いちばん重要な点です。「上限を上げる」という対処は、1つ目にしか効きません。2つ目に対しては、要求量を正しく設定することが効きます。上限だけを大きくして要求量を書かないままにすると、2つ目の状況ではむしろ殺されやすいままです。 なお、kubelet が能動的に対象を退去させる仕組みは別物で、状態名も違います。こちらの既定のしきい値は、空きが100メガバイトを下回った時点です。 エラーの概要 一覧では、繰り返せば待機中の表示になります。判断の材料は詳細のほうにあります。 Last State: Terminated Reason: OOMKilled Exit Code: 137 Started: Wed, 29 Jul 2026 11:02:14 +0900 Finished: Wed, 29 Jul 2026 11:19:48 +0900 終了コードの 137 は、128に9を足した値です。9番は強制終了の信号なので、ソフトウェアが自分で終了したのではなく、外から止められたことを示します。理由の欄が OOMKilled になっていれば、止めた理由はメモリです。 開始から終了までの時間も重要です。数分から数時間かけて止まっている場合、使用量が徐々に増えている可能性があります。起動直後に止まる場合は、初期化の時点で上限を超えています。 種類の判定は、要求量と上限の書き方で決まります。 kubectl get pod <ポッド名> -o jsonpath='{.status.qosClass}' 要求量と上限が等しければ最も保護される種類、どちらも書いていなければ最も保護されない種類、その中間はそれ以外です。 まず最初に:自分の上限か、機器の枯渇か 第一に、止められたコンテナの使用量が、自分の上限に達していたかを確認します。達していれば1つ目です。 第二に、同じ時刻に、同じ機器の上で他のコンテナも止まっていないかを確認します。複数が同時に止まっていれば、2つ目の可能性が高くなります。 第三に、機器全体のメモリの状況を確認します。空きが逼迫していた形跡があれば2つ目です。 この区別を付けずに上限だけを上げると、1つ目なら直り、2つ目なら悪化します。上限を上げたコンテナがより多くを使うようになり、機器全体の逼迫が早まるためです。 よくある原因と解決手順 原因1:自分の上限を超えている 最も分かりやすい形です。設定した上限に対して、実際の使用量が足りていません。 まず、上限と実測を並べます。 kubectl get pod <ポッド名> \ -o jsonpath='{range .spec.containers[*]}{.name}{" req="}{.resources.requests.memory}{" lim="}{.resources.limits.memory}{"\n"}{end}' kubectl top pod <ポッド名> --containers Before(上限が実態に対して低い): ...

2026年7月29日 · ErrorLog

Kubernetes の Pending:原因と解決策

冒頭まとめ Pending は、コンテナの状態を表す名前ではありません。対象全体がどの段階にあるかを表す名前です。公式の定義には、対象は受け付けられたがコンテナの1つ以上がまだ起動していない状態であり、これには機器に割り当てられる前の時間と、イメージを取得している時間の両方が含まれる、と書かれています。 この一文が示すとおり、Pending は性質の違う2つの状況を1語でまとめています。置き場所がまだ決まっていない状況と、置き場所は決まったが起動の準備が終わっていない状況です。前者は配置を担う仕組みの問題で、後者は機器の上の仕組みの問題です。原因も対処もまったく違います。 分岐は1点で決まります。配置先が決まっているかどうかです。決まっていなければ配置の問題、決まっていれば起動準備の問題です。この確認を最初に行えば、調べる範囲が半分になります。 配置の問題であれば、記録に理由が残ります。文言は「0/N nodes are available」で始まり、そのあとに理由が続きます。この形式はソースに定義されていて、理由ごとに何台の機器が該当したかという数が付きます。 読み方に注意点が1つあります。この数は理由ごとの機器の台数で、1台の機器が複数の理由に数えられることがあります。したがって、並んでいる数字を足しても総数に一致するとは限りません。合計が合わないのは異常ではありません。 エラーの概要 一覧では、準備できているコンテナの数が0のまま止まります。 NAME READY STATUS RESTARTS AGE my-app-5f8c7d9b4-nq3vt 0/1 Pending 0 6m41s 配置が済んでいない場合、記録に理由が残ります。 Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedScheduling 6m (x5 over 6m) default-scheduler 0/5 nodes are available: 3 Insufficient memory, 2 node(s) had untolerated taint {node-role.kubernetes.io/control-plane: }. この例では、5台のうち3台がメモリの空き不足、2台が許容していない印によって除外されています。理由が2つ並んでいるので、対処も2通り考えられます。空きを増やすか、印を許容する設定を加えるかです。 配置が済んでいる場合は、この記録が出ません。代わりに、コンテナごとの待機の理由が入ります。この場合、Pending という表示のままイメージの取得や保管領域の準備が進んでいます。 まず最初に:配置先が決まっているかを見る 第一に、配置先が入っているかを確認します。 kubectl get pod <ポッド名> -o jsonpath='{.spec.nodeName}{"\n"}' 何も出なければ、まだ置き場所が決まっていません。配置の問題として調べます。機器の名前が出れば、置き場所は決まっています。起動準備の問題として調べます。 ...

2026年7月29日 · ErrorLog

Kubernetes の 504 エラー:原因と解決策

冒頭まとめ Kubernetes で 504 Gateway Timeout に出会う場面は、大きく2つに分かれます。API サーバーが自分の締め切りに達して要求を打ち切った場合と、Ingress などの中継役が背後の応答を待ちきれずに返した場合です。前者はクラスタの操作そのものが止まり、後者は利用者向けの通信が止まります。原因も対処もまったく別です。 API サーバーが打ち切った場合、文言は一意に定まっています。ソースを読むと、時間切れの応答は Timeout: request did not complete within the allotted timeout という文言で、区分は Timeout、状態コードは 504 として組み立てられます。kubectl からは Error from server (Timeout): の形で表示されます。この文言が出ていれば、打ち切ったのは API サーバー自身です。 締め切りの既定値は60秒です。API サーバーの起動時の指定として定義されており、変更にはクラスタ側の設定変更が要ります。 ここで重要なのが、クライアント側の指定との関係です。要求に待ち時間を付けて送ることはできますが、ソースの処理を読むと、指定された値が0より大きく、かつサーバー側の上限より小さい場合にだけ採用される、と書かれています。つまり、クライアント側で長い値を指定しても、サーバー側の締め切りは伸びません。短くすることはできても、伸ばすことはできない、という一方通行です。「待ち時間を伸ばす」という定番の対処が効かない理由がここにあります。 なお、監視や実行、ログの追従といった長時間動き続ける種類の要求は、この打ち切りの対象から外れます。ソースでも、該当する要求はそのまま通す分岐になっています。 エラーの概要 kubectl からは次の形で見えます。 Error from server (Timeout): error when creating "example.yaml": Timeout: request did not complete within the allotted timeout 応答そのものは次の構造です。区分と状態コードが対応しています。 { "kind": "Status", "status": "Failure", "message": "Timeout: request did not complete within the allotted timeout", "reason": "Timeout", "code": 504 } API サーバー側の記録には、要求ごとの処理時間と結果が残ります。時間切れになった要求は、要した時間とともに記録されます。 "HTTP" verb="GET" URI="/api/v1/namespaces/example/endpoints/sample?timeout=10s" latency="15.79s" resp=504 この例では、要求に10秒の指定が付いているにもかかわらず、15.79秒かかっています。指定した値と実際の処理時間は一致しません。 ...

2026年7月28日 · ErrorLog

Kubernetes の 500 エラー:原因と解決策

エラーの概要 Kubernetes環境で500エラーが発生した場合、APIサーバーまたはコントロールプレーンコンポーネントで予期しない内部エラーが生じています。このエラーはクラスタ全体の管理機能に影響を与える可能性があり、迅速な対応が必要です。500エラーが返される場合、リソースの作成・更新・削除やクラスタ情報の取得が失敗することになります。 実際のエラーメッセージ例 $ kubectl apply -f deployment.yaml Error from server (InternalError): error when creating "deployment.yaml": Internal error occurred: <unknown> { "apiVersion": "v1", "kind": "Status", "metadata": {}, "status": "Failure", "message": "Internal error occurred: etcd server failed", "reason": "InternalError", "code": 500 } よくある原因と解決手順 1. etcdデータベースの障害 なぜ発生するか:etcdはKubernetesクラスタの状態を保持する分散キー・バリューストアです。etcdが応答しない、ディスク満杯、または不整合が発生するとAPIサーバーは500エラーを返します。 Before(エラーが起きる状態): $ kubectl get nodes Error from server (InternalError): Internal error occurred: etcd server failed After(解決手順): # 1. etcdのヘルスチェック実行 kubectl exec -it etcd-<master-node-name> -n kube-system -- etcdctl endpoint health # 2. etcdメンバーの状態確認 kubectl exec -it etcd-<master-node-name> -n kube-system -- etcdctl member list # 3. etcdポッドを再起動(自動復旧を待つ) kubectl delete pod etcd-<master-node-name> -n kube-system # 4. APIサーバーのログを確認 kubectl logs -n kube-system -l component=kube-apiserver --tail=100 2. APIサーバーのメモリ不足またはクラッシュ なぜ発生するか:APIサーバーはクラスタのすべてのリソース定義をメモリに保持しています。大規模クラスタやメモリ制限が厳しい環境では、メモリ不足(OOM)によりプロセスがクラッシュし500エラーが多発します。 ...

2026年5月27日 · ErrorLog

Kubernetes の 503 エラー:原因と解決策

エラーの概要 Kubernetes環境で503エラーが発生するのは、クライアントからのリクエストに対応できるPodが存在しない、または全てのPodが利用不可状態にあることを示しています。Service経由でアクセスした際、バックエンドのPodがすべてダウンしていたり、起動途中だったり、リソース不足で応答できない状態で表示されるHTTPステータスコードです。本エラーは一時的な問題である場合が多く、Podの自動復旧により解決することもありますが、根本原因の特定と対処が必要です。 実際のエラーメッセージ例 HTTP/1.1 503 Service Unavailable Content-Type: text/html; charset=utf-8 Connection: close <html> <body><h1>503 Service Unavailable</h1> No servers are available to handle this request. </body></html> { "kind": "Status", "apiVersion": "v1", "metadata": {}, "status": "Failure", "message": "no endpoints available for service", "code": 503 } よくある原因と解決手順 原因1: Podがすべてダウン状態である DeploymentやStatefulSetで定義したPodが何らかの理由でクラッシュしており、バックエンドサーバーが完全に停止している状態です。CrashLoopBackOff状態やExit Code 1などの異常終了が続いている場合に発生します(Kubernetes の CrashLoopBackOff の記事)。 Before(エラーが起きるコード): apiVersion: apps/v1 kind: Deployment metadata: name: web-app spec: replicas: 3 selector: matchLabels: app: web template: metadata: labels: app: web spec: containers: - name: app image: myapp:latest env: - name: DATABASE_URL value: "invalid-connection-string" After(修正後): ...

2026年5月27日 · ErrorLog

Kubernetes の 404 エラー:原因と解決策

エラーの概要 Kubernetesの404エラーは、APIサーバーが指定したリソース(Pod・Service・Deploymentなど)やアクセスしようとしたエンドポイントが存在しないことを示します。kubectlコマンド実行時やKubernetes APIへのHTTPリクエスト時に発生し、リソースの削除後のアクセスや存在しないNamespaceへのクエリで特に見られます。このエラーはデータ消失を意味しませんが、リソースが実際に動作していない状態を示しているため、早期の対応が必要です。 実際のエラーメッセージ例 $ kubectl get pod my-app -n production Error from server (NotFound): pods "my-app" not found { "kind": "Status", "apiVersion": "v1", "metadata": {}, "status": "Failure", "message": "pods \"web-server\" not found", "reason": "NotFound", "details": { "name": "web-server", "kind": "pods" }, "code": 404 } よくある原因と解決手順 原因1:リソースが削除されている なぜ発生するか: Podやサービスが意図せず削除されたり、別のプロセスによって削除された後もアクセスしようとした場合に発生します。Deployment経由でPodを管理している場合、Podは自動的に再作成されることもあります。 Before(エラーが起きるコード): kubectl delete pod my-app kubectl get pod my-app # Error: pods "my-app" not found After(修正後): # リソースが本来管理されるべきDeploymentから再作成させる kubectl get deployment kubectl describe deployment my-app-deployment # または新しいPodを作成 kubectl run my-app --image=my-image:latest 原因2:Namespaceの指定ミス なぜ発生するか: リソースがあるNamespaceと異なるNamespaceを指定した場合、APIサーバーはそのNamespace内のリソースを探すため404となります。デフォルトのdefault Namespaceではなく、productionやstagingなどのNamespaceにリソースが存在することを見落とすことが多くあります。 ...

2026年5月26日 · ErrorLog

Kubernetes の 400 エラー:原因と解決策

エラーの概要 Kubernetes APIサーバーへのリクエストが不正な形式や内容であることを示すHTTP 400エラーです。マニフェストファイルの構文エラー、API仕様に違反するフィールド値、または不完全なリクエストボディが原因となります。このエラーはクラスタとの通信に成功した後、サーバー側でリクエストの妥当性検証に失敗したときに発生する重要な診断シグナルです。 実際のエラーメッセージ例 { "kind": "Status", "apiVersion": "v1", "metadata": {}, "status": "Failure", "message": "error validating data: ValidationError(Pod.spec.containers[0].resources.limits): invalid type for io.k8s.api.core.v1.ResourceList: got \"string\", expected \"object\"", "reason": "BadRequest", "code": 400 } error: error validating "deployment.yaml": error validating data: [ValidationError(Deployment.spec.template.spec.containers[0].ports[0].containerPort): invalid type for io.k8s.api.core.v1.ContainerPort: got "string", expected "integer", ValidationError(Deployment.spec.template.spec.containers[0].image): string length must be non-empty] よくある原因と解決手順 原因1: YAML構文エラーまたはフィールド型の不一致 なぜ発生するか: Kubernetesマニフェストファイルで、数値型フィールドを文字列で指定したり、オブジェクト型フィールドにスカラー値を渡したりするときに発生します。特にポート番号やリソース制限でこの問題が頻発します。 Before(エラーが起きるコード): apiVersion: v1 kind: Pod metadata: name: nginx-pod spec: containers: - name: nginx image: nginx:latest ports: - containerPort: "8080" # 文字列型で指定 resources: limits: memory: 512Mi # オブジェクト型だが不正 cpu: "1" # 数値型だが文字列 After(修正後): apiVersion: v1 kind: Pod metadata: name: nginx-pod spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 8080 # 整数型で指定 resources: limits: memory: 512Mi cpu: "1" # CPU値は文字列でも有効 requests: memory: 256Mi cpu: "500m" 原因2: 必須フィールドの欠落 なぜ発生するか: Kubernetesリソースの必須フィールド(例:metadata.name、コンテナのimage)が定義されていない場合に発生します。APIサーバーは最小限のリソース定義すら受け付けません。 ...

2026年5月25日 · ErrorLog

Kubernetes の 401 エラー:原因と解決策

エラーの概要 Kubernetesで401エラーが発生するのは、APIサーバーへのリクエストに対して認証に失敗した状態を示します。認証トークンの有効期限切れ、認証情報の不足、または権限がないServiceAccountの使用が典型的な原因です。このエラーが出ると、kubectlコマンドの実行やPodからAPIサーバーへのアクセスが拒否されます。 実際のエラーメッセージ例 error: You must be logged in to the server (Unauthorized) { "kind": "Status", "apiVersion": "v1", "metadata": {}, "status": "Failure", "message": "Unauthorized", "reason": "Unauthorized", "code": 401 } kubectl logs pod-name -n default Error from server (Unauthorized): pods "pod-name" is forbidden: User "system:serviceaccount:default:default" cannot get resource "pods" in API group "" in the namespace "default" よくある原因と解決手順 原因1:kubeconfig設定の無効化または存在しない認証情報 kubeconfig内の証明書やトークンが無効になっている、または参照しているファイルが削除されている場合に401エラーが発生します。クラスタをセットアップした時点での認証情報が失われたり、パスが誤っていたりすることが多いです。 Before(エラーが起きるコード): # ~/.kube/config apiVersion: v1 clusters: - cluster: certificate-authority: /etc/kubernetes/pki/ca.crt # ファイルが削除済み server: https://10.0.0.1:6443 name: my-cluster contexts: - context: cluster: my-cluster user: admin-user name: my-context current-context: my-context users: - name: admin-user user: client-certificate: /home/user/.certs/client.crt # パスが誤っている client-key: /home/user/.certs/client.key After(修正後): ...

2026年5月25日 · ErrorLog