Autopilot クラスタのトラブルシューティング


このページでは、Google Kubernetes Engine(GKE)Autopilot クラスタの問題を解決する方法について説明します。

さらにサポートが必要な場合は、Cloud カスタマーケアにお問い合わせください。

クラスタに関する問題

クラスタを作成できない: 0 個のノードが登録されている

次の問題は、無効になっている IAM サービス アカウントまたは必要な権限がない IAM サービス アカウントで Autopilot クラスタを作成しようとすると発生します。クラスタの作成が失敗し、次のエラー メッセージが表示されます。

All cluster resources were brought up, but: only 0 nodes out of 2 have registered.

この問題を解決するには、次の操作を行います。

  1. 使用するデフォルトの Compute Engine サービス アカウントまたはカスタム IAM サービス アカウントが無効になっているかどうかを確認します。

    gcloud iam service-accounts describe SERVICE_ACCOUNT
    

    SERVICE_ACCOUNT を、サービス アカウントのメールアドレス(my-iam-account@my-first-project.iam.gserviceaccount.com など)に置き換えます。

    サービス アカウントが無効になっている場合、出力は次のようになります。

    disabled: true
    displayName: my-service-account
    email: my-service-account@my-project.iam.gserviceaccount.com
    ...
    
  2. サービス アカウントが無効になっている場合は、有効にします。

    gcloud iam service-accounts enable SERVICE_ACCOUNT
    

サービス アカウントが有効になっていてもエラーが解決しない場合は、GKE に必要な最小限の権限をサービス アカウントに付与します。

gcloud projects add-iam-policy-binding PROJECT_ID \
    --member "serviceAccount:SERVICE_ACCOUNT" \
    --role roles/container.nodeServiceAccount

クラスタにノードがない場合、Namespace が終了中の状態のままになる

次の問題は、クラスタをゼロノードにスケールダウンした後にクラスタ内の Namespace を削除すると発生します。metrics-server コンポーネントは、レプリカがゼロであるため、Namespace の削除リクエストを受け入れることはできません。

この問題を診断するには、次のコマンドを実行します。

kubectl describe ns/NAMESPACE_NAME

NAMESPACE_NAME は Namespace の名前に置き換えます。

次のような出力が表示されます。

Discovery failed for some groups, 1 failing: unable to retrieve the complete
list of server APIs: metrics.k8s.io/v1beta1: the server is currently unable to
handle the request

この問題を解決するには、任意のワークロードをスケールアップして 新しいノードを作成するよう GKE をトリガーします。ノードの準備が整うと、Namespace 削除リクエストが自動的に完了します。GKE により Namespace が削除されたら、ワークロードを再びスケールダウンします。

スケーリングに関する問題

ノードのスケールアップが失敗した: Pod がスケジュールされない可能性がある

次の問題は、Google Cloud プロジェクトでシリアルポート ロギングが無効になっていると発生します。GKE Autopilot クラスタでは、ノードの問題を効果的にデバッグするために、シリアルポート ロギングが必要です。シリアルポート ロギングが無効になっていると、Autopilot はワークロードを実行するノードをプロビジョニングできません。

Kubernetes イベントログのエラー メッセージは、次のようになります。

LAST SEEN   TYPE      REASON          OBJECT                          MESSAGE
12s         Warning   FailedScaleUp   pod/pod-test-5b97f7c978-h9lvl   Node scale up in zones associated with this pod failed: Internal error. Pod is at risk of not being scheduled

シリアルポートのロギングは、compute.disableSerialPortLogging 制約を適用する組織のポリシーによって組織レベルで無効になっていることがあります。シリアルポート ロギングは、プロジェクト レベルまたは仮想マシン(VM)インスタンス レベルで無効になっていることもあります。

この問題を解決するには、次の操作を行います。

  1. Google Cloud 組織のポリシー管理者に、Autopilot クラスタを含むプロジェクトで compute.disableSerialPortLogging 制約を削除するよう依頼してください。
  2. この制約を適用する組織のポリシーがない場合は、プロジェクト メタデータでシリアルポート ロギングを有効にすることを試してください。この操作には、compute.projects.setCommonInstanceMetadata IAM 権限が必要です。

ノードのスケールアップが失敗した: GCE のリソース不足

Compute Engine リージョンまたはゾーンで使用可能なリソースよりも多くのリソースをワークロードがリクエストすると、次の問題が発生します。Pod が Pending 状態のままになることがあります。

  • Pod イベントを確認します。

    kubectl events --for='pod/POD_NAME' --types=Warning
    

    RESOURCE_NAME は、保留中の Kubernetes リソースの名前に置き換えます。例: pod/example-pod

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

    LAST SEEN         TYPE            REASON                  OBJECT                   Message
    19m               Warning         FailedScheduling        pod/example-pod          gke.io/optimize-utilization-scheduler  0/2 nodes are available: 2 node(s) didn't match Pod's node affinity/selector. preemption: 0/2 nodes are available: 2 Preemption is not helpful for scheduling.
    14m               Warning         FailedScheduling        pod/example-pod          gke.io/optimize-utilization-scheduler  0/2 nodes are available: 2 node(s) didn't match Pod's node affinity/selector. preemption: 0/2 nodes are available: 2 Preemption is not helpful for scheduling.
    12m (x2 over 18m) Warning         FailedScaleUp           cluster-autoscaler       Node scale up in zones us-central1-f associated with this pod failed: GCE out of resources. Pod is at risk of not being scheduled.
    34s (x3 over 17m) Warning         FailedScaleUp           cluster-autoscaler       Node scale up in zones us-central1-b associated with this pod failed: GCE out of resources. Pod is at risk of not being scheduled.
    

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

  • Pod を別のリージョンまたはゾーンにデプロイします。Pod にトポロジ セレクタなどのゾーン制限がある場合は、可能であれば制限を解除します。手順については、GKE Pod を特定のゾーンに配置するをご覧ください。
  • 別のリージョンにクラスタを作成して、デプロイを再試行します。
  • 別のコンピューティング クラスを使用してみます。小さい Compute Engine マシンタイプを基盤とするコンピューティング クラスは、利用可能なリソースが多い傾向があります。たとえば、Autopilot のデフォルトのマシンタイプは可用性が最も高くなります。コンピューティング クラスと対応するマシンタイプのリストについては、特定のコンピューティング クラスを使用するタイミングをご覧ください。
  • GPU ワークロードを実行する場合、リクエストされた GPU がノードのロケーションで使用できないことがあります。ワークロードを別の場所にデプロイするか、別のタイプの GPU をリクエストしてください。

将来のリソースの可用性によるスケールアップの問題を回避するには、次の方法を検討してください。

ノードのスケールアップが失敗した: Pod のゾーンリソース超過

次の問題は、新しいノードがリソース上限に違反するため、Autopilot が特定のゾーンの Pod に新しいノードをプロビジョニングしない場合に発生します。

ログのエラー メッセージは次のようになります。

    "napFailureReasons": [
            {
              "messageId": "no.scale.up.nap.pod.zonal.resources.exceeded",
              ...

このエラーは、ノードの自動プロビジョニングでゾーン内の Pod にノードグループがまったくプロビジョニングされなかった場合の noScaleUp イベントを示しています。

このエラーが発生した場合は、次の点を確認してください。

ワークロードに関する問題

エフェメラル ストレージ エラーでワークロードが停止する

GKE バージョン 1.28.6-gke.1317000 以降では、Pod エフェメラル ストレージ リクエストが Autopilot の最大値である 10 GiB を超えると、GKE は Pod を作成しません。

この問題を診断するには、Deployment や Job などのワークロード コントローラの説明を取得します。

kubectl describe CONTROLLER_TYPE/CONTROLLER_NAME

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

  • CONTROLLER_TYPE: ワークロード コントローラのタイプ(replicasetdaemonset など)。コントローラ タイプの一覧については、ワークロード管理をご覧ください。
  • CONTROLLER_NAME: 停止したワークロードの名前。

エフェメラル ストレージ リクエストが最大値を超えているために Pod が作成されなかった場合、出力は次のようになります。

# lines omitted for clarity

Events:

{"[denied by autogke-pod-limit-constraints]":["Max ephemeral-storage requested by init containers for workload '' is higher than the Autopilot maximum of '10Gi'.","Total ephemeral-storage requested by containers for workload '' is higher than the Autopilot maximum of '10Gi'."]}

この問題を解決するには、ワークロード コンテナと Webhook が挿入するコンテナによってリクエストされるエフェメラル ストレージの合計が許容される最大値以下になるように、エフェメラル ストレージ リクエストを更新します。上限の詳細については、ワークロード構成の Autopilot のリソース リクエストをご覧ください。

Pod が Pending 状態から動かなくなる

Pod が使用するノードを具体的に選択した場合に、ノードで実行する必要がある Pod と DaemonSet のリソース リクエストの合計が、ノードに割り当て可能な最大容量を超えると、Pod が Pending ステータスで停止することがあります。これにより、Pod が Pending ステータスになり、スケジュール設定されないままになる可能性があります。

この問題を回避するには、デプロイしたワークロードのサイズを評価して、サポートされる Autopilot の最大リソース リクエストの範囲内であることを確認します。

通常のワークロード Pod をスケジュールする前に DaemonSet のスケジュールを設定してみることもできます。

特定のノードにおける一貫して信頼性の低いいワークロード パフォーマンス

GKE バージョン 1.24 以降では、特定のノード上のワークロードで中断、クラッシュ、またはそれと同様の信頼性の低い動作が繰り返し発生する場合は、次のコマンドでノードを閉鎖して、GKE に問題のあるノードを通知できます。

kubectl drain NODE_NAME --ignore-daemonsets

NODE_NAME は、問題のあるノードの名前に置き換えます。ノード名を確認するには、kubectl get nodes を実行します。

GKE は次の処理を行います。

  • ノードから既存のワークロードを強制排除し、そのノードでワークロードのスケジュール設定を停止します。
  • 他のノード上の Deployment や StatefulSet などのコントローラによって管理されている、強制排除されたワークロードを自動的に再作成します。
  • ノードに残っているワークロードを終了し、時間をかけてノードを修復または再作成します。
  • Autopilot を使用する場合、GKE はノードを直ちにシャットダウンして置き換え、構成済みの PodDisruptionBudgets を無視します。

空のクラスタでの Pod のスケジュールに想定よりも時間がかかる

このイベントは、他のワークロードがない Autopilot クラスタにワークロードをデプロイする場合に発生します。Autopilot クラスタは、使用可能なノードがゼロノードから始まり、クラスタが空の場合はゼロノードにスケーリングされるため、クラスタ内に未使用のコンピューティング リソースが存在することを回避できます。ノードがゼロのクラスタにワークロードをデプロイすると、スケールアップ イベントがトリガーされます。

これが発生した場合、Autopilot は意図したとおりに機能しているため、対応は必要ありません。新しいノードの起動後に、ワークロードが想定どおりにデプロイされます。

Pod が新しいノードを待機しているかどうかを確認します。

  1. 保留中の Pod を記述します。

    kubectl describe pod POD_NAME
    

    POD_NAME を保留中の Pod の名前に置き換えます。

  2. 出力の Events セクションを確認します。Pod が新しいノードを待機している場合、出力は次のようになります。

    Events:
      Type     Reason            Age   From                                   Message
      ----     ------            ----  ----                                   -------
      Warning  FailedScheduling  11s   gke.io/optimize-utilization-scheduler  no nodes available to schedule pods
      Normal   TriggeredScaleUp  4s    cluster-autoscaler                     pod triggered scale-up: [{https://www.googleapis.com/compute/v1/projects/example-project/zones/example-zone/instanceGroups/gk3-example-cluster-pool-2-9293c6db-grp 0->1 (max: 1000)} {https://www.googleapis.com/compute/v1/projects/example-project/zones/example-zone/instanceGroups/gk3-example-cluster-pool-2-d99371e7-grp 0->1 (max: 1000)}]
    

    TriggeredScaleUp イベントは、クラスタがゼロノードから、デプロイされたワークロードの実行に必要なノード数までスケールアップしていることを示します。

空のクラスタでシステム Pod のスケジュールが設定されない

このイベントは、クラスタで独自のワークロードが実行されていない場合に発生し、クラスタがゼロノードにスケールダウンします。Autopilot クラスタは、使用可能なノードがゼロノードから始まり、クラスタでワークロードを実行していない場合はゼロノードにスケールダウンされます。この動作により、クラスタ内のコンピューティング リソースの浪費を最小限に抑えることができます。

クラスタが 0 ノードにスケールダウンすると、GKE システム ワークロードはスケジュールされず、Pending 状態のままになります。これは想定された動作であり、対応は必要ありません。次回クラスタにワークロードをデプロイすると、GKE はクラスタをスケールアップし、保留中のシステム Pod がこれらのノードで実行されます。

空のクラスタが原因でシステム Pod が保留中かどうかを確認するには、次の操作を行います。

  1. クラスタにノードが存在するかどうかを確認します。

    kubectl get nodes
    

    出力は次のようになります。これは、クラスタにノードがないことを示しています。

    No resources found
    
  2. システム Pod のステータスを確認します。

    kubectl get pods --namespace=kube-system
    

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

    NAME                                                       READY   STATUS    RESTARTS   AGE
    antrea-controller-horizontal-autoscaler-6d97f7cf7c-ngfd2   0/1     Pending   0          9d
    egress-nat-controller-84bc985778-6jcwl                     0/1     Pending   0          9d
    event-exporter-gke-5c5b457d58-7njv7                        0/2     Pending   0          3d5h
    event-exporter-gke-6cd5c599c6-bn665                        0/2     Pending   0          9d
    konnectivity-agent-694b68fb7f-gws8j                        0/2     Pending   0          3d5h
    konnectivity-agent-7d659bf64d-lp4kt                        0/2     Pending   0          9d
    konnectivity-agent-7d659bf64d-rkrw2                        0/2     Pending   0          9d
    konnectivity-agent-autoscaler-5b6ff64fcd-wn7fw             0/1     Pending   0          9d
    konnectivity-agent-autoscaler-cc5bd5684-tgtwp              0/1     Pending   0          3d5h
    kube-dns-65ccc769cc-5q5q7                                  0/5     Pending   0          3d5h
    kube-dns-7f7cdb9b75-qkq4l                                  0/5     Pending   0          9d
    kube-dns-7f7cdb9b75-skrx4                                  0/5     Pending   0          9d
    kube-dns-autoscaler-6ffdbff798-vhvkg                       0/1     Pending   0          9d
    kube-dns-autoscaler-8b7698c76-mgcx8                        0/1     Pending   0          3d5h
    l7-default-backend-87b58b54c-x5q7f                         0/1     Pending   0          9d
    metrics-server-v1.31.0-769c5b4896-t5jjr                    0/1     Pending   0          9d
    
  3. システム Pod のステータスが Pending である理由を確認します。

    kubectl describe pod --namespace=kube-system SYSTEM_POD_NAME
    

    SYSTEM_POD_NAME は、前のコマンドの出力にある任意のシステム Pod の名前に置き換えます。

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

    ...
    Events:
    Type     Reason            Age                       From               Message
    ----     ------            ----                      ----               -------
    Warning  FailedScheduling  4m35s (x27935 over 3d5h)  default-scheduler  no nodes available to schedule pods
    ...
    

    出力の FailedScheduling イベントの Message フィールドの no nodes available to schedule pods 値は、クラスタが空であるためシステム Pod がスケジュールされなかったことを示します。

GKE Autopilot クラスタでは、基盤となるノードへのアクセスは禁止されています。したがって、Pod 内から tcpdump ユーティリティを実行し、kubectl cp コマンドを使用してコピーする必要があります。通常、GKE Autopilot クラスタ内の Pod から tcpdump ユーティリティを実行すると、次のエラーが表示されることがあります。

    tcpdump: eth0: You don't have permission to perform this capture on that device
    (socket: Operation not permitted)

これは、GKE Autopilot がデフォルトで、潜在的な脆弱性を軽減するために NET_RAW 機能を破棄するセキュリティ コンテキストをすべての Pod に適用するためです。例:

apiVersion: v1
kind: Pod
metadata:
  labels:
    app: tcpdump
  name: tcpdump
spec:
  containers:
  - image: nginx
    name: nginx
    resources:
      limits:
        cpu: 500m
        ephemeral-storage: 1Gi
        memory: 2Gi
      requests:
        cpu: 500m
        ephemeral-storage: 1Gi
        memory: 2Gi
    securityContext:
      capabilities:
        drop:
        - NET_RAW

ワークロードで NET_RAW 機能を必要とする場合は、次の方法で再度有効にできます。

  1. Pod の YAML 仕様の securityContext セクションに NET_RAW 機能を追加します。

    securityContext:
      capabilities:
        add:
        - NET_RAW
    
  2. Pod 内から tcpdump を実行します。

    tcpdump port 53 -w packetcap.pcap
    tcpdump: listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
    
  3. kubectl cp コマンドを使用してローカルマシンにコピーし、詳細な分析を行います。

    kubectl cp POD_NAME:/PATH_TO_FILE/FILE_NAME/PATH_TO_FILE/FILE_NAME
    
  4. kubectl exec を使用して tcpdump コマンドを実行し、ネットワーク パケット キャプチャを実行して出力をリダイレクトします。

    kubectl exec -it POD_NAME -- bash -c "tcpdump port 53 -w -" > packet-new.pcap
    

次のステップ

さらにサポートが必要な場合は、Cloud カスタマーケアにお問い合わせください。