【解決】 Kubernetes: Liveness probe failed の解決方法と原因 | Kubernetes トラブルシューティング

Kubernetes環境で「Liveness probe failed」というエラーに直面すると、デプロイしたアプリケーションが不安定になり、サービスに影響が出る可能性があるため、すぐに解決したいですよね。

この記事では、Windowsユーザーの皆さんがPowerShellやCmdを使って、この問題を迅速に解決し、さらに将来的な再発を防ぐための具体的な手順と情報を提供します。ご安心ください、原因を一つずつ確認し、確実な対処法を見つけていきましょう。

1. Kubernetes: Liveness probe failed とは?(概要と緊急度)

「Liveness probe failed」は、Kubernetesクラスター上で稼働しているコンテナの「生存確認(Liveness Probe)」が失敗したことを意味するエラーです。

Kubernetesは、Liveness Probeという仕組みを利用して、コンテナ内のアプリケーションが正常に動作しているか(生きているか)を定期的に監視しています。この監視が失敗すると、Kubernetesはコンテナが異常状態にあると判断し、自動的にそのコンテナを再起動しようとします。

つまり、このエラーは「あなたのコンテナ内のアプリケーションがフリーズしている、デッドロックに陥っている、またはKubernetesがそれを検知できない状態にある」ことを示しています。この状態が続くとコンテナは再起動を繰り返すため、サービス提供に大きな影響を与える可能性があります。緊急度の高い問題として、速やかに対応する必要があります。

2. 【最速】今すぐ試すべき解決策

まずは、最も手軽に試せる解決策として、問題のPodを再起動してみましょう。一時的なリソース枯渇やアプリケーションの一時的なフリーズであれば、この方法で回復する可能性があります。

解決策1:問題のあるPodを再起動する

Liveness Probeの失敗により、KubernetesはすでにPodの再起動を試みているはずですが、手動で該当Podを削除することで、新しいPodが起動し、問題が解消されることがあります。これは、一時的なメモリリークやデッドロックなどの状態をリセットするのに有効です。

まず、Liveness Probeが失敗している、あるいは再起動を繰り返しているPodの名前を特定します。

# すべてのPodの状態を確認し、再起動回数が多いものや「CrashLoopBackOff」状態のPodを探します。
# <namespace>は、Podがデプロイされている名前空間に置き換えてください(例: default)。
kubectl get pods -n <namespace>

# 特定のPodの詳細情報を確認し、Liveness Probeの失敗イベントを探します。
# 通常、「Events」セクションに「Unhealthy」や「Liveness probe failed」といったメッセージが表示されます。
# <pod-name>は、特定したPodの名前に置き換えてください。
kubectl describe pod <pod-name> -n <namespace>

問題のPod名(例: my-app-pod-xyz12)が特定できたら、以下のコマンドでPodを削除します。Kubernetesは自動的に新しいPodを起動します。

# <pod-name>と<namespace>を適切に置き換えて実行してください。
kubectl delete pod <pod-name> -n <namespace>

例:

kubectl delete pod my-app-pod-xyz12 -n default

Podが再起動された後、kubectl get pods -n <namespace>でステータスを確認し、Running状態になっていることを確認してください。もし再度Liveness probe failedが発生する場合は、より詳細な原因調査が必要です。

3. Kubernetes: Liveness probe failed が発生する主要な原因(複数)

Podの再起動で一時的に回復しても、根本原因を解決しない限り再発する可能性があります。ここでは、Liveness probe failedが発生する主な原因と、その特定に役立つ方法を解説します。

原因1:アプリケーションのフリーズまたはデッドロック

最も一般的な原因の一つは、コンテナ内で実行されているアプリケーション自体がフリーズしたり、デッドロックに陥ったりして、HTTPエンドポイントやコマンドに応答できなくなるケースです。これは、CPUスパイク、メモリリーク、無限ループ、データベース接続の停滞などが原因で発生することがあります。

特定方法:

  • アプリケーションログの確認: 該当Podのログを確認し、エラーメッセージ、警告、スタックトレースなどがないか調べます。これにより、アプリケーション内部で何が起こっているかの手がかりを得られます。
    kubectl logs <pod-name> -n <namespace>
  • リソース使用状況の確認: Podが過剰なCPUやメモリを使用していないか確認します。
    kubectl top pod <pod-name> -n <namespace>

    また、Podの詳細情報でOOMKilled(Out Of Memory Killed)イベントなどがないかも確認します。

    kubectl describe pod <pod-name> -n <namespace>

原因2:ヘルスチェックパスの誤設定または未実装

KubernetesのLiveness Probe設定において、ヘルスチェック用のパス(例: /healthz)が間違っているか、あるいはそのパスでアプリケーションが期待される応答(HTTP 200 OKなど)を返していない可能性があります。

特定方法:

  • Kubernetes YAML設定ファイルの確認: DeploymentやPod定義のlivenessProbeセクションを確認し、httpGetpathportexeccommandが正しいかを確認します。
    livenessProbe:
      httpGet:
        path: /healthz  # このパスが正しいか
        port: 8080      # アプリケーションがリッスンしているポートか
      initialDelaySeconds: 15
      periodSeconds: 20
      timeoutSeconds: 5
      failureThreshold: 3
  • アプリケーションコードの確認: 設定されているヘルスチェックパスが、実際にアプリケーションで実装されており、正常な場合に適切なステータスコード(例: HTTP 200)を返しているかを確認します。
  • コンテナ内からの疎通確認: kubectl execでコンテナ内に入り、curlコマンドなどでヘルスチェックパスに直接アクセスして応答を確認します。これにより、アプリケーションが正常なパスで応答しているか、またはネットワーク的な問題かを切り分けられます。
    # WindowsのPowerShellでコンテナのシェルに接続
    kubectl exec -it <pod-name> -n <namespace> -- /bin/sh
    # (コンテナ内に入ったら)
    curl http://localhost:<port>/<path>

原因3:コンテナのリソース不足

コンテナに割り当てられたCPUやメモリが不足している場合、アプリケーションが正常に動作せず、Liveness Probeに応答できなくなることがあります。

特定方法:

  • リソース使用状況の確認: 「原因1」と同様にkubectl top podでPodのリソース使用状況を確認し、CPU(cores)MEMORY(bytes)の値がrequestslimits(後述)に近いか、あるいはそれを超えているかを確認します。
  • Podイベントの確認: kubectl describe pod <pod-name>Eventsセクションで、OOMKilled(Out Of Memory Killed)などのリソース不足に関するイベントがないか確認します。
  • Kubernetes YAML設定の確認: コンテナ定義のresourcesセクションでlimitsrequestsが適切に設定されているかを確認します。limitsが低すぎる場合、アプリケーションが必要とするリソースを確保できず、OOMKilledになる可能性があります。

原因4:ネットワークまたは環境の問題

稀に、Kubernetesの内部ネットワーク、CNIプラグイン、またはPodが動作しているノードの問題により、Liveness Probeがコンテナに到達できない場合があります。

特定方法:

  • PodのIPアドレスとServiceの確認: kubectl get pod -o wideでPodのIPアドレスを確認し、Serviceが正しくルーティングされているか確認します。
  • ノードの状態確認: kubectl get nodeskubectl describe node <node-name>で、Podが動作しているノードに異常がないか確認します。

4. Kubernetesで恒久的に再発を防ぐには

Liveness Probeの失敗を恒久的に防ぐためには、単発の対処療法ではなく、以下の点について見直しと改善を行うことが重要です。

対策1:Liveness Probe設定の最適化

コンテナ内のアプリケーションの特性に合わせて、Liveness Probeの設定を調整することで、誤検知を防ぎ、安定性を向上させることができます。

  • initialDelaySeconds の調整: アプリケーションの起動に時間がかかる場合(例: データベース接続、大量のデータロードなど)、この値を適切に長く設定することで、起動直後のLiveness Probe失敗を防げます。
  • periodSeconds の調整: チェックの頻度です。頻繁すぎるとKubernetes APIに負荷をかけ、遅すぎると異常検知が遅れます。一般的なWebアプリケーションであれば10〜30秒程度が妥当です。
  • timeoutSeconds の調整: プローブが応答を待つ時間です。アプリケーションの応答が遅い場合、この値を長くすることで、タイムアウトによる失敗を防げます。
  • failureThreshold の調整: Liveness Probeが何回連続で失敗したらコンテナを再起動するかを指定します。一時的なネットワークの揺らぎや負荷スパイクによる誤検知を防ぐため、2〜3回程度に設定することが推奨されます。

設定例:

livenessProbe:
  httpGet:
    path: /healthz
    port: 8080
  initialDelaySeconds: 30  # 起動後30秒間はチェックを開始しない
  periodSeconds: 10      # 10秒ごとにチェック
  timeoutSeconds: 5      # 5秒以内に応答がない場合は失敗と判断
  failureThreshold: 3    # 3回連続で失敗したらコンテナを再起動

対策2:Readiness Probeの併用

Liveness Probeはコンテナの「生存」を確認しますが、Readiness Probeはコンテナが「トラフィックを受け入れる準備ができているか」を確認します。両者を適切に使い分けることで、より堅牢なサービス運用が可能になります。

  • Liveness Probe: アプリケーションが完全にフリーズしたり、デッドロックに陥ったりした場合に再起動を促す。
  • Readiness Probe: アプリケーションが起動中、または一時的に外部サービス(データベースなど)に接続できないなどの理由でリクエストを処理できない場合に、Serviceからのトラフィックを一時的に停止させる。

これにより、起動中のコンテナや一時的に不健全なコンテナにリクエストが送られることを防ぎ、ユーザー体験を向上させることができます。

対策3:リソース制限(requests/limits)の最適化

アプリケーションが安定して稼働するために必要なCPUとメモリ量を正確に見積もり、Kubernetesのリソース設定(requestslimits)を最適化することが重要です。

  • requests: コンテナが最低限必要とするリソース量。これを設定することで、Kubernetesはそのリソースが利用可能なノードにPodをスケジュールします。
  • limits: コンテナが使用できるリソースの最大量。これを超過すると、CPUスロットリングが発生したり(CPUの場合)、コンテナがOOMKilledされたり(メモリの場合)します。

アプリケーションの負荷テストを実施し、その結果に基づいて適切な値を設定することで、リソース不足によるLiveness Probe失敗を防ぐことができます。

対策4:詳細なログとモニタリングの実装

問題発生時に迅速に原因を特定できるよう、アプリケーションのログを集中管理システム(Fluentd, Loki, ELK Stackなど)に集約し、CPU使用率、メモリ使用量、ネットワークI/O、アプリケーションのエラーレートなどを継続的にモニタリングすることが不可欠です。

  • アプリケーションログ: エラーや警告を詳細に記録し、異常時にすぐに参照できるようにする。
  • Kubernetesイベント: kubectl get eventsでクラスターイベント(Podのスケジューリング、Kubeletの操作など)を監視し、異常の兆候を捉える。
  • Prometheus/Grafana: メトリクスベースのモニタリングツールを導入し、リソース使用率やLiveness Probeの成功/失敗回数などを可視化する。

対策5:アプリケーションコードの堅牢性向上

Liveness Probeの失敗は、根本的にはアプリケーションコードの不具合に起因することが多いため、アプリケーション自体の堅牢性を高めることが最も重要です。

  • デッドロックが発生しにくい設計
  • メモリリークやリソースリークの防止
  • 外部サービスへの依存関係に対する適切なタイムアウトやリトライ処理の実装
  • ヘルスチェックエンドポイントの正確な実装とテスト

これらの対策を講じることで、「Liveness probe failed」エラーの発生を大幅に削減し、Kubernetesクラスター上でのアプリケーションの安定稼働を実現できます。