排查 4xx 错误


本页面可帮助您解决使用 Google Kubernetes Engine (GKE) 时可能遇到的 400、401、403 和 404 错误。

问题:身份验证和授权错误

连接到 GKE 集群时,您可能会收到 HTTP 状态代码为 401 (Unauthorized) 的身份验证和授权错误。如果您尝试在本地环境的 GKE 集群中运行 kubectl 命令,可能会遇到此问题。

此问题可能是由以下某种原因造成的:

  • gke-gcloud-auth-plugin 身份验证插件未正确安装或配置。
  • 您无权连接到集群 API 服务器和运行 kubectl 命令。

如需诊断原因,请完成以下部分中的步骤:

  1. 使用 curl 连接到集群
  2. 在 kubeconfig 中配置插件

使用 curl 连接到集群

如需诊断身份验证和授权错误的原因,请使用 curl 连接到集群。使用 curl 可绕过 kubectl 命令行工具和 gke-gcloud-auth-plugin 插件。

  1. 设置环境变量:

    APISERVER=https://$(gcloud container clusters describe CLUSTER_NAME \
        --location=COMPUTE_LOCATION --format "value(endpoint)")
    TOKEN=$(gcloud auth print-access-token)
    
  2. 验证您的访问令牌是否有效:

    curl https://oauth2.googleapis.com/tokeninfo?access_token=$TOKEN
    

    当您拥有有效的访问令牌时,此命令会向 Google 的 OAuth 2.0 服务器发送请求,而服务器会回复令牌相关信息。

  3. 尝试连接到 API 服务器中的核心 API 端点:

    # Get cluster CA certificate
    gcloud container clusters describe CLUSTER_NAME \
        --location=COMPUTE_LOCATION \
        --format "value(masterAuth.clusterCaCertificate)" | \
        base64 -d > /tmp/ca.crt
    
    # Make API call with authentication and CA certificate
    curl -s -X GET "${APISERVER}/api/v1/namespaces" \
        --header "Authorization: Bearer $TOKEN" \
        --cacert /tmp/ca.crt
    

    如果 curl 命令成功,您将看到命名空间列表。请继续使用在 kubeconfig 中配置插件部分中的步骤检查插件是否是原因。

    如果 curl 命令失败,并且输出类似于以下内容,则表示您没有正确的权限来访问集群:

    {
    "kind": "Status",
    "apiVersion": "v1",
    "metadata": {},
    "status": "Failure",
    "message": "Unauthorized",
    "reason": "Unauthorized",
    "code": 401
    }
    

    如需解决此问题,请咨询您的管理员,以获取正确的权限来访问集群。

在 kubeconfig 中配置插件的使用

如果您在连接到集群时收到身份验证和授权错误,但能够使用 curl 连接到集群,请确保您无需 gke-gcloud-auth-plugin 插件也可访问集群。

如需解决此问题,请将您的本地环境配置为在向集群进行身份验证时忽略 gke-gcloud-auth-plugin 二进制文件。在运行 1.25 及更高版本的 Kubernetes 客户端中,gke-gcloud-auth-plugin 二进制文件是必需的,因此您需要使用 1.24 或更低版本的 kubectl 命令行工具。

请按照以下步骤操作,以便在不需要插件的情况下访问集群:

  1. 使用 curl 安装 1.24 版或更低版本的 kubectl 命令行工具。以下示例安装的是 1.24 版的工具:

    curl -LO https://dl.k8s.io/release/v1.24.0/bin/linux/amd64/kubectl
    
  2. 在文本编辑器中打开 shell 启动脚本文件。例如,针对 Bash shell,打开 .bashrc

    vi ~/.bashrc
    

    如果您使用的是 macOS,请在这些说明中使用 ~/.bash_profile 而非 .bashrc

  3. 将以下代码行添加到启动脚本文件中,然后保存:

    export USE_GKE_GCLOUD_AUTH_PLUGIN=False
    
  4. 运行启动脚本:

    source ~/.bashrc
    
  5. 获取设置 .kube/config 文件的集群的凭据:

    gcloud container clusters get-credentials CLUSTER_NAME \
        --location=COMPUTE_LOCATION
    

    替换以下内容:

  6. 运行 kubectl 命令。例如:

    kubectl cluster-info
    

    如果您在运行这些命令后收到 401 错误或类似的授权错误,请确保您拥有正确的权限,然后重新运行返回错误的步骤。

错误 400:节点池需要重新创建

尝试执行重新创建控制平面和节点的操作时,可能会发生以下错误:

ERROR: (gcloud.container.clusters.update) ResponseError: code=400, message=Node pool "test-pool-1" requires recreation.

例如,当您完成正在进行的凭据变换时,可能会发生此错误。

在后端,节点池会标记为要进行重新创建,但实际的重新创建操作可能需要一些时间才能开始。因此,该操作会失败,因为 GKE 尚未重新创建集群中的一个或多个节点池。

如需解决此问题,请选择以下解决方案之一:

  • 等待重新创建进行。这可能需要几个小时、几天或几周的时间,具体取决于现有维护窗口和排除项等因素。
  • 通过启动与控制平面相同的版本升级,手动开始创建受影响的节点池。

    如需开始重新创建,请运行以下命令:

    gcloud container clusters upgrade CLUSTER_NAME \
        --node-pool=POOL_NAME
    

    升级完成后,请重试该操作。

错误 403:权限不足

当您尝试使用 gcloud container clusters get-credentials 连接到 GKE 集群,但该账号无权访问 Kubernetes API 服务器时,会发生以下错误:

ERROR: (gcloud.container.clusters.get-credentials) ResponseError: code=403, message=Required "container.clusters.get" permission(s) for "projects/<your-project>/locations/<region>/clusters/<your-cluster>".

如需解决此问题,请完成以下步骤:

  1. 确定存在访问权限问题的账号:

    gcloud auth list
    
  2. 按照向 Kubernetes API 服务器进行身份验证中的说明,向该账号授予所需的访问权限。

错误 403:重试预算用尽

在尝试创建 GKE 集群时,可能会出现以下错误:

Error: googleapi: Error 403: Retry budget exhausted: Google Compute Engine:
Required permission 'PERMISSION_NAME' for 'RESOURCE_NAME'.

在此错误消息中,以下变量适用:

  • PERMISSION_NAME:权限的名称,例如 compute.regions.get
  • RESOURCE_NAME:您尝试访问的 Google Cloud 资源的路径,例如 Compute Engine 区域。

如果附加到集群的 IAM 服务账号没有创建集群所需的最低权限,则会发生此错误。

如需解决此问题,请执行以下操作:

  1. 创建或修改 IAM 服务账号,以拥有运行 GKE 集群所需的所有权限。如需查看相关说明,请参阅使用最小权限 IAM 服务账号
  2. 使用 --service-account 标志在集群创建命令中指定更新后的 IAM 服务账号。如需查看相关说明,请参阅创建 Autopilot 集群

或者,省略 --service-account 标志,让 GKE 使用项目中的 Compute Engine 默认服务账号,该账号默认具有所需权限。

错误 404:找不到资源

如果您在调用 gcloud container 命令时收到错误 404(找不到资源),请通过重新对 Google Cloud CLI 进行身份验证来解决此问题:

gcloud auth login

错误 400/403:缺少账号的修改权限

缺少账号的修改权限错误(错误 400 或 403)表示以下任一项已被手动删除或修改:

启用 Compute Engine 或 Kubernetes Engine API 时,Google Cloud 会创建以下服务账号和代理:

  • 对您的项目具有修改权限的 Compute Engine 默认服务账号
  • 对您的项目具有修改权限的 Google API 服务代理
  • 在您的项目中具有 Kubernetes Engine Service Agent 角色的 Google Kubernetes Engine 服务账号

如果有人在任何时候修改了这些权限、移除了项目上的角色绑定、完全移除了服务账号或停用了 API,则集群创建和所有管理功能都将失败。

如需验证 Google Kubernetes Engine 服务账号是否已在项目中分配了 Kubernetes Engine Service Agent 角色,请完成以下步骤:

  1. 确定您的 Google Kubernetes Engine 服务账号的名称。所有服务账号都采用以下格式:

    service-PROJECT_NUMBER@container-engine-robot.iam.gserviceaccount.com
    

    PROJECT_NUMBER 替换为您的项目编号

  2. 验证您的 Google Kubernetes Engine 服务账号没有在项目中分配 Kubernetes Engine Service Agent 角色:

    gcloud projects get-iam-policy PROJECT_ID
    

    PROJECT_ID 替换为您的项目 ID。

要解决此问题,如果有人从您的 Google Kubernetes Engine 服务账号中移除了 Kubernetes Engine Service Agent 角色,请重新添加。否则,请按照以下说明重新启用 Kubernetes Engine API,以恢复您的服务账号和权限:

控制台

  1. 转到 Google Cloud 控制台中的 API 和服务页面。

    转到“API 和服务”

  2. 选择您的项目。

  3. 点击启用 API 和服务

  4. 搜索 Kubernetes,然后从搜索结果中选择 API。

  5. 点击启用。如果您之前已启用 API,则必须先停用,然后再次启用。API 和相关服务的启用可能需要几分钟才能完成。

gcloud

在 gcloud CLI 中运行以下命令:

PROJECT_NUMBER=$(gcloud projects describe "PROJECT_ID"
    --format 'get(projectNumber)')
gcloud projects add-iam-policy-binding PROJECT_ID \
    --member "serviceAccount:service-${PROJECT_NUMBER?}@container-engine-robot.iam.gserviceaccount.com" \
    --role roles/container.serviceAgent

后续步骤

如果您需要其他帮助,请与 Cloud Customer Care 联系。