デプロイされたワークロードに関する問題のトラブルシューティング

このページでは、Google Kubernetes Engine(GKE)でデプロイされたワークロードのエラーを解決する方法について説明します。

アプリケーションのトラブルシューティングに関する一般的なアドバイスについては、Kubernetes のドキュメントでアプリケーションのトラブルシューティングをご覧ください。

すべてのエラー: Pod のステータスを確認する

ワークロードの Pod に問題がある場合、Kubernetes は Pod のステータスをエラー メッセージとともに更新します。これらのエラーを確認するには、 Google Cloud コンソールまたは kubectl コマンドライン ツールを使用して Pod のステータスを確認します。

コンソール

次の手順を行います。

  1. Google Cloud コンソールで、[ワークロード] ページに移動します。

    [ワークロード] に移動

  2. 調査するワークロードを選択します。[概要] タブにワークロードのステータスが表示されます。

  3. [マネージド Pod] セクションで、エラー ステータス メッセージをクリックします。

kubectl

クラスタで実行しているすべての Pod を表示するには、次のコマンドを実行します。

kubectl get pods

出力は次のようになります。

NAME       READY  STATUS             RESTARTS  AGE
POD_NAME   0/1    CrashLoopBackOff   23        8d

発生する可能性のあるエラーは Status 列に示されます。

特定の Pod の詳細情報を取得するには、次のコマンドを実行します。

kubectl describe pod POD_NAME

POD_NAME を調査する Pod の名前に置き換えます。

出力の Events フィールドに、エラーの詳細が表示されます。

詳細については、コンテナログを表示します。

kubectl logs POD_NAME

これらのログは、コンテナ内のコマンドまたはコードが Pod のクラッシュの原因であるかどうかを特定する際に役立ちます。

エラーを特定したら、次のセクションに進み、問題を解決してください。

エラー: CrashLoopBackOff

ステータスが CrashLoopBackOff の場合、特定のエラーがあるわけではなく、コンテナが再起動後に繰り返しクラッシュしていることを示します。

詳細については、CrashLoopBackOff イベントのトラブルシューティングをご覧ください。

エラー: ImagePullBackOff と ErrImagePull

ステータスが ImagePullBackOff または ErrImagePull の場合、コンテナが使用するイメージをイメージ レジストリから読み込めないことを示します。

これらのステータスのトラブルシューティングのガイダンスについては、イメージの pull のトラブルシューティングをご覧ください。

エラー: OutOfPods

ステータスが OutOfPods の場合、ノードが Pod の最大容量に達しているため、ノードで Pod を実行できないことを示します。

現象

Pod のイベントに次のようなメッセージが表示されることがあります。

Node didn't have enough resource: pods, requested: 1, used: 32, capacity: 32

原因

このエラーは、容量がすでに上限に達しているノードに Pod をスケジュールするリクエストがある場合に発生します。この状況は、ノードの起動時によく発生します。たとえば、独自の Pod 容量を必要とする kube-proxy コンポーネントのような静的 Pod の存在を kubelet エージェントが報告する前に、kube-scheduler コンポーネントが Pod を新しいノードに割り当てる場合などです。

解決策

この問題を解決するには、次のいずれかの解決策を試してください。

  • ノードあたりの Pod の最大数を増やす。ノードが常に Pod の上限に達している場合は、ノードプールの --max-pods-per-node 設定の値を大きくします。Pod の数を増やすと、リソース需要の増加に対応するために、より大きなノードが必要になることがあります。

  • クラスタ オートスケーラーとノード自動プロビジョニングを有効にする。Pod の容量が頻繁に不足する場合は、クラスタ オートスケーラーノード自動プロビジョニングを有効にすると、クラスタでワークロードの需要を満たすために十分なノードを確保できます。

  • 自動スケーリング プロファイルを変更する。クラスタ オートスケーラーをすでに使用している場合は、 自動スケーリング プロファイルoptimize-utilization プロファイルではなく balanced プロファイルに変更してみてください。 optimize-utilization プロファイルは、使用率が最も高いノードに Pod を配置しようとするため、OutOfPods エラーが発生する可能性が高くなります。

エラー: Pod unschedulable

ステータスが PodUnschedulable の場合、リソースが不足しているか、なんらかの構成エラーのために Pod をスケジュールできないことを示します。

コントロール プレーンの指標を構成している場合は、スケジューラの指標API サーバーの指標でエラーの詳細を確認できます。

スケジュール不可の Pod のインタラクティブ ハンドブックを使用する

Google Cloud コンソールのインタラクティブ ハンドブックを使用して、PodUnschedulable エラーをトラブルシューティングできます。

  1. スケジュール不可の Pod のインタラクティブ ハンドブックに移動します。

    ハンドブックに移動

  2. [クラスタ] プルダウン リストで、トラブルシューティングするクラスタを選択します。クラスタが見つからない場合は、フィルタ)フィールドにクラスタの名前を入力します。

  3. [Namespace] プルダウン リストで、トラブルシューティングする Namespace を選択します。Namespace が見つからない場合は、フィルタ)フィールドに Namespace を入力します。

  4. 原因を特定するには、ハンドブックの各セクションを確認します。

    1. CPU とメモリの調査
    2. ノードあたりの最大 Pod 数の調査
    3. オートスケーラーの動作の調査
    4. その他の障害モードの調査
    5. 変更イベントの相関
  5. 省略可: 今後 PodUnschedulable エラーが発生した場合に通知を受け取るには、[今後の対応のヒント] セクションで [アラートを作成する] を選択します。

エラー: Insufficient resources

Pod のリクエストを満たすのに十分な CPU、メモリ、その他のリソースがない場合、PodUnschedulable ステータスが発生することがあります。

現象

CPU、メモリ、またはその他のリソースが不足していることを示すエラーが発生する場合があります。例: No nodes are available that match all of the predicates: Insufficient cpu (2)。このメッセージは、2 つのノードで、Pod のリクエストに対して十分な CPU がないことを示します。

原因

Pod のリソース リクエストが有効なノードプールの単一ノードの上限を超えた場合、GKE は Pod をスケジュールしません。また、新しいノードを追加するためのスケールアップもトリガーしません。

クラスタは kube-system Namespace でシステム コンテナを実行します。システム コンテナもクラスタ リソースを使用します。

解決策

次の解決策を試してください。

  • spec: containers: resources: requests フィールドに小さい値を指定して、Pod のリソース リクエストを調整します。デフォルトの CPU リクエストは 100m、または CPU の 10%(あるいは 1 コア)です。

  • Pod のリクエストを満たすのに十分なリソースを持つノードで新しいノードプールを作成します。

  • ノード自動プロビジョニングを有効にして、GKE がスケジュールされていない Pod が実行可能なノードを含むノードプールを自動的に作成できるようにします。

エラー: MatchNodeSelector

MatchNodeSelector エラーは、Pod のラベルセレクタに一致するノードがないことを示します。

現象

Pod のステータスまたはイベントに MatchNodeSelector エラーが表示されます。

原因

Pod マニフェストの nodeSelector フィールドに指定されたラベルが、クラスタ内のどのノードにも存在しません。

解決策

このエラーを解決するには、Pod の nodeSelector フィールドに指定されたラベルが、クラスタ内の少なくとも 1 つのノードのラベルと一致していることを確認します。

  1. Pod が探しているラベル要件を特定するには、spec: nodeSelector フィールドを確認します。

  2. Pod の要件に一致するラベルがあるかどうかを確認するには、クラスタ内のノードに割り当てられている実際のラベルを表示します。

    kubectl get nodes --show-labels
    
  3. ノードでこの Pod を実行する場合は、必要なラベルを付加します。

    kubectl label nodes NODE_NAME LABEL_KEY=LABEL_VALUE
    

    次のように置き換えます。

    • NODE_NAME: ラベルを追加するノード。
    • LABEL_KEY: ラベルのキー。
    • LABEL_VALUE: ラベルの値。

詳細については、Kubernetes のドキュメントで ノードに Pod を割り当てる をご覧ください。

エラー: PodToleratesNodeTaints

A PodToleratesNodeTaints エラーは、Pod に既存の node taintに対応する toleration がないため、Pod を ノードにスケジュールできないことを示します。

現象

Pod のステータスまたはイベントに PodToleratesNodeTaints エラーが表示されます。

原因

Pod に既存の node taint に対応する toleration がないため、Pod をノードにスケジュールできません。

解決策

  1. ノードの taint を確認します。

    kubectl describe nodes NODE_NAME
    

    出力で、Taints フィールドを確認すると、Key-Value ペアとスケジューリングの結果が一覧表示されています。リストされた結果が NoSchedule の場合、そのノードは一致する 容認がなければ、Pod を スケジュールできません。

  2. ノードから taint を削除します。たとえば、NoSchedule taint を削除するには、次のコマンドを実行します。

    kubectl taint nodes NODE_NAME key:NoSchedule-
    

エラー: PodFitsHostPorts

PodFitsHostPorts エラーは、ノードがすでに占有されているポートを使用しようとしていることを意味します。

現象

Pod のステータスに PodFitsHostPorts エラーが表示されます。

原因

Pod が、ターゲット ノード上の別の Pod またはプロセスですでに使用されているホストポートをリクエストしています。

解決策

この問題を解決するには、 Kubernetes のベスト プラクティス に沿って、hostPort 設定ではなく NodePort Service を使用することを検討してください。

ホストポートを使用する必要がある場合は、Pod のマニフェストを調べて、同じノード上のすべての Pod に hostPort 設定に一意の値が定義されていることを確認します。

エラー: Does not have minimum availability

このエラーは、ノードに十分なリソースがあるものの、スケジューリングに使用できない場合に発生することがあります。

現象

  • Does not have minimum availability エラーが表示されます。

  • ノードのステータスに SchedulingDisabled ステータスまたは Cordoned ステータスが表示されます。

原因

ノードが閉鎖されているため、新しい Pod をスケジュールできません。

解決策

Pod を再度スケジュールできるようにするには、ノードの閉鎖を解除します。

コンソール

次の手順を行います。

  1. Google Cloud コンソールで [Google Kubernetes Engine] ページに移動します。

    Google Kubernetes Engine に移動

  2. 調査するクラスタを選択します。[ノード] タブに、ノードとそのステータスが表示されます。

ノードでスケジューリングを可能にするには、次の操作を行います。

  1. リストで、調査するノードをクリックします。

  2. [ノードの詳細] セクションで、[閉鎖解除] をクリックします。

kubectl

ノードのステータスを取得するには、次のコマンドを実行します。

kubectl get nodes

ノードでスケジューリングを可能にするには、次のコマンドを実行します。

kubectl uncordon NODE_NAME

エラー: Maximum Pods per node limit reached

Too many pods エラーは、ターゲット ノードが構成済みの Pod の最大容量に達しているため、Pod をスケジュールできないことを示します。

現象

  • Pod が Unschedulable 状態のままになる。
  • Too many pods というフレーズを含むメッセージが表示される。

原因

クラスタ内のすべてのノードがノードあたりの最大 Pod 数 の上限に達しています。

解決策

このエラーを解決するには、次の操作を行います。

  1. Google Cloud コンソールで GKE クラスタの詳細に移動し、[ノード] タブで Maximum pods per node 構成を確認します。

  2. ノードのリストを取得します。

    kubectl get nodes
    
  3. ノードごとに、そのノードで実行されている Pod の数を確認します。

    kubectl get pods -o wide | grep NODE_NAME | wc -l
    
  4. 上限に達している場合は、新しいノードプールを追加するか、既存のノードプールにノードを追加します。

問題: クラスタ オートスケーラーが有効な状態でノードプールの最大サイズに達した

この問題は、ノードプールがクラスタ オートスケーラーで構成された最大サイズに達した場合に発生します。

現象

GKE は、このノードプールでスケジュールされている Pod のスケールアップをトリガーしません。代わりに、Pod は Pending 状態のままになります。

原因

ノードプールがクラスタ オートスケーラーの構成に従って最大 サイズ に達しています。

解決策

クラスタ オートスケーラーの 構成を変更して、ノードプールの最大サイズを増やします。

問題: クラスタ オートスケーラーが無効な状態でノードプールの最大サイズに達した

この問題は、ノードプールが最大サイズに達し、クラスタ オートスケーラーが無効になっている場合に発生します。

現象

GKE はノードプールで Pod をスケジュールできません。

原因

ノードプールが最大ノード数に達し、クラスタ オートスケーラーが無効になっています。

解決策

この問題を解決するには、次のいずれかの解決策を試してください。

エラー: Unbound PersistentVolumeClaims

Unbound PersistentVolumeClaims エラーは、Pod がバインドされていない PersistentVolumeClaim を参照していることを示します。

現象

Pod のステータスまたはイベントに Unbound PersistentVolumeClaims エラーが表示されます。

原因

このエラーは、次のいずれかの理由で発生した可能性があります。

  • PersistentVolume のプロビジョニングに失敗しました。
  • PersistentVolume および PersistentVolumeClaim とのバインディングを手動で事前プロビジョニングする際に構成エラーがありました。

解決策

  1. PersistentVolumeClaim のイベントを取得して、プロビジョニングが失敗したかどうかを確認します。

    kubectl describe pvc STATEFULSET_NAME-PVC_NAME-0
    

    次のように置き換えます。

    • STATEFULSET_NAME: StatefulSet オブジェクトの名前。
    • PVC_NAME: PersistentVolumeClaim オブジェクトの名前。
  2. ボリュームの事前プロビジョニングをもう一度行ってみてください。

エラー: Insufficient quota

GKE が Pod をスケジュールするためにクラスタをスケールアップしようとしたときに、割り当ての制約が発生すると、スケールアップは失敗します。

現象

Pod のイベントに scale.up.error.quota.exceeded エラー メッセージが表示されます。

原因

クラスタをスケールアップすると、プロジェクトの使用可能な割り当てを超えます。

解決策

GKE がクラスタをスケールアップするのに十分な Compute Engine 割り当てがプロジェクトにあることを確認します。詳細については、 ScaleUp エラーをご覧ください。

問題: 非推奨の API

マニフェストでサポートされなくなった API を使用すると、ワークロードのデプロイが妨げられる可能性があります。

現象

非推奨の API の使用により、ワークロードのデプロイまたは実行に失敗します。

原因

マニフェストで、クラスタのマイナー バージョンで削除された非推奨の API を使用しています。

解決策

非推奨の API を使用していないことを確認します。サポートされている API を使用するようにマニフェストを更新します。詳細については、機能と API の非推奨をご覧ください。

エラー: リクエストされた Pod ポートに空きポートがない

Pod をホストポートにバインドすると、GKE が Pod をスケジュールできる場所が制限されます。これは、各 hostIP アドレス、hostPort 設定、protocol 値の組み合わせが一意である必要があるためです。

現象

次のようなエラーが表示されます。

0/1 nodes are available: 1 node(s) didn't have free ports for the requested pod ports. preemption: 0/1 nodes are available: 1 No preemption victims found for incoming pod.

原因

同じノード上の複数の Pod が、hostPort フィールドで定義されている同じ値を指定しています。

解決策

この問題を解決するには、次のいずれかの解決策を試してください。

  • Kubernetes のベスト プラクティス に沿って、ホストポートではなく NodePort Service を使用します。
  • ホストポートを使用する必要がある場合は、Pod のマニフェストを調べて、同じノード上のすべての Pod に hostPort フィールドに一意の値が定義されていることを確認します。

問題: Pod でのアプリケーションとプローブの障害

この問題は、HTTPS を使用してサーバーと通信するアプリケーションを実行する場合に発生します。

現象

これらのアプリケーションの障害は次のようになります。

  • Pod が起動せず、コンテナが終了コード 137 でクラッシュする。
  • 次のようなエラー メッセージが表示され、Liveness プローブまたは Readiness プローブが失敗する。

    probeResult="failure" output="Get "https://example.com/healthy": EOF"
    
  • Pod は想定どおりに実行されるが、アプリケーション ログに接続エラーが表示される。

原因

Kubernetes バージョン 1.30 以降では、次の TLS 暗号スイートを無効にする Golang バージョンを使用します。

  • TLS_RSA_WITH_AES_128_GCM_SHA256
  • TLS_RSA_WITH_AES_256_GCM_SHA384
  • TLS_RSA_WITH_AES_128_CBC_SHA
  • TLS_RSA_WITH_AES_256_CBC_SHA
  • TLS_RSA_WITH_3DES_EDE_CBC_SHA

解決策

サポートされている暗号スイート を TLS 1.2 以降で使用します。

次のステップ

  • このドキュメントで問題を解決できない場合は、サポートを受けるで、次のトピックに関するアドバイスなど、詳細なヘルプをご覧ください。

    • Cloud カスタマーケアに問い合わせて、サポートケースを登録する。
    • StackOverflow で質問する、google-kubernetes-engine タグを使用して類似の問題を検索するなどして、コミュニティからサポートを受ける。Slack チャネル に参加して、コミュニティ サポートを利用することもできます。#kubernetes-engine
    • 公開バグトラッカーを使用して、問題の報告や機能リクエストを行う。