解决托管式 Cloud Service Mesh 问题

本文档介绍了常见的 Cloud Service Mesh 问题以及如何解决这些问题,例如在 pod 中注入 istio.istio-system 时,安装工具会生成错误,例如 HTTP 400 状态代码和集群成员资格错误。

如果您需要其他帮助来排查 Cloud Service Mesh 问题,请参阅获取支持

修订版本报告运行状况不佳错误

如果代管式 Cloud Service Mesh 的服务代理没有所需的 Identity and Access Management (IAM) 角色,您可能会看到一般性 Revision(s) reporting unhealthy 错误。通常,当 Terraform、Puppet 或 CI/CD 重新配置撤消角色时,就会发生这种情况。

排查此错误所需的步骤取决于您使用的是 Google Cloud 控制台还是 Google Cloud CLI。

Google Cloud 控制台

  1. 在 Google Cloud 控制台中,转到 IAM 和管理 > IAM

  2. 选择包括 Google 提供的角色授权

  3. 查看主要账号列表。

    如果您在列表中看到具有所需 IAM 角色的服务代理,则表示该服务代理已正确配置。

    如果列表中未列出服务代理和所需角色,请继续执行下一步。

  4. 向项目中的 Cloud Service Mesh 服务代理授予 Anthos Service Mesh Service Agent 角色 (roles/anthosservicemesh.serviceAgent)。如需查看相关说明,请参阅管理对项目、文件夹和组织的访问权限

Google Cloud CLI

  1. 在 Google Cloud CLI 中,运行以下命令,检查是否已授予所需的 IAM 角色:

    gcloud projects get-iam-policy PROJECT_ID  \
    --flatten="bindings[].members" \
    --filter="bindings.members:serviceAccount:service-PROJECT_NUMBER@gcp-sa-servicemesh.iam.gserviceaccount.com AND bindings.role:roles/anthosservicemesh.serviceAgent" \
    --format='table(bindings.role)'
    
  2. 查看 ROLE 列表。

    如果列表中显示了任何角色,则表示该服务账号已正确配置。

    如果列表中未列出任何角色,则表示所需角色已被撤消。

  3. 如需向服务代理授予所需的角色,请运行以下命令:

     gcloud projects add-iam-policy-binding PROJECT_ID \
     --member="serviceAccount:service-PROJECT_NUMBER@gcp-sa-servicemesh.iam.gserviceaccount.com" \
     --role="roles/anthosservicemesh.serviceAgent"
    

安装工具生成 HTTP 400 错误

安装工具可能会生成如下 HTTP 400 错误:

HealthCheckContainerError, message: Cloud Run error: Container failed to start.
Failed to start and then listen on the port defined by the PORT environment
variable. Logs for this revision might contain more information.

如果您未在 Kubernetes 集群上启用 Workload Identity,就可能发生此错误,可以使用以下命令执行此操作:

export CLUSTER_NAME=...
export PROJECT_ID=...
export LOCATION=...
gcloud container clusters update $CLUSTER_NAME --zone $LOCATION \
    --workload-pool=$PROJECT_ID.svc.id.goog

代管式数据平面状态

以下命令会显示代管式数据平面的状态:

gcloud container fleet mesh describe --project PROJECT_ID

下表列出了所有可能的代管式数据平面状态:

状态 编码 说明
ACTIVE OK 代管式数据平面正常运行。
DISABLED DISABLED 如果未配置命名空间或修订版本来使用代管式数据平面,则代管式数据平面将处于此状态。按照说明通过 Fleet API 启用托管式 Cloud Service Mesh,或在预配托管式 Cloud Service Mesh 之后使用 asmcli 启用托管式数据平面。请注意,只有通过为命名空间或修订版本添加注解来启用代管式数据平面,代管式数据平面状态报告才可用。为各个 Pod 添加注解会导致这些 Pod 受管理,但如果没有为命名空间或修订版添加注解,则功能状态为 DISABLED
FAILED_PRECONDITION MANAGED_CONTROL_PLANE_REQUIRED 代管式数据平面需要有效的代管式 Cloud Service Mesh 控制平面。
PROVISIONING PROVISIONING 代管式数据平面正在预配。如果此状态持续超过 10 分钟,则可能发生了错误,您应该与支持团队联系
STALLED INTERNAL_ERROR 由于内部错误条件,代管式数据平面被阻止运行。如果问题仍然存在,请与支持团队联系
NEEDS_ATTENTION UPGRADE_FAILURES 代管式数据平面需要人工干预,才能使服务恢复到正常状态。如需了解详情以及如何解决此问题,请参阅 NEEDS_ATTENTION 状态

NEEDS_ATTENTION 状态

如果 gcloud container fleet mesh describe 命令显示代管式数据平面状态为 NEEDS_ATTENTION 状态且代码为 UPGRADE_FAILURES,则表示代管式数据平面无法升级某些工作负载。代管式数据平面服务将以 dataplane-upgrade: failed 标记这些工作负载,以进行进一步分析。必须手动重启代理才能升级。如需获取需要注意的 pod 列表,请运行以下命令:

kubectl get pods --all-namespaces -l dataplane-upgrade=failed

集群成员资格错误(未指定身份提供商)

安装工具可能会失败,并显示如下所示的集群成员资格错误:

asmcli: [ERROR]: Cluster has memberships.hub.gke.io CRD but no identity
provider specified. Please ensure that an identity provider is available for the
registered cluster.

如果您在注册集群之前未启用 GKE Workload Identity,则可能会发生此错误。您可以使用 gcloud container fleet memberships register --enable-workload-identity 命令在命令行上重新注册集群。

检查代管式控制平面状态

如需检查代管式控制平面状态,请运行 gcloud container fleet mesh describe --project FLEET_PROJECT_ID

在响应中,membershipStates[].servicemesh.controlPlaneManagement.details 字段可能会说明具体错误。

如需了解详情,请检查集群中的 ControlPlaneRevision 自定义资源,该资源会在代管式控制平面预配或预配失败时更新。

如需检查该资源的状态,请将 NAME 替换为与每个渠道对应的值:asm-managedasm-managed-stableasm-managed-rapid

kubectl describe controlplanerevision NAME -n istio-system

输出类似于以下内容:

    Name:         asm-managed

    …

    Status:
      Conditions:
        Last Transition Time:  2021-08-05T18:56:32Z
        Message:               The provisioning process has completed successfully
        Reason:                Provisioned
        Status:                True
        Type:                  Reconciled
        Last Transition Time:  2021-08-05T18:56:32Z
        Message:               Provisioning has finished
        Reason:                ProvisioningFinished
        Status:                True
        Type:                  ProvisioningFinished
        Last Transition Time:  2021-08-05T18:56:32Z
        Message:               Provisioning has not stalled
        Reason:                NotStalled
        Status:                False
        Type:                  Stalled

Reconciled 条件决定了代管式控制平面是否正确运行。如果为 true,则表示控制平面已成功运行。 Stalled 确定代管式控制平面预配过程是否遇到错误。如果为 Stalled,则 Message 字段包含有关特定错误的详细信息。如需详细了解可能的错误,请参阅停止代码

ControlPlaneRevision 停止代码

有多种原因可能导致 Stalled 条件在 ControlPlaneRevisions 状态下变为 true。

原因 消息 说明
PreconditionFailed 仅支持 GKE 成员资格,但 ${CLUSTER_NAME} 不是 GKE 集群。 当前集群似乎不是 GKE 集群。代管式控制平面仅适用于 GKE 集群。
不受支持的 ControlPlaneRevision 名称:${NAME} ControlPlaneRevision 的名称必须是以下项之一:
  • asm-managed
  • asm-managed-rapid
  • asm-managed-stable
不受支持的 ControlPlaneRevision 命名空间:${NAMESPACE} ControlPlaneRevision 的命名空间必须是 istio-system
名为 ${NAME} 的 ControlPlaneRevision 的渠道 ${CHANNEL} 不受支持。预期的 ${OTHER_CHANNEL} ControlPlaneRevision 的名称必须与 ControlPlaneRevision 的渠道匹配,如下所示:
  • asm-managed -> regular
  • asm-managed-rapid -> rapid
  • asm-managed-stable -> stable
渠道值不能省略,也不能留空 Channel 是 ControlPlaneRevision 的必填字段。针对自定义资源,它可缺失或为空。
不受支持的控制平面修订版本类型:${TYPE} managed_service 是 ControlPlaneRevisionType 字段唯一允许的字段。
不支持的 Kubernetes 版本:${VERSION} 支持 Kubernetes 1.15 及更高版本。
未启用 Workload Identity 请在集群上启用 Workload Identity。
不受支持的工作负载池:${POOL} 工作负载池的格式必须为 ${PROJECT_ID}.svc.id.goog
ProvisioningFailed 更新集群资源时出错 Google 无法更新集群内的资源,例如 CRD 和网络钩子。
MutatingWebhookConfiguration "istiod-asm-managed"包含网址为 ${EXISTING_URL} 的网络钩子,但预期的网址是 ${EXPECTED_URL} Google 不会覆盖现有的网络钩子,以避免中断安装。如有必要,请手动更新此设置。
ValidatingWebhookConfiguration ${NAME} 包含网址为 ${EXISTING_URL} 的网络钩子,但预期的网址是 ${EXPECTED_URL} Google 不会覆盖现有的网络钩子,以避免中断安装。如有必要,请手动更新此设置。

代管式 Cloud Service Mesh 无法连接到 GKE 集群

2022 年 6 月至 2022 年 9 月期间,Google 完成了安全工作(这些安全工作与已获授权的网络以及 Google Kubernetes Engine (GKE) 上的 Cloud Run 和 Cloud Run 函数相关)。之前使用代管式 Cloud Service Mesh 但在迁移之前停止使用它的项目没有 Cloud Run 与 GKE 之间通信所需的 API。

在这种情况下,代管式 Cloud Service Mesh 预配将失败,Cloud Logging 将显示以下错误消息:

Connect Gateway API has not been used in project [*PROJECT_NUMBER*] before or it is disabled.
Enable it by visiting https://console.developers.google.com/apis/api/connectgateway.googleapis.com/overview?project=[*PROJECT_NUMBER*] then retry.
If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.

使用以下查询过滤此消息:

resource.type="istio_control_plane"
resource.labels.project_id=[*PROJECT_ID*]
resource.labels.location=[*REGION*]
severity=ERROR
jsonPayload.message=~"Connect Gateway API has not been used in project"

同时,边车注入和部署任何与 Cloud Service Mesh 相关的 Kubernetes 自定义资源也会失败,并且 Cloud Logging 将显示以下警告消息:

Error creating: Internal error occurred: failed calling webhook
"rev.namespace.sidecar-injector.istio.io": failed to call webhook: an error on
the server ("unknown") has prevented the request from succeeding.

使用以下查询过滤此消息:

resource.type="k8s_cluster"
resource.labels.project_id=[*PROJECT_ID*]
resource.labels.location=[*REGION*]
resource.labels.cluster_name=[*CLUSTER_NAME*]
severity=WARNING
jsonPayload.message=~"Internal error occurred: failed calling webhook"

要解决该问题,请执行以下操作:

  1. 启用所需的 connectgateway API:

     gcloud services enable connectgateway.googleapis.com --project=[*PROJECT_ID*]
    
  2. 重新安装托管式 Cloud Service Mesh

  3. 对工作负载执行滚动式重启。

未启用 Google Cloud API

如果您的托管式 Cloud Service Mesh 舰队使用 TRAFFIC_DIRECTOR 控制平面实现,则必须启用某些 API。

  1. 启用所有必需的 API,包括在未使用托管式 Cloud Service Mesh 时列为“可停用”的 API。

    gcloud services enable --project=[*PROJECT_ID*] \
        trafficdirector.googleapis.com \
        networkservices.googleapis.com \
        networksecurity.googleapis.com
    
  2. 请确保您没有任何会还原此更改的自动化工具。如果错误再次出现,则更新任何相关配置或许可名单。

适用于 GKE 的 NodePool Workload Identity Federation 已停用

以下命令会显示托管式 Cloud Service Mesh 的状态:

    gcloud container fleet mesh describe

您可能会在会员资格的 Conditions 字段中看到 NODEPOOL_WORKLOAD_IDENTITY_FEDERATION_REQUIRED 错误代码:

    membershipStates:
      projects/test-project/locations/us-central1/memberships/my-membership:
        servicemesh:
          conditions:
          - code: NODEPOOL_WORKLOAD_IDENTITY_FEDERATION_REQUIRED
            details: One or more node pools have workload identity federation disabled.
            documentationLink: https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity
            severity: ERROR
          controlPlaneManagement:
            details:
            - code: REVISION_FAILED_PRECONDITION
              details: Required in-cluster components are not ready. This will be retried
                within 15 minutes.
            implementation: TRAFFIC_DIRECTOR
            state: FAILED_PRECONDITION

如果 GKE 集群的所有节点池都未启用 Workload Identity Federation,系统会显示此错误,因为这是安装 Cloud Service Mesh 的前提条件。

如需解决此错误消息,您必须按照说明在所有节点池上启用 Workload Identity 联合。请注意,启用方式可能会因您的具体集群情况而异。

启用后,错误消息应会自动移除,集群应会恢复为 ACTIVE 状态。如果问题仍然存在,并且您需要其他帮助,请参阅获取支持