【実務・中級編】【完全版】Kubernetesのよくあるエラーとトラブルシューティング集:CrashLoopBackOff等の原因と対処法 – インフラ構成管理(IaC)活用バイブル

【完全版】Kubernetesのよくあるエラーとトラブルシューティング集:CrashLoopBackOff等の原因と対処法

テックリードの私たちが日々運用するKubernetesクラスターにおいて、Podの障害は避けて通れない。「なぜ動かないのか?」という問いに対して、勘や経験に頼ったデバッグから脱却し、構造化されたアプローチで迅速に原因を特定・排除することこそが、チーム全体の開発スピードを極限まで高めるカギとなる。

本稿では、実務で遭遇頻度が極めて高い4つの深刻な障害シナリオを取り上げ、その根本原因と破壊的な解決策を、プロの実践テクニックとともに徹底解説する。

—

0. 本番前夜に仕込むべき「神のツールチェイン」と環境設定

トラブルシューティングの速度は、使用しているツールとキーバインドに支配される。まずは、現場の戦闘力を底上げする環境を整えよう。

必須プラグイン(Krew経由)

  • `kubectl-neat`: 可読性を地の底まで落とす「自動生成フィールド(`managedFields`や`uid`など)」をパージし、人間が読めるYAMLに整形する。
  • `kubectl-stern`: 複数レプリカ(Deploymentなど)のログを、色分けしてリアルタイムにテイルする。これなしでマイクロサービスのログは追えない。

開発スピードを倍化するシェル設定(Zsh/Bash)

~/.zshrc
alias k=’kubectl’
source <(kubectl completion zsh) complete -o default -F __start_kubectl k 瞬時にコンテナへ飛び、bash/shを自動判定してアタッチする神エイリアス alias ksh='f() { local pod=$1; shift; kubectl exec -it $pod -- sh -c "command -v bash >/dev/null 2>&1 && exec bash || exec sh”; }; f’

—

1. CrashLoopBackOffエラーの原因究明と対策

最も頻出する `CrashLoopBackOff` は、「コンテナが起動した直後に何らかの理由で終了し、Kubeletが再起動ループに入っている」状態を示す。Kubeletは指数関数的バックオフ(1秒、2秒、4秒…最大300秒)で再起動を試みるため、調査の猶予が短い。

根本原因の特定フロー

1. 直前まで動いていたコンテナの終了コードを確認する。
2. アプリケーション層のエクスプロイト、環境変数(ConfigMap/Secret)の欠落、あるいはLiveness Probeの早すぎる失敗を疑う。

実践:デバッグ用マニフェスト(ベストプラクティス構成)

apiVersion: apps/v1
kind: Deployment
metadata:
name: api-service
namespace: production
labels:
app.kubernetes.io/name: api-service
spec:
replicas: 2
selector:
matchLabels:
app.kubernetes.io/name: api-service
template:
metadata:
labels:
app.kubernetes.io/name: api-service
spec:
containers:

  • name: app

image: 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/api:v1.2.3
imagePullPolicy: IfNotPresent
envFrom:

  • secretRef:

name: db-credentials # ここが存在しないとCrashLoopBackOffの原因になる
ports:

  • containerPort: 8080

name: http
# 【重要】Liveness Probeはアプリケーションが完全にトラフィックを受け入れられる状態になってから発動させる
livenessProbe:
httpGet:
path: /healthz
port: http
initialDelaySeconds: 30 # アプリの起動時間を十分に考慮する
periodSeconds: 10
failureThreshold: 3
resources:
limits:
cpu: “500m”
memory: “512Mi”
requests:
cpu: “100m”
memory: “256Mi”

> プロの技: 終了コードが `137` の場合、OOMKilled(メモリ不足)の可能性が極めて高い。`kubectl describe pod ` で `OOMKilled: true` および `Exit Code: 137` を即座に確認せよ。

—

2. ImagePullBackOffエラーの解決策

コンテナイメージの取得に失敗している状態を示す。このエラーの厄介な点は、インフラストラクチャ層(認証情報、ネットワーク、DNS)の不備と、単なるタイポ(タグの間違い)が混在していることだ。

3大原因とスマートな切り分け

1. イメージ名・タグのタイポ: `kubectl describe pod` の `Events` 欄を直視せよ。
2. プライベートレジストリの認証エラー: ECR, GCR, DockerHub等への認証情報(`ImagePullSecret`)が漏れている。
3. プロキシ・Egress制限: クラウド環境のNAT Gatewayやセキュリティグループがレジストリのエンドポイントをブロックしている。

チームで共有すべき `ImagePullSecret` の自動アタッチ設計

手動でPodごとにSecretを設定するのはアンチパターンである。ServiceAccountに紐付けることで、すべてのPodに自動継承させる。

apiVersion: v1
kind: ServiceAccount
metadata:
name: ecr-sa
namespace: production
imagePullSecrets:

  • name: regcred # あらかじめ作成しておいたDocker Registry用のSecret

—
apiVersion: apps/v1
kind: Deployment
metadata:
name: secured-app
namespace: production
spec:
template:
spec:
serviceAccountName: ecr-sa # ここで紐付けることで個別設定を排除する
containers:

  • name: app

image: private-registry.io/org/app:latest

—

3. Pending状態から動かないPodのデバッグ手法

Podがいつまで経っても `Pending` のままスケジューリングされない場合、Kubernetesのスケジューラ(`kube-scheduler`)が「リクエストを満たすノードを見つけられない」と悲鳴を上げている。

チェックすべき項目とコマンド

1. リソース不足(CPU / Memory): ノードのキャパシティを超えている。
2. Node Selector / Taints & Tolerations: 意図しない制約によって配置可能なノードが存在しない。
3. PersistentVolumeClaim (PVC) のバインド待ち: 動的プロビジョニングが失敗している。

決定打となる診断コマンド

为什么にPendingなのかの根本理由は必ずEventsに記されている
kubectl describe pod | grep -A 10 Events:

もし `Insufficient cpu` や `Insufficient memory` が原因であれば、Horizontal Pod Autoscaler (HPA) の設定値や、ノードグループのオートスケーリング(Cluster Autoscaler)の閾値設計に欠陥がある。直ちに見直すべきだ。

—

4. ネットワーク疎通トラブルの切り分け手順

Kubernetesのネットワーク(Container Network Interface: CNI)は抽象化されているが故に、トラブル時のレイヤーが深く、切り分けが難解になりやすい。

ネットワークトラブルの4階層アプローチ

[Client] —> Service —> Endpoints —> Pod (Container Port)

このパイプラインのどこでパケットが消失しているかを、上流から順にロジカルに突き止める。

ステップ1: ServiceとEndpointsの整合性確認

Serviceが存在しても、セレクタが一致するPodが存在しなければ `Endpoints` は空(``)になる。これがネットワーク疎通不良の9割を占める。

EndpointsにIPアドレスが正しく紐づいているか確認
kubectl get endpoints

もし `` ならば、Deployment/Pod側の `labels` と Service側の `selector` の一致を疑え。

ステップ2: クラスター内からのDNS・疎通テスト(Ephemeral Containersの活用)

トラブルシューティングのために、わざわざデバッグ用コンテナをマニフェストに追加してデプロイし直す必要はない。Kubernetes 1.23以降で標準有効化された 一時コンテナ(Ephemeral Containers) を使え。

稼働中の障害Podに対して、即座にデバッグ用ネットワークツール(netshoot等)をインジェクトする
kubectl debug -it –image=nicolaka/netshoot –target=

インジェクトした一時コンテナ内から、以下のコマンドで一撃でボトルネックを暴く。

DNSの解決確認
nslookup target-service.production.svc.cluster.local

TCPレイヤーの疎通確認
nc -zv target-service 8080

—

結びにかえて:インフラストラクチャをコードと対話するアートへ

Kubernetesのエラーは、システムからの「意図しない不整合のシグナル」に他ならない。エラーメッセージに怯えるのではなく、Kubelet、Scheduler、CNIの挙動という「背後の物理法則」を理解していれば、恐るるに足りない。

ここに示した設定と診断手法をチームの共通言語とし、偶発的な障害に怯えない、堅牢でモダンなKubernetes運用体制を構築してほしい。

タイトルとURLをコピーしました