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

このページでは、Google Cloud コンソール、Google Cloud CLI、kubectlを使用し、Connect Gateway を介してクラスタをフリートに登録する際、または Google Cloud の外側にあるクラスタに接続する際によく見られるエラーをトラブルシューティングする方法について説明します。

オンプレミス クラスタと他のパブリック クラウドのクラスタは、Connect Agent を使用して、クラスタと Google Cloud プロジェクト間の接続を確立して維持し、Kubernetes リクエストを処理します。「接続できないエージェント」や「クラスタのコントロール プレーンに接続できない」などのエラーが表示される場合は、Connect Agent に問題がある可能性があります。

Connect Agent のログの収集

Google Cloud の外部のクラスタを登録する際、Google Cloud は Connect Agent を使用してクラスタとフリートホスト プロジェクト間の通信を処理します。Connect Agent は Deployment gke-connect-agent で、通常は、クラスタの gke-connect 名前空間にインストールされます。この Connect Agent からログを収集すると、登録と接続に関する問題のトラブルシューティングに役立ちます。

エージェントのログを取得するには、次のコマンドを実行します(必要に応じて行数を調整します)。

kubectl logs -n gke-connect -l app=gke-connect-agent --tail=-1

プロジェクト クラスタで実行中のすべての Connect Agent に関する情報を取得するには、次のコマンドを実行します。

kubectl describe deployment --all-namespaces -l app=gke-connect-agent

接続が成功すると、次の例のようなエントリが表示されます。

2019/02/16 17:28:43.312056 dialer.go:244: dialer: dial: connected to gkeconnect.googleapis.com:443
2019/02/16 17:28:43.312279 tunnel.go:234: serve: opening egress stream...
2019/02/16 17:28:43.312439 tunnel.go:248: serve: registering endpoint="442223602236", shard="88d2bca5-f40a-11e8-983e-42010a8000b2" {"Params":{"GkeConnect":{"endpoint_class":1,"metadata":{"Metadata":{"Default":{"manifest_version":"234227867"}}}}}} ...
2019/02/16 17:28:43.312656 tunnel.go:259: serve: serving requests...

GKE Identity Service のログの収集

Connect Gateway の Google グループまたはサードパーティのサポートに問題がある場合は、GKE Identity Service のログを調べると役立つことがあります。このログ生成方法は、VMware 上の GKE またはベアメタル クラスタ用の Google Distributed Cloud Virtual にのみ適用されます。

  1. GKE Identity Service のログの詳細度を高めるには、次のコマンドを使用して clientconfig カスタム リソースを編集します。

    kubectl edit deployment -n anthos-identity-service
    

    containers フィールドの下に vmodule フラグを追加します。

    spec:
      containers:
      ...
      - command:
        - --vmodule=cloud/identity/hybrid/charon/*=9
    
  2. 次のコマンドを使用して GKE Identity Service Pod を削除し、再起動します。

    kubectl delete pods -l k8s-app=ais -n anthos-identity-service
    

    数秒以内に Pod が再び起動します。

  3. Pod が再起動したら、予期しないレスポンスが返された元のコマンドを実行して、GKE Identity Service Pod ログに詳細情報を入力します。

  4. 次のコマンドを使用して、これらのログの出力をファイルに保存します。

    kubectl logs -l k8s-app=ais -n anthos-identity-service --tail=-1 > gke_id_service_logs.txt
    

想定されるグループが GKE Identity Service Pod のログにない場合は、クラスタの設定が正しいことを確認します。GKE Identity Service に関連するその他の問題がある場合は、ユーザー アクセスの問題のトラブルシューティングまたはフリートレベルの設定に関する問題のトラブルシューティングをご覧ください。

tls: oversized record エラー

症状

次ようなエラーが発生する場合があります。

... dialer: dial: connection to gkeconnect.googleapis.com:443 failed after
388.080605ms: serve: egress call failed: rpc error: code = Unauthenticated
desc = transport: oauth2: cannot fetch token: Post
https://oauth2.googleapis.com/token: proxyconnect tcp: tls: oversized record
received with length 20527
考えられる原因

Connect Agent が HTTP のみのプロキシに、HTTPS で接続しようとしている可能性があります。Connect Agent は CONNECT ベースの HTTP プロキシのみをサポートします。

解決策

プロキシの環境変数を次のように再構成する必要があります。

http_proxy=http://[PROXY_URL]:[PROXY_PORT]
https_proxy=http://[PROXY_URL]:[PROXY_PORT]

oauth2: cannot fetch token エラー

症状

次ようなエラーが発生する場合があります。

...  dialer: dial: connection to gkeconnect.googleapis.com:443 failed
after 388.080605ms: serve: egress call failed: rpc error: code =
Unauthenticated desc = transport: oauth2: cannot fetch token: Post
https://oauth2.googleapis.com/token: read tcp 192.168.1.40:5570->1.1.1.1:80
read: connection reset by peer
考えられる原因

アップストリームの HTTP プロキシが接続をリセットした可能性があります。おそらく、この特定の URL が HTTP プロキシで許可されていないためです。上記の例では、1.1.1.1:80 が HTTP プロキシ アドレスです。

解決策

HTTP プロキシの許可リストに次の URL とドメインが含まれていることを確認してください。

gkeconnect.googleapis.com
oauth2.googleapis.com/token
www.googleapis.com/oauth2/v1/certs

Connect Agent Pod がクラッシュして再起動エラーが発生する

症状

Google Cloud コンソールでクラスタに関する「接続できないエージェント」エラーが断続的に発生する場合や、Pod が複数回再起動する場合があります。

$ kubectl get pods -n gke-connect
NAME                                                READY   STATUS    RESTARTS   AGE
gke-connect-agent-20230706-03-00-6b8f75dd58-dzwmt   1/1     Running   5          99m

この動作をトラブルシューティングするには、最後の状態がメモリ不足エラー(OOMKilled)による終了だったかどうかを確認するよう Pod を記述します。

  kubectl describe pods/gke-connect-agent-20230706-03-00-6b8f75dd58-dzwmt -n gke-connect
        <some details skipped..>
        Last State:     Terminated
        Reason:       OOMKilled
考えられる原因
デフォルトでは、Connect Agent Pod の RAM の上限は 256 MiB です。クラスタで多くのワークロードがインストールされている場合、一部のリクエストとレスポンスを期待どおりに処理できない場合があります。
解決策

Connect Agent のデプロイメントを更新し、メモリの上限をより高く設定します。次に例を示します。

containers:
  name: gke-connect-agent-20230706-03-00
  resources:
    limits:
      memory: 512Mi

PermissionDenied エラー

症状

次ようなエラーが発生する場合があります。

tunnel.go:250: serve: recv error: rpc error: code = PermissionDenied
desc = The caller does not have permission
dialer.go:210: dialer: dial: connection to gkeconnect.googleapis.com:443
failed after 335.153278ms: serve: receive request failed: rpc error:
code = PermissionDenied desc = The caller does not have permission
dialer.go:150: dialer: connection done: serve: receive request failed:
rpc error: code = PermissionDenied desc = The caller does not have permission
dialer.go:228: dialer: backoff: 1m14.1376766s
考えられる原因

Connect Agent から Google への接続を承認するために作成した Google Cloud サービス アカウントに、必要な Identity and Access Management(IAM)ロールが割り当てられていない可能性があります。Google Cloud サービス アカウントには、gkehub.connect IAM ロールが必要です。

これは、Google Cloud サービス アカウントを削除して同じ名前で再作成する場合にも発生します。その場合は、IAM ロール バインディングを削除して再作成する必要もあります。詳細については、サービス アカウントの削除と再作成をご覧ください。

解決策

サービス アカウントに gkehub.connect ロールをバインドします(gkehub.admin ロールには接続のための適切な権限が付与されておらず、サービス アカウントによる使用を想定していません)。

たとえば、my-project という名前のプロジェクトと gkeconnect@my-project.iam.gserviceaccount.com という Google Cloud サービス アカウントの場合は、次のコマンドを実行してロールをサービス アカウントにバインドします。

gcloud projects add-iam-policy-binding my-project --member \
serviceAccount:gkeconnect@my-project.iam.gserviceaccount.com \
--role "roles/gkehub.connect"

次のコマンドの出力を調べることで、Google Cloud サービス アカウントにサービス アカウントの権限が適用されていることを表示して確認できます。また、role: roles/gkehub.connect が関連付けられた Google Cloud のサービス アカウントにバインドされていることがわかります。

gcloud projects get-iam-policy my-project

IAM ロールを Google Cloud サービス アカウントにバインドするときにエラーが発生する

症状

次ようなエラーが発生する場合があります。

ERROR: (gcloud.projects.add-iam-policy-binding) PERMISSION_DENIED:
Service Management API has not been used in project [PROJECT_ID] before or it
is disabled. Enable it by visiting
https://console.developers.google.com/apis/api/servicemanagement.googleapis.com/overview?project=[PROJECT_ID]
then retry. If you enabled this API recently, wait a few minutes for the
action to propagate to our systems and retry.
考えられる原因

コマンド gcloud projects add-iam-policy-binding を実行するための IAM 権限を付与されていない可能性があります。

解決策

resourcemanager.projects.setIamPolicy 権限を付与されていることが必要です。Project IAM AdminOwnerEditor のいずれかのロールを割り当てられている場合は、コマンドを実行できます。内部セキュリティ ポリシーにより、コマンドの実行が禁止されている場合は、管理者に確認してください。

無効なサービス アカウント キーからエラーが返される

症状

次ようなエラーが発生する場合があります。

2020/05/08 01:22:21.435104 environment.go:214: Got ExternalID 3770f509-b89b-48c4-96e0-860bb70b3a58 from namespace kube-system.
2020/05/08 01:22:21.437976 environment.go:485: Using gcp Service Account key
2020/05/08 01:22:21.438140 gkeconnect_agent.go:50: error creating kubernetes connect agent: failed to get tunnel config: unexpected end of JSON input
考えられる原因

これらのログは、インストール時に Connect Agent に無効なサービス アカウント キーが指定されたことを示しています。

解決策

サービス アカウントの認証情報が含まれている JSON ファイルを新規に作成し、手順に沿って再度クラスタを登録して、Connect Agent を再インストールします。

期限切れのサービス アカウント キーからエラーが返される

症状

次ようなエラーが発生する場合があります。

2020/05/08 01:22:21.435104 dialer.go:277: dialer: dial: connection to gkeconnect.googleapis.com:443 failed after 37.901608ms:
serve: egress call failed: rpc error: code = Unauthenticated desc = transport: oauth2: cannot fetch token: 400 Bad Request
Response: {"error":"invalid_grant","error_description":"Invalid JWT Signature."}
考えられる原因

これらのログは、Connect Agent が Google の認証サービスでは使用できない、問題のあるサービス アカウント キーを使用して Connect に発信していたことを示しています。サービス アカウント キー ファイルが破損しているか、キーの有効期限が切れている可能性があります。

キーの有効期限が切れていることを確認するには、Google Cloud コンソールのサービス アカウントの詳細ページで「鍵の有効期限」を表示できます。デフォルトで、サービス アカウントの有効期間が短い特殊なポリシーが、プロジェクトまたは組織で設定されている場合もあります。

解決策

サービス アカウントの認証情報が含まれている JSON ファイルを新規に作成し、手順に沿って再度クラスタを登録して、Connect Agent を再インストールします。

システム クロックのずれによるエラー

症状

次ようなエラーが発生する場合があります。

acceptCall: failed to parse token in req [rpc_id=1]: Token used before issued [rpc_id=1]
考えられる原因

通常、このログ メッセージはクラスタで時計のずれが生じていることを示しています。クラスタが発行したトークンに同期のずれたタイムスタンプがあるため、トークンが拒否されます。

解決策

時計が正しく同期されていないことを確認するには、クラスタで date コマンドを実行して、標準時間と比較することができます。通常は、数秒のドリフトがあるとこの問題が発生します。この問題を解決するには、クラスタの時計を再同期してください。

Google Cloud コンソールでワークロードを確認できない

症状

Connect Agent のログに、以下のエラーが記録される場合があります。

"https://10.0.10.6:443/api/v1/nodes" YYYY-MM-DDTHH mm:ss.sssZ http.go:86: GET
"https://10.0.10.6:443/api/v1/pods" YYYY-MM-DDTHH mm:ss.sssZ http.go:139:
Response status: "403 Forbidden" YYYY-MM-DDTHH mm:ss.sssZ http.go:139:
Response status: "403 Forbidden"`
考えられる原因

これらのログは、登録時に指定した認証情報を使用して Google Cloud がクラスタにアクセスしようとしたことを示しています。403 エラーは、クラスタへのアクセスに必要な権限が認証情報にないことを表します。

解決策

トークンとそのトークンがバインドされているアカウントを確認し、クラスタに対する適切な権限があることを確認します。

コンテキストの期限を超過している

症状

次ようなエラーが発生する場合があります。

2019/03/06 21:08:43.306625 dialer.go:235: dialer: dial: connecting to gkeconnect.googleapis.com:443...
2019/03/06 21:09:13.306893 dialer.go:240: dialer: dial: unable to connect to gkeconnect.googleapis.com:443: context deadline exceeded
2019/03/06 21:09:13.306943 dialer.go:183: dialer: connection done: context deadline exceeded
考えられる原因

このエラーは低レベルの TCP ネットワーキングの問題で、Connect Agent が gkeconnect.googleapis.com と通信できないことを示しています。

解決策

このクラスタ内の Pod ワークロードが、gkeconnect.googleapis.com を解決し、ポート 443 でアウトバウンド接続を行っていることを確認します。

エージェントの接続が断続的に失敗する

症状

Connect Agent のログに、以下のエラーが記録される場合があります。

2020/10/06 18:02:34.409749 dialer.go:277: dialer: dial: connection to gkeconnect.googleapis.com:443 failed after 8m0.790286282s: serve: receive request failed: rpc error: code = Unavailable desc = transport is closing
2020/10/06 18:02:34.416618 dialer.go:207: dialer: connection done: serve: receive request failed: rpc error: code = Unavailable desc = transport is closing
2020/10/06 18:02:34.416722 dialer.go:295: dialer: backoff: 978.11948ms
2020/10/06 18:02:34.410097 tunnel.go:651: sendResponse: EOF [rpc_id=52]
2020/10/06 18:02:34.420077 tunnel.go:651: sendResponse: EOF [rpc_id=52]
2020/10/06 18:02:34.420204 tunnel.go:670: sendHalfClose: EOF [rpc_id=52]
2020/10/06 18:02:34.401412 tunnel.go:670: sendHalfClose: EOF [rpc_id=53]
考えられる原因

Connect Agent のリソースが不足している(t3.medium のような小規模な AWS EC2 インスタンスなど)場合に、Connect への接続が終了します。

解決策

AWS と T3 インスタンス タイプを使用する場合は、T3 無制限を有効にするか、ノードプールに対してより多くのリソースを利用できるインスタンス タイプを使用します。

フリートがプロジェクトにアクセスできない

症状

一部のフリート オペレーション(通常はクラスタ登録)中に、次のようなエラーが発生する場合があります。

ERROR: (gcloud.container.hub.memberships.register) failed to initialize Feature
"authorizer", the fleet service account (service-PROJECT_NUMBER@gcp-sa-gkehub.iam.gserviceaccount.com) may not have access to your project
考えられる原因

GKE のデフォルトのサービス アカウント(gcp-sa-gkehub)が、プロジェクトから誤ってバインド解除されることがあります。フリート サービス エージェントは、クラスタ リソースを管理する権限をサービス アカウントに付与する IAM ロールです。このロール バインディングをサービス アカウントから削除すると、デフォルト サービス アカウントはプロジェクトからバインド解除され、アプリケーションのデプロイや他のクラスタ操作をユーザーができなくなる可能性があります。

gcloud CLI または Google Cloud コンソールを使用して、サービス アカウントがプロジェクトから削除されているか確認できます。コマンドまたはダッシュボードで、サービス アカウントの中に gcp-sa-gkehub が表示されない場合、サービス アカウントのバインドは解除されています。

gcloud

次のコマンドを実行します。

gcloud projects get-iam-policy PROJECT_NAME

PROJECT_NAME はクラスタの登録を試行するプロジェクトの名前です。

コンソール

Google Cloud コンソールで [IAM と管理] ページにアクセスします。

解決策

フリート サービス エージェントのロール バインディングを削除した場合は、次のコマンドを実行してロール バインディングを復元します。

PROJECT_NUMBER=$(gcloud projects describe PROJECT_NAME --format "value(projectNumber)")
gcloud projects add-iam-policy-binding PROJECT_NAME \
  --member "serviceAccount:service-${PROJECT_NUMBER}@gcp-sa-gkehub.iam.gserviceaccount.com" \
  --role roles/gkehub.serviceAgent

ロール バインディングが付与されたことを確認するには、次のコマンドを実行します。

gcloud projects get-iam-policy PROJECT_NAME

サービス アカウント名と gkehub.serviceAgent 役割が表示されている場合、役割バインディングが付与されています。例:

- members:
  - serviceAccount:service-1234567890@gcp-sa-gkehub.iam.gserviceaccount.com
  role: roles/gkehub.serviceAgent

フリートとは別のプロジェクトの GKE クラスタを登録する際にエラーが発生する

症状

フリート プロジェクトとは別のプロジェクトの GKE クラスタを登録する際に、gcloud CLI で次のようなエラーが発生する場合があります。

...
message: 'DeployPatch failed'>
detail: 'DeployPatch failed'
...

ログで確認するには、次のフィルタを適用します。

resource.type="gke_cluster"
resource.labels.cluster_name="my-cluster"
protoPayload.methodName="google.container.v1beta1.ClusterManager.UpdateCluster"
protoPayload.status.code="13"
protoPayload.status.message="Internal error."
severity=ERROR

考えられる原因

フリートのデフォルトのサービス アカウントに、GKE クラスタのプロジェクトで必要な権限が付与されていません。

解決策

クラスタを登録する前に、フリートのデフォルトのサービス アカウントに必要な権限を付与します。

認証情報のローテーション時に、GKE クラスタの登録または登録解除や、登録済みの GKE クラスタのフリート メンバーシップの詳細の更新でエラーが発生する

症状

クラスタ認証情報のローテーション(https://cloud.google.com/kubernetes-engine/docs/how-to/credential-rotation)中に、GKE クラスタの登録や登録解除、または登録済みの GKE クラスタのメンバーシップの更新を行うと、エラーが発生することがあります。

ERROR: (gcloud.container.hub.memberships.unregister) "code": 13,
"message": "an internal error has occurred"
考えられる原因

クラスタ認証情報は中間状態にあり、フリート サービスが認証情報にアクセスできません。

解決策

クラスタの登録や登録解除、または登録済みの GKE クラスタのメンバーシップの更新の前に、ローテーションを完了します。

Fleet API を無効にする際にエラーが発生する

症状

Fleet API(gkehub.googleapis.com)を無効にしようとすると、次のようなエラーが発生する場合があります。

Not ready to deactivate the service on this project; ensure there are no more resources managed by this service.
考えられる原因

このプロジェクトには、まだ Google Cloud(メンバーシップ)に登録されているクラスタがあるか、フリートレベルの機能が有効になっています。API を無効にする前に、すべてのメンバーや機能を、登録解除するか無効にする必要があります。

  • 現在の登録済みクラスタを表示するには、フリート メンバーの表示の手順に沿って操作します。

  • プロジェクトでアクティブなフリートレベルの機能をすべて表示するには、次のコマンドを実行します。

gcloud および cURL

$ curl -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    https://gkehub.googleapis.com/v1alpha1/projects/PROJECT_NAME/locations/global/features

PROJECT_NAME は Fleet API を無効化するプロジェクトの名前です。

コンソール

プロジェクトで GKE Enterprise を有効にしている場合は、Google Cloud コンソールの機能の概要ページにアクセスします。[有効] と表示されている機能は、アクティブなフリートレベルの機能です。

解決策

最初に、プロジェクト フリートにまだ登録されているクラスタを登録解除します。なんらかの機能を無効にするには、その前にすべてのクラスタの登録を解除する必要があります。

この手順を完了したら、フリートレベルの機能をすべて無効にします。現在、この操作は Fleet REST API でのみ行えます。

  1. プロジェクトに対して有効にしたフリートレベルの機能を無効にする

    $ gcloud alpha container hub FEATURE_COMMAND disable
    
  2. デフォルトで有効になっている Feature Authorizer と測定を無効にします。

    $ curl -H "Authorization: Bearer $(gcloud auth print-access-token)" \
        -X "DELETE" \
        https://gkehub.googleapis.com/v1alpha1/projects/PROJECT_NAME/locations/global/features/FEATURE
    

    FEATURE は無効にする機能の名前です(authorizermetering など)。

クラスタを登録する際にクラスタに関する権限がない

症状:

ユーザー アカウントや Google Cloud サービス アカウントでクラスタを登録しようとすると、次のようなエラーが発生することがあります。

ERROR: (gcloud.container.hub.memberships.register) ResponseError: code=403, message=Required "container.clusters.get" permission(s) for "projects/my-project/zones/zone-a/clusters/my-cluster"
考えられる原因:

クラスタを登録しようとしているアカウントに、クラスタに必要な cluster-admin ロールベース アクセス制御(RBAC)のロールがありません。

解決策:

クラスタを登録する前に、アカウントに cluster-admin RBAC ロールを付与します

クラスタの登録時に Failed to check if the user is a cluster-admin: Unable to connect to the server エラーが発生する

症状:

クラスタを登録しようとすると、次のようなエラーが発生することがあります。

ERROR: (gcloud.container.hub.memberships.register) Failed to check if the user is a cluster-admin: Unable to connect to the server: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)

または

ERROR: (gcloud.container.hub.memberships.register) Failed to check if the user is a cluster-admin: Unable to connect to the server: dial tcp MASTER_ENDPOINT_IP:443: i/o timeout
考えられる原因:

gcloud 登録コマンドを実行しているマシンが、クラスタの外部エンドポイントに接続できません。このエラーは通常、外部アクセスや外部 IP が無効になっている限定公開クラスタを使用しているが、マシンの外部 IP アドレスが許可リストに登録されていない場合に発生します。gcloud 407.0.0 以降では、GKE クラスタの登録にはこのような要件がないことに注意してください。

解決策:

gcloud 登録コマンドを実行するマシンが、クラスタの API サーバーにアクセスできることを確認します。クラスタで外部アクセスが有効になっていない場合は、Google Cloud サポートにご連絡ください

追加の支援を受ける

Google Cloud サポートで GKE Enterprise のチケットを作成する手順は、次のとおりです。

  1. Google Cloud サポートにサポートケースを送信します。
  2. Connect Agent ログの収集の手順に沿って、GKE Connect ログを保存します。
  3. Google グループまたはサードパーティ サポートを使用して GKE on VMware または Google Distributed Cloud Virtual for Bare Metal クラスタのトラブルシューティングを行う場合は、GKE Identity Service のログを収集するの手順に沿って GKE Identity Service のログを保存します。必要に応じて、保存したファイル内の Pod ログをサニタイズしてください。
  4. 関連するログをケースに添付します。