【完全版】Kubernetesのよくあるエラーとトラブルシューティング集:CrashLoopBackOff等の原因と対処法
こんにちは!クラウドインフラおよびSRE領域を歩んできた先輩エンジニアです。
Kubernetes(以下k8s)を触り始めたばかりのころ、画面に踊る赤文字や「CrashLoopBackOff」「ImagePullBackOff」といった謎のエラーログを見て、「何が起きているんだ…」と途方に暮れた経験はありませんか?
安心してください。誰もが最初はそこからスタートします。k8sは非常に高度なオーケストレーションツールですが、「エラーの読み方」と「デバッグの定石(型)」さえ身につけてしまえば、決して怖いものではありません。 むしろ、k8sは非常に親切で、何が起きているかのヒントを必ずどこかに残してくれています。
この記事では、k8sの基礎知識と環境構築からスタートし、現場で最も遭遇する「4大トラブル」の原因究明と対策までを徹底的に噛み砕いて解説します。これをマスターすれば、毎日の障害対応やデバッグ作業が劇的に楽になり、自信を持ってコンテナを運用できるようになりますよ!
—
0. まずは基本から:Kubernetesの役割と最速セットアップ
トラブルシューティングに入る前に、k8sが何をしているのか、そして手元で試せる実験環境(HelloWorld)をサクッと整えましょう。
Kubernetes(k8s)の役割とは?
一言で言えば「大量のコンテナ(Dockerなど)を自動で管理・指揮するオーケストラの指揮者」です。
複数台のサーバー(ノード)上で、コンテナの配置、死活監視、自動復旧(セルフヒーリング)、ロードバランシング、スケールアウトなどを自動で行ってくれます。
手元で動かす実験環境(kind のセットアップ)
ローカルで安全に実験するために、Docker上でk8sクラスタを動かせる軽量ツール「kind (Kubernetes in Docker)」を使いましょう。
インストール手順(Mac/Linux例)
kindのインストール (Homebrewを使用する場合)
brew install kind kubectl
ローカルクラスタの作成
kind create cluster –name dev-cluster
クラスタが正常に立ち上がったか確認(これがHelloWorld的な動作確認です)
kubectl cluster-info –context kind-dev-cluster
HelloWorld Podのデプロイ
動作確認のために、簡単なWebサーバー(Nginx)を動かしてみましょう。
nginx-hello.yaml
apiVersion: v1
kind: Pod
metadata:
name: hello-nginx
labels:
app: hello
spec:
containers:
- name: nginx
image: nginx:latest # 使用するコンテナ画像
ports:
- containerPort: 80 # コンテナが解放するポート番号
これを適用(反映)します。
kubectl apply -f nginx-hello.yaml
状態確認(STATUSが Running になれば成功です!)
kubectl get pods
さあ、これであなたの手元に実験用のk8s環境が整いました。ここからが本題です!
—
1. CrashLoopBackOffエラーの原因究明と対策
最も頻繁に遭遇し、初心者をもっとも悩ませるのが `CrashLoopBackOff` です。
これはどういう状態?
コンテナが「起動した直後に異常終了(Crash)し、k8sが再起動を試みるが(Loop)、何度も失敗するため再起動の間隔を徐々に広げている(BackOff)」状態です。k8sのセルフヒーリング機能が裏目に出ているように見える現象ですね。
よくある原因
1. 設定値・環境変数の不足(DBの接続情報やAPIキーがない)
2. 起動コマンド・Entrypointのミス(ファイルパスが存在しない、文法エラー)
3. アプリケーションの初期化失敗(DBに接続できずにAppがクラッシュ)
4. メモリ不足(OOMKilled)
プロのデバッグ手順と対策
ステップ1:ログを見る(最優先)
まずはアプリケーションが何と言って死んだのか、ログを聞きに行きましょう。
コンテナの標準出力ログを確認
kubectl logs hello-nginx
【超重要】すでに再起動してしまっている場合、1つ前の死んだコンテナのログを見る
kubectl logs hello-nginx –previous
※この `–previous` フラグを知っているだけで、デバッグ効率は10倍変わります!
ステップ2:詳細なイベントを確認する
ログが出力される前に死んでいる場合は、k8sのイベントログを確認します。
kubectl describe pod hello-nginx
一番下の `Events:` セクションや、`Containers.State` の `Exit Code` を確認してください。
- Exit Code 137: メモリ溢れ(OOMKilled)による強制終了
- Exit Code 1/127: アプリケーションのエラー、またはコマンドが見つからない
修正例:環境変数の不足で落ちていた場合
例えば、WordPressコンテナのように「環境変数(DBパスワード等)がないと即死する」仕様のアプリには、正しい環境変数を注入してあげます。
crash-fix-example.yaml
apiVersion: v1
kind: Pod
metadata:
name: wordpress-app
spec:
containers:
- name: wordpress
image: wordpress:6-php8.1-apache
env:
# 必要な環境変数を明示的に渡すことでCrashLoopBackOffを防ぐ
- name: WORDPRESS_DB_PASSWORD
value: “secure_password_123”
- name: WORDPRESS_DB_USER
value: “root”
—
2. ImagePullBackOffエラーの解決策
次に多いのが `ImagePullBackOff` や `ErrImagePull` です。
これはどういう状態?
k8sが指定されたコンテナイメージをレジストリ(Docker HubやECRなど)からダウンロード(Pull)できない状態です。
よくある原因
1. イメージ名やタグのスペルミス(例: `nginx:latst` などのタイポ)
2. プライベートレジストリへの認証失敗(Secretの設定漏れ)
3. レジストリのレートリミット(回数制限)
プロのデバッグ手順と対策
ステップ1:`describe` でイベントを見る
ImagePullエラーの理由は、`kubectl describe` を見れば100%分かります。
kubectl describe pod `Events:` セクションに以下のようなメッセージが出ていないか探します。 認証が必要なリポジトリから画像を引っ張ってくる場合、`imagePullSecrets` をマニフェストに定義します。 image-pull-fix.yaml image: registry.example.com/acme/my-app:v1.0.0 # 正しいイメージURL — Podを作ったのに STATUS が `Pending` のまま一向に動き出さないことがあります。 「Podを配置したいけれど、条件に合うノード(サーバー)が見つからず、スケジューリング(配置計算)が止まっている」状態です。コンテナ自体はまだ起動すらしていません。 1. クラスターのリソース不足(CPUやメモリの空きがない) このエラーの答えも `kubectl describe pod` にあります。 kubectl describe pod `Events:` のログに注目しましょう! 初心者がやりがちなのが、`requests`(最低限保証してほしいスペック)に巨大な値を書いてしまうことです。 pending-fix-example.yaml image: nginx ※このように `requests` を現実的なサイズに小さく調整することで、Schedulerが「このノードなら置けるぞ!」と判断できるようになります。 — 「Podは Running になっているのに、外部からアクセスできない!」「Pod同士が通信できない!」という問題です。 1. Serviceの `selector` と Podの `labels` が一致していない(超高頻度!) Serviceが正しくPodを認識しているか確認します。 Serviceに紐づいているPodのIP一覧を表示 ここで `ENDPOINTS` が ` service-pod-match.yaml image: nginx — port: 80 コンテナ内のアプリが `LISTEN` しているIPアドレスを確認してください。 「クラスター内部から名前解決やHTTPリクエストができるか」を確かめるため、調査用の臨時Podを立ち上げて直接コマンドを叩くのがエンジニアの常套手段です。 調査用の臨時コンテナ(curlimages/curl)を起動し、シェルに入る — 調査用コンテナの中での操作 — 2. Service経由でアクセスできるか? 確認が終わったら exit で抜ければPodは自動削除されます (–rm) — 今回解説したトラブルシュートの基本フローを整理しましょう。 【トラブル解決の4ステップ】 Kubernetesのトラブルシューティングは、闇雲に試すのではなく「k8sの制御面(コントロールプレーン)の問題か?」「コンテナのアプリの問題か?」「ネットワークの問題か?」を順番に切り分けていくのが最大のコツです。 この「型」さえ知っていれば、どんな複雑なエラーに遭遇しても落ち着いて対処できますよ。 最初は誰でも戸惑うものです。手元の `kind` クラスタでわざとエラーを起こしてみて、今回紹介したコマンドを叩いて遊んでみてください。エラーメッセージが「相棒からのヒント」に見えてきたら、あなたはもう立派なKubernetesエンジニアです! 毎日のインフラ運用が、少しでも楽しく楽になりますように!応援しています!
> `Error: ImagePullBackOff`
> `Failed to pull image “my-app:1.0”: rpc error: code = NotFound` → イメージ名ミス
> `pull access denied for …` → 認証失敗対策:プライベートレジストリの認証情報を設定する
apiVersion: v1
kind: Pod
metadata:
name: private-app
spec:
containers:
# プライベート認証情報を指定
imagePullSecrets:
3. Pending状態から動かないPodのデバッグ手法
これはどういう状態?
よくある原因
2. Requests(要求リソース)の設定が大きすぎる
3. NodeSelectorやAffinityの条件が厳しすぎる
4. PVC(永続ボリューム)がバインドされていないプロのデバッグ手順と対策
ステップ1:Schedulerのメッセージを読む
> `0/3 nodes are available: 3 Insufficient memory.`
> (3台あるノードのどれもメモリが足りません)対策:リソースのリクエスト(Requests)を適正化する
apiVersion: v1
kind: Pod
metadata:
name: resource-friendly-pod
spec:
containers:
resources:
requests:
# 巨大すぎる値(例: cpu: “32”)を指定するとPendingになる
cpu: “100m” # 0.1コア(現実的な値に設定)
memory: “128Mi” # 128メビバイト
limits:
cpu: “500m” # 最大0.5コアまで許可
memory: “512Mi” # 最大512MBまで許可4. ネットワーク疎通トラブルの切り分け手順
ネットワークトラブルの4大原因
2. アプリケーションが `127.0.0.1`(localhost)でListenしている
3. NetworkPolicy(ファイアウォールルール)で遮断されている
4. DNSの解決失敗プロの切り分け4ステップ(黄金フロー)
ステップ1:Serviceのターゲットを確認する(最重要)
kubectl get endpoints 【正しい設定の例】
apiVersion: v1
kind: Pod
metadata:
name: web-backend
labels:
app: my-web # ① ここのラベルと
spec:
containers:
ports:
apiVersion: v1
kind: Service
metadata:
name: web-service
spec:
selector:
app: my-web # ② ここのセレクターが完全に一致している必要がある!
ports:
targetPort: 80ステップ2:アプリのListenアドレスを確認する
アプリのコードや設定ファイルで `127.0.0.1` や `localhost` 向けにバインドされていると、Podの外部(他のPodやService)からの通信を拒否してしまいます。
必ず `0.0.0.0`(すべてのネットワークインターフェース)でListenするようにアプリ側を設定しましょう。ステップ3:デバッグ用Podを打ち込んで疎通テストを行う
kubectl run net-debug –rm -i –tty –image=curlimages/curl — sh
1. DNSの名前解決ができるか?
nslookup web-service
curl http://web-service:80まとめ:トラブルシューティングをマスターしたあなたへ
1. kubectl get pods -> Podの全体状態(STATUS)を把握する
2. kubectl describe pod
3. kubectl logs
4. kubectl run net-debug … -> ネットワーク疎通・DNSを疑う