本页介绍如何排查在将集群注册到舰队或使用 Google Cloud 控制台、Google Cloud CLI 或 kubectl
通过 Connect Gateway 连接到 Google Cloud 外部的集群时可能遇到的常见错误。
本地集群和其他公有云上的集群依赖于 Connect Agent 在集群和 Google Cloud 项目之间建立和维护连接,以及处理 Kubernetes 请求。如果您看到“无法访问代理”或“无法连接到集群的控制平面”等错误,这可能表明 Connect Agent 存在问题。
收集 Connect Agent 日志
当您在 Google Cloud 外部注册集群时,它会使用 Connect Agent 来处理您的集群和舰队宿主项目之间的通信。Connect Agent 是一个 Deployment (gke-connect-agent
),通常安装在集群的 gke-connect
命名空间中。从此 Connect Agent 收集日志有助于排查注册和连接问题。
您可以通过运行以下命令来检索 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 网关的 Google 群组或第三方支持方面遇到问题,检查 GKE Identity Service 日志可能会很有帮助。这种生成日志的方法仅适用于 VMware 或 Bare Metal 上的 Google Distributed Cloud 部署中的集群。
可提高 GKE Identity Service 日志的详细程度,具体方法是使用以下命令修改 clientconfig 自定义资源:
kubectl edit deployment -n anthos-identity-service
并在
containers
字段下添加vmodule
标志,如下所示:spec: containers: ... - command: - --vmodule=cloud/identity/hybrid/charon/*=9
可使用以下命令删除 GKE Identity Service Pod,以进行重启:
kubectl delete pods -l k8s-app=ais -n anthos-identity-service
Pod 应在几秒钟内再次启动。
Pod 重启后,运行返回非预期响应的原始命令,以使用更多详细信息填充 GKE Identity Service Pod 日志。
可使用以下命令将这些日志的输出保存到文件中:
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 尝试通过 HTTPS 连接到仅限 HTTP 的代理。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 代理重置了连接,这很可能是因为您的 HTTP 代理不允许使用此特定网址。在上面的示例中,1.1.1.1:80 是 HTTP 代理地址。
- 解决方法
检查您的 HTTP 代理许可名单是否包含以下网址/域名:
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
如需排查此行为,请描述 Pod 以查看其上一个状态是否因内存不足错误 (OOMKilled) 而终止:
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 限制为 256MiB。如果集群已安装大量工作负载,则某些请求和响应可能无法按预期处理。
- 解决方法
更新 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
- 可能的原因
这可能意味着您尚未将必需的 Identity and Access Management (IAM) 角色绑定到您创建的 Google Cloud 服务账号以授权 Connect Agent 连接到 Google。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 Admin
、Owner
或Editor
角色,则应该可以运行该命令。如果内部安全政策禁止您运行该命令,请咨询您的管理员。
服务账号密钥无效导致错误
- 症状
您可能会遇到类似这样的错误:
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 正在使用无效的服务账号密钥对 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
- 可能的原因
此错误表明 Connect Agent 无法与 gkeconnect.googleapis.com 通信的低级 TCP 网络问题。
- 解决方法
验证此集群中的 Pod 工作负载是否可以解析,以及连到端口 443 和 443 的出站连接。
Agent 连接间歇性故障
- 表现
在 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 的连接就会关闭。- 解决方法
Fleet 无法访问项目
- 表现
在执行某些 Fleet 操作(通常是集群注册)期间,您可能会观察到类似于以下内容的错误:
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
- 可能的原因
Fleet 的默认服务账号
gcp-sa-gkehub
可能会意外地从项目中解除绑定。Fleet Service Agent 是一种 IAM 角色,它授予服务账号管理集群资源的权限。如果从服务账号中移除此角色绑定,则默认服务账号将从项目中解除绑定,这可能会阻止您注册集群以及执行其他集群操作。您可以使用 gcloud CLI 或 Google Cloud 控制台检查服务账号是否已从项目中移除。如果命令或信息中心未针对服务账号显示
gcp-sa-gkehub
,则该服务账号已解除绑定。
gcloud
运行以下命令:
gcloud projects get-iam-policy PROJECT_NAME
其中,PROJECT_NAME
是您尝试在其中注册集群的项目的名称。
控制台
访问 Google Cloud 控制台中的 IAM 和管理页面。
- 解决方法
如果移除了 Fleet Service Agent 角色绑定,请运行以下命令以恢复角色绑定:
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
通过 Fleet 以外的项目注册 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
- 可能的原因
Fleet 默认服务账号在 GKE 集群项目中没有所需的权限。
- 解决方法
在注册集群之前,向 Fleet 默认服务账号授予所需的权限。
在凭据轮替期间注册/取消注册 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(成员)或 fleet 级层功能。必须先取消注册或者停用所有成员资格或功能,然后才能停用 API。
如需查看当前已注册的集群,请按照查看舰队成员中的说明进行操作
如需查看项目的所有活跃的舰队级层功能,请执行以下操作:
gcloud 和 cURL
$ curl -H "Authorization: Bearer $(gcloud auth print-access-token)" \
https://gkehub.googleapis.com/v1alpha/projects/PROJECT_NAME/locations/global/features
其中 PROJECT_NAME
是您要尝试在其中停用 Fleet API 的项目名称。
控制台
如果您在项目中启用了 GKE Enterprise,请访问 Google Cloud 控制台中的 Feature Manager 页面。列为已启用的功能属于活跃的舰队级功能。
- 解决方法
首先,取消注册任何集群(仍在您的项目舰队中注册的集群)。必须先取消注册所有集群,然后才能停用部分功能。
完成此操作后,将会停用所有舰队级功能。目前,只能通过 Fleet REST API 执行此操作。
停用您为项目启用的舰队级层功能
$ gcloud alpha container hub FEATURE_COMMAND disable
停用 Feature Authorizer 和计量功能(该功能默认处于启用状态)。
$ curl -H "Authorization: Bearer $(gcloud auth print-access-token)" \ -X "DELETE" \ https://gkehub.googleapis.com/v1alpha/projects/PROJECT_NAME/locations/global/features/FEATURE
其中
FEATURE
是要停用的功能的名称(例如authorizer
或metering
)。
注册集群时缺少集群权限
- 具体情况:
尝试使用用户账号或 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 支持服务工单:
- 向 Google Cloud 支持团队提交案例。
- 按照收集 Connect Agent 日志中的说明以保存 Connect 日志。
- 如果使用 Google 群组或第三方支持对本地集群进行问题排查,请按照收集 GKE Identity Service 日志中的说明保存 GKE Identity Service 日志。如有必要,请务必清理已保存文件中的 Pod 日志。
- 将相关日志关联到您的案例。