Kubernetes Pod障害トラブルシューティング:総合ガイド

この総合ガイドで、Kubernetes Podの障害がもたらす複雑さを乗り越えましょう。CrashLoopBackOff、ImagePullBackOff、リソース枯渇といった一般的な問題を診断するための構造化されたプロセスを学びます。`kubectl describe`や`kubectl logs --previous`などの重要なツールを活用して根本原因を特定し、コンテナの終了ステータスを解釈し、信頼性の高いアプリケーションの稼働時間と安定性を維持するための実践的な修正を実装する方法を詳しく解説します。

31 ビュー

Kubernetes Pod障害のトラブルシューティング:包括的なガイド

Kubernetes Podは、エコシステムにおける最小のデプロイ可能な単位であり、アプリケーションを動かすコンテナを実行します。Podが失敗すると、サービスの可用性と信頼性に直接影響します。Pod障害を迅速かつ正確に診断することは、Kubernetes管理者や開発者にとって不可欠なスキルです。

このガイドでは、最も一般的なPod障害シナリオを診断するための構造化された段階的なアプローチを提供します。検査に使用される必須のkubectlコマンド、さまざまなPodステータスの解釈、およびアプリケーションを安定した実行状態に復元するための実行可能な解決策について説明します。


Pod診断の3つの柱

トラブルシューティングは、障害のあるPodに関する利用可能なすべての情報を収集するために、3つの主要なkubectlコマンドを使用することから始まります。

1. 初期ステータスチェック (kubectl get pods)

最初のステップは常に、Podとそのコンテナの現在の状態を判断することです。STATUS列とREADY列に特に注意してください。

kubectl get pods -n my-namespace

Podステータスの解釈

ステータス 意味 初期の対応
Running Podは正常で、すべてのコンテナが実行中です。 (readiness probeが失敗していない限り、おそらく問題なし)
Pending PodはKubernetesによって受け入れられましたが、コンテナはまだ作成されていません。 スケジューリングイベントまたはイメージプルステータスを確認してください。
CrashLoopBackOff コンテナが起動し、クラッシュし、Kubeletが繰り返し再起動を試みています。 アプリケーションログを確認してください (kubectl logs --previous)。
ImagePullBackOff Kubeletが必要なコンテナイメージをプルできません。 イメージ名、タグ、およびレジストリの認証情報を確認してください。
Error ランタイムエラーまたは起動コマンドの失敗によりPodが終了しました。 ログとdescribeイベントを確認してください。
Terminating/Unknown Podがシャットダウン中であるか、Kubeletホストが応答しません。 ノードのヘルスを確認してください。

2. 詳細な調査 (kubectl describe pod)

ステータスがRunning以外の場合、describeコマンドは、スケジューリングの決定、リソース割り当て、コンテナの状態を詳述する重要なコンテキストを提供します。

kubectl describe pod [POD_NAME] -n my-namespace

出力の以下のセクションに注目してください。

  • Containers/Init Containers: State (特にWaitingまたはTerminated) とLast State (障害理由がよく記録される箇所。例: Reason: OOMKilled) を確認します。
  • Resource Limits: LimitsRequestsが正しく設定されていることを確認します。
  • Events: これは最も重要なセクションです。イベントは、スケジューリングの失敗、ボリュームマウントの問題、イメージプルの試行など、ライフサイクル履歴を示します。

ヒント: Eventsセクションに「0/N nodes available」のようなメッセージが表示される場合、Podはリソース不足 (CPU、メモリ) またはアフィニティルールが満たされていないためにスケジュールに失敗している可能性が高いです。

3. ログの確認 (kubectl logs)

ランタイムアプリケーションの問題については、ログがプロセスが終了した理由を説明するスタックトレースやエラーメッセージを提供します。

# 現在のコンテナログを確認
kubectl logs [POD_NAME] -n my-namespace

# Pod内の特定のコンテナのログを確認
kubectl logs [POD_NAME] -c [CONTAINER_NAME] -n my-namespace

# CrashLoopBackOffに不可欠: 以前に失敗した実行のログを確認
kubectl logs [POD_NAME] --previous -n my-namespace

一般的なPod障害シナリオと解決策

ほとんどのPod障害は、いくつかの認識可能なパターンに分類され、それぞれにターゲットを絞った診断アプローチが必要です。

シナリオ1: CrashLoopBackOff

これは最も頻繁なPod障害です。コンテナは正常に起動していますが、コンテナ内のアプリケーションがすぐに終了している (ゼロ以外の終了コードで) ことを意味します。

診断:
1. kubectl logs --previousを使用して、トレースバックまたは終了理由を表示します。
2. kubectl describeを使用して、Last StateセクションのExit Codeを確認します。

一般的な原因と修正:

  • 終了コード 1/2: 一般的なアプリケーションエラー、設定ファイルの欠落、データベース接続の失敗、または不正な入力によるアプリケーションのクラッシュ。
    • 修正: アプリケーションコードをデバッグするか、マウントされているConfigMaps/Secretsを確認します。
  • 依存関係の欠落: エントリポイントスクリプトに必要なファイルや環境が存在しない。
    • 修正: Dockerfileとイメージビルドプロセスを確認します。

シナリオ2: ImagePullBackOff / ErrImagePull

これは、KubeletがPod定義で指定されたコンテナイメージを取得できない場合に発生します。

診断:
1. kubectl describeEventsセクションで特定のエラーメッセージ (例: 404 Not Foundまたはauthentication required) を確認します。

一般的な原因と修正:

  • タイプミスまたは間違ったタグ: イメージ名またはタグが間違っている。
    • 修正: DeploymentまたはPod仕様のイメージ名を修正します。
  • プライベートレジストリへのアクセス: クラスターがプライベートレジストリ (Docker Hub、GCR、ECRなど) からプルするための認証情報を持っていない。
    • 修正: 適切なimagePullSecretがPod仕様で参照されており、そのSecretがnamespaceに存在することを確認します。
# プルシークレットを使用するためのPod仕様の例
spec:
  containers:
  ...
  imagePullSecrets:
  - name: my-registry-secret

シナリオ3: Pendingステータス (スタック)

PodがPendingステータスのままになるのは、通常、ノードにスケジュールできないか、リソース (PersistentVolumeなど) を待っていることを示しています。

診断:
1. kubectl describeを実行し、Eventsセクションを確認します。

一般的な原因と修正:

  • リソースの枯渇: クラスターに、Podのrequestsを満たすのに十分なCPUまたはメモリを持つノードがない。
    • 修正: クラスターサイズを増やすか、Podのリソース要求を減らします (可能な場合)。
    • イベントメッセージの例: 0/4 nodes are available: 4 Insufficient cpu.
  • ボリュームバインディングの問題: Podが、基となるPersistentVolume (PV) にバインドできないPersistentVolumeClaim (PVC) を必要としている。
    • 修正: PVCのステータス (kubectl get pvc) を確認し、StorageClassが機能していることを確認します。

シナリオ4: OOMKilled (メモリ不足により強制終了)

これは通常CrashLoopBackOffステータスになりますが、根本原因は特定されています。コンテナがその仕様で定義された制限よりも多くのメモリを使用したため、ホストオペレーティングシステム (Kubelet経由) が強制的に終了させたものです。

診断:
1. kubectl describe -> Last State -> Reason: OOMKilled を確認します。

修正:

  1. 制限の増加: Pod仕様のメモリlimitを増やし、より多くの余裕を与えます。
  2. アプリケーションの最適化: アプリケーションをプロファイルして、メモリフットプリントを削減します。
  3. リクエストの設定: スケジューリングの信頼性を向上させるために、requestsが実際の定常状態の使用量に近い値に設定されていることを確認します。
resources:
  limits:
    memory: "512Mi" # この値を増やします
  requests:
    memory: "256Mi"

将来の障害を防ぐ: ベストプラクティス

堅牢なアプリケーションには、一般的なデプロイの落とし穴を防ぐための慎重な設定が必要です。

LivenessおよびReadinessプローブを使用する

プローブを適切に実装することで、Kubernetesはコンテナのヘルスをインテリジェントに管理できます。

  • Livenessプローブ: コンテナが実行を継続するのに十分なヘルス状態にあるかを判断します。livenessプローブが失敗した場合、Kubeletはコンテナを再起動します (ソフトロックを解決する)。
  • Readinessプローブ: コンテナがトラフィックを処理する準備ができているかを判断します。readinessプローブが失敗した場合、Podはサービスエンドポイントから削除され、コンテナが回復する間、失敗したリクエストを防ぎます。

リソース制限とリクエストを強制する

常にコンテナのリソース要件を定義してください。これにより、Podが過剰なリソースを消費するのを防ぎ (ノードの不安定化につながる)、スケジューラが十分な容量を持つノードにPodを配置できることが保証されます。

セットアップにInitコンテナを利用する

メインアプリケーションが起動する前にPodが依存関係のチェックやデータセットアップを必要とする場合 (例: データベース移行の完了を待つ)、Initコンテナを使用します。Initコンテナが失敗した場合、Podはそれを繰り返し再起動し、セットアップエラーをアプリケーションのランタイムエラーから明確に分離します。

結論

Kubernetes Podのトラブルシューティングを習得するには、kubectl getkubectl describe、およびkubectl logsの出力に大きく依存する体系的なアプローチが不可欠です。Podステータスを体系的に分析し、イベント履歴を読み解き、一般的な終了コードを理解することで、CrashLoopBackOffImagePullBackOff、およびリソース関連の障害を迅速に診断し解決し、一貫したアプリケーションの稼働時間を確保できます。