このページでは、Google Kubernetes Engine(GKE)でデプロイされたワークロードのエラーを解決する方法について説明します。
アプリケーションのトラブルシューティングに関する一般的なアドバイスについては、Kubernetes のドキュメントでアプリケーションのトラブルシューティングをご覧ください。
すべてのエラー: Pod のステータスを確認する
ワークロードの Pod に問題がある場合、Kubernetes は Pod のステータスをエラー メッセージとともに更新します。これらのエラーを確認するには、 Google Cloud コンソールまたは kubectl
コマンドライン ツールを使用して Pod のステータスを確認します。
コンソール
次の手順を行います。
Google Cloud コンソールで、[ワークロード] ページに移動します。
調査するワークロードを選択します。[概要] タブにワークロードのステータスが表示されます。
[マネージド 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
の場合、特定のエラーがあるわけではなく、コンテナが再起動後に繰り返しクラッシュしていることを示します。コンテナが起動直後にクラッシュまたは終了した場合(CrashLoop
)、Kubernetes はコンテナの再起動を試みます。再起動が失敗するたびに、次の試行までの遅延(BackOff
)は指数関数的に増加し(10 秒、20 秒、40 秒など)、最大で 5 分になります。
以降のセクションでは、コンテナがクラッシュする原因を特定する方法について説明します。
クラッシュループしている Pod のインタラクティブ ハンドブックを使用する
Google Cloud コンソールのインタラクティブ ハンドブックを使用して、CrashLoopBackOff
ステータスの原因のトラブルシューティングを開始します。
クラッシュループしている Pod のインタラクティブ ハンドブックに移動します。
[クラスタ] プルダウン リストで、トラブルシューティングするクラスタを選択します。クラスタが見つからない場合は、
(フィルタ)フィールドにクラスタの名前を入力します。[Namespace] プルダウン リストで、トラブルシューティングする Namespace を選択します。Namespace が見つからない場合は、
(フィルタ)フィールドに Namespace を入力します。各セクションを確認して、原因を特定します。
- アプリケーション エラーの特定
- メモリ不足問題の調査
- ノードの中断を調査する
- livenessProbe 失敗の調査
- 変更イベントの相関
省略可: 今後
CrashLoopBackOff
エラーが発生した場合に通知を受け取るには、[今後の対応のヒント] セクションで [アラートを作成する] を選択します。
ログを検査する
コンテナはさまざまな理由でクラッシュすることがあり、Pod のログを調べると根本原因のトラブルシューティングに役立ちます。
ログを確認するには、 Google Cloud コンソールまたは kubectl
コマンドライン ツールを使用します。
コンソール
次の手順を行います。
Google Cloud コンソールの [ワークロード] ページに移動します。
調査するワークロードを選択します。[概要] タブにワークロードのステータスが表示されます。
[マネージド Pod] セクションで、問題のある Pod をクリックします。
Pod のメニューで、[ログ] タブをクリックします。
kubectl
クラスタで実行されているすべての Pod を表示します。
kubectl get pods
上記のコマンドの出力で、
Status
列にCrashLoopBackOff
エラーがある Pod を探します。Pod のログを取得します。
kubectl logs POD_NAME
POD_NAME
は、問題のある Pod の名前に置き換えます。また、
-p
フラグを使用して、Pod の以前のコンテナ インスタンス(存在する場合)のログを取得することもできます。
クラッシュしたコンテナの終了コードを確認する
コンテナがクラッシュした理由を詳しく把握するには、終了コードを確認します。
Pod の説明を取得します。
kubectl describe pod POD_NAME
POD_NAME
は、問題のある Pod の名前に置き換えます。containers: CONTAINER_NAME: last state: exit code
フィールドの値を確認します。- 終了コードが 1 の場合、コンテナがクラッシュした理由はアプリケーションのクラッシュです。
- 終了コードが 0 の場合は、アプリの実行時間を確認します。コンテナは、アプリケーションのメインプロセスが終了したときに終了します。アプリの実行が非常に速く終了する場合、コンテナが再起動を続行している可能性があります。このエラーが発生した場合は、
restartPolicy
フィールドをOnFailure
に設定することをおすすめします。この変更を行うと、終了コードが 0 でない場合のみ、アプリが再起動されます。
実行中のコンテナに接続する
コンテナから bash コマンドを実行してネットワークをテストしたり、アプリケーションで使用されているファイルやデータベースにアクセスできるかどうかを確認するには、Pod へのシェルを開始します。
kubectl exec -it POD_NAME -- /bin/bash
Pod 内にコンテナが複数ある場合は、-c CONTAINER_NAME
を追加します。
エラー: ImagePullBackOff と ErrImagePull
ステータスが ImagePullBackOff
または ErrImagePull
の場合、コンテナが使用するイメージをイメージ レジストリから読み込めないことを示します。
これらのステータスのトラブルシューティングのガイダンスについては、イメージの pull のトラブルシューティングをご覧ください。
エラー: Pod unschedulable
ステータスが PodUnschedulable
の場合、リソースが不足しているか、なんらかの構成エラーのために Pod をスケジュールできないことを示します。
コントロール プレーンの指標を構成している場合は、スケジューラの指標と API サーバーの指標でエラーの詳細を確認できます。
スケジュール不可の Pod のインタラクティブ ハンドブックを使用する
Google Cloud コンソールのインタラクティブ ハンドブックを使用して、PodUnschedulable
エラーをトラブルシューティングできます。
スケジュール不可の Pod のインタラクティブ ハンドブックに移動します。
[クラスタ] プルダウン リストで、トラブルシューティングするクラスタを選択します。クラスタが見つからない場合は、
(フィルタ)フィールドにクラスタの名前を入力します。[Namespace] プルダウン リストで、トラブルシューティングする Namespace を選択します。Namespace が見つからない場合は、
(フィルタ)フィールドに Namespace を入力します。原因を特定するには、ハンドブックの各セクションを確認します。
- CPU とメモリの調査
- ノードあたりの最大 Pod 数の調査
- オートスケーラーの動作の調査
- その他の障害モードの調査
- 変更イベントの相関
省略可: 今後
PodUnschedulable
エラーが発生した場合に通知を受け取るには、[今後の対応のヒント] セクションで [アラートを作成する] を選択します。
エラー: Insufficient resources
CPU、メモリ、またはその他のリソースが不足していることを示すエラーが発生する場合があります。たとえば、No nodes are available that match all of the predicates:
Insufficient cpu (2)
は、2 つのノードで、Pod のリクエストに対して十分な CPU がないことを示します。
Pod のリソース リクエストが有効なノードプールの単一ノードの上限を超えた場合、GKE は Pod をスケジュールしません。また、新しいノードを追加するためのスケールアップもトリガーしません。GKE が Pod をスケジュールするには、Pod 用にリクエストするリソースを減らすか、十分なリソースを持つ新しいノードプールを作成する必要があります。
また、ノードの自動プロビジョニングを有効にして、スケジュールされていない Pod が実行可能なノードを含むノードプールを自動的に作成することもできます。
デフォルトの CPU リクエストは 100m、または CPU の 10%(あるいは 1 コア)です。リクエストするリソースの数を変更するには、spec: containers: resources: requests
の Pod 仕様に値を指定します。
エラー: MatchNodeSelector
MatchNodeSelector
は、Pod のラベルセレクタに一致するノードがないことを示します。
これを確認するには、Pod 仕様の nodeSelector
フィールド(spec: nodeSelector
の下)に指定されているラベルを確認します。
クラスタ内のノードがどのようにラベルされているか確認するには、次のコマンドを実行します。
kubectl get nodes --show-labels
ノードにラベルを付けるには、次のコマンドを実行します。
kubectl label nodes NODE_NAME LABEL_KEY=LABEL_VALUE
次のように置き換えます。
NODE_NAME
: ラベルを追加するノード。LABEL_KEY
: ラベルのキー。LABEL_VALUE
: ラベルの値。
詳細については、Kubernetes のドキュメントでノードに Pod を割り当てるをご覧ください。
エラー: PodToleratesNodeTaints
PodToleratesNodeTaints
は、Pod に既存の node taint に対応する toleration がないため、Pod をノードにスケジュールできないことを示します。
これが該当することを確認するには、次のコマンドを実行します。
kubectl describe nodes NODE_NAME
出力で、Taints
フィールドを確認すると、Key-Value のペアとスケジューリングの結果が一覧表示されています。
リストされた結果が NoSchedule
の場合、そのノードは一致する容認がなければ、Pod をスケジュールできません。
この問題を解決する方法の 1 つは、taint を削除することです。たとえば、NoSchedule taint を削除するには、次のコマンドを実行します。
kubectl taint nodes NODE_NAME key:NoSchedule-
エラー: PodFitsHostPorts
PodFitsHostPorts
エラーは、ノードがすでに占有されているポートを使用しようとしていることを意味します。
この問題を解決するには、Kubernetes のベスト プラクティスに沿って、hostPort
ではなく NodePort
を使用することを検討してください。
hostPort
を使用する必要がある場合は、Pod のマニフェストを調べて、同じノード上のすべての Pod に hostPort
に一意の値が定義されていることを確認します。
エラー: Does not have minimum availability
ノードに十分なリソースがあるのに Does not have minimum availability
というメッセージが表示される場合は、Pod のステータスを確認します。ステータスが SchedulingDisabled
または Cordoned
の場合、ノードは新しい Pod をスケジュールできません。ノードのステータスを確認するには、 Google Cloud コンソールまたは kubectl
コマンドライン ツールを使用します。
コンソール
次の手順を行います。
Google Cloud コンソールで [Google Kubernetes Engine] ページに移動します。
調査するクラスタを選択します。[ノード] タブに、ノードとそのステータスが表示されます。
ノードでスケジューリングを可能にするには、次の操作を行います。
リストで、調査するノードをクリックします。
[ノードの詳細] セクションで、[閉鎖解除] をクリックします。
kubectl
ノードのステータスを取得するには、次のコマンドを実行します。
kubectl get nodes
ノードでスケジューリングを可能にするには、次のコマンドを実行します。
kubectl uncordon NODE_NAME
エラー: Maximum Pods per node limit reached
クラスタ内のすべてのノードがノードあたりの最大 Pod 数の上限に達すると、Pod はスケジュール不可の状態で停止します。Pod の [イベント] タブに、Too many pods
というフレーズを含むメッセージが表示されます。
このエラーを解決するには、次の操作を行います。
Google Cloud コンソールで GKE クラスタの詳細に移動し、[ノード] タブで
Maximum pods per node
構成を確認します。ノードのリストを取得します。
kubectl get nodes
ノードごとに、そのノードで実行されている Pod の数を確認します。
kubectl get pods -o wide | grep NODE_NAME | wc -l
上限に達している場合は、新しいノードプールを追加するか、既存のノードプールにノードを追加します。
問題: クラスタ オートスケーラーが有効な状態でノードプールの最大サイズに達した
ノードプールがクラスタ オートスケーラーの構成に従って最大サイズに達した場合、GKE は、このノードプールでスケジュールされている Pod のスケールアップをトリガーしません。このノードプールで Pod をスケジュールする場合は、クラスタ オートスケーラーの構成を変更します。
問題: クラスタ オートスケーラーが無効な状態でノードプールの最大サイズに達した
クラスタ オートスケーラーが無効になっている状態でノードプールが最大ノード数に達した場合、GKE はノードプールで Pod をスケジュールできません。ノードプールのサイズを増やすか、GKE でクラスタ オートスケーラーを有効にして、クラスタのサイズを自動的に変更します。
エラー: Unbound PersistentVolumeClaims
Unbound PersistentVolumeClaims
は、Pod がバインドされていない PersistentVolumeClaim を参照していることを示します。このエラーは、PersistentVolume がプロビジョニングに失敗した場合に発生することがあります。プロビジョニングが失敗したことを確認するには、PersistentVolumeClaim のイベントを取得して失敗の有無を調べます。
イベントを取得するには、次のコマンドを実行します。
kubectl describe pvc STATEFULSET_NAME-PVC_NAME-0
次のように置き換えます。
STATEFULSET_NAME
: StatefulSet オブジェクトの名前。PVC_NAME
: PersistentVolumeClaim オブジェクトの名前。
PersistentVolume および PersistentVolumeClaim とのバインディングを手動で事前プロビジョニングする際に構成エラーがあった場合にも、このエラーが発生することがあります。
このエラーを解決するには、ボリュームの事前プロビジョニングをもう一度試します。
エラー: Insufficient quota
GKE がクラスタをスケールアップするのに十分な Compute Engine 割り当てがプロジェクトにあることを確認します。GKE が Pod をスケジュールするためにクラスタにノードを追加しようとしたときに、スケールアップがプロジェクトの使用可能な割り当てを超えると、scale.up.error.quota.exceeded
エラー メッセージが表示されます。
詳細については、ScaleUp エラーをご覧ください。
問題: 非推奨の API
クラスタのマイナー バージョンと一緒に削除される非推奨の API を使用していないことを確認します。詳細については、機能と API の非推奨をご覧ください。
エラー: リクエストされた Pod ポートに空きポートがない
次のようなエラーが表示された場合は、同じノードに複数の Pod があり、hostPort
フィールドに同じ値が定義されている可能性があります。
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
にバインドすると、GKE が Pod をスケジュールできる場所が制限されます。これは、各 hostIP
、hostPort
、protocol
の組み合わせが一意である必要があるためです。
この問題を解決するには、Kubernetes のベスト プラクティスに沿って、hostPort
ではなく NodePort
を使用することを検討してください。
hostPort
を使用する必要がある場合は、Pod のマニフェストを調べて、同じノード上のすべての Pod に hostPort
に一意の値が定義されていることを確認します。
次のステップ
このドキュメントに問題のソリューションが見当たらない場合は、サポートを受けるで、次のトピックに関するアドバイスなど、詳細なヘルプをご覧ください。
- Cloud カスタマーケアに問い合わせて、サポートケースを登録する。
- StackOverflow で質問し、
google-kubernetes-engine
タグを使用して類似の問題を検索することで、コミュニティからサポートを受ける。#kubernetes-engine
Slack チャンネルに参加して、コミュニティ サポートを利用することもできます。 - 公開バグトラッカーを使用して、バグの報告や機能リクエストの登録を行う。