解决代管式 Anthos Service Mesh 问题

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

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

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

如果代管式 Anthos Service Mesh 没有具有 Anthos Service Mesh Service Agent Identity and Access Management (IAM) 角色绑定的必要的 Google 管理的服务账号,您可能会看到一般性 Revision(s) reporting unhealthy 错误。通常,如果通过 Terraform、Puppet 或 CI/CD 重新配置撤消 Anthos Service Mesh Service Agent 角色的权限,就会发生这种情况。

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

Google Cloud 控制台

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

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

  3. 查看主账号列表。

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

    如果您在列表中没有看到具有所需 IAM 角色的所需代管式服务帐号,则表示该代管式服务帐号中不存在所需的 Anthos Service Mesh Service Agent IAM 角色绑定。

  4. Google Cloud 控制台中向 Anthos Service Mesh 代管式服务账号授予 Anthos Service Mesh Service Agent (roles/anthosservicemesh.serviceAgent) IAM 角色绑定。

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. 运行以下命令,为 Anthos Service Mesh 代管式服务帐号分配适当的 IAM 角色绑定:

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

Pod 注入 istiod.istio-system

如果您没有替换 istio-injection: enabled 标签,则可能会发生这种情况。

此外,请使用以下命令验证更改网络钩子配置:

kubectl get mutatingwebhookconfiguration

...
istiod-asm-managed

# may include istio-sidecar-injector

kubectl get mutatingwebhookconfiguration   istio-sidecar-injector -o yaml

# Run debug commands
export T=$(echo '{"kind":"TokenRequest","apiVersion":"authentication.k8s.io/v1","spec":{"audiences":["istio-ca"], "expirationSeconds":2592000}}' | kubectl create --raw /api/v1/namespaces/default/serviceaccounts/default/token -f - | jq -j '.status.token')

export INJECT_URL=$(kubectl get mutatingwebhookconfiguration istiod-asmca -o json | jq -r .webhooks[0].clientConfig.url)
export ISTIOD_ADDR=$(echo $INJECT_URL | 'sed s/\/inject.*//')

curl -v -H"Authorization: Bearer $T" $ISTIOD_ADDR/debug/configz

安装工具生成 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 启用代管式 Anthos Service Mesh,或在预配代管式 Anthos Service Mesh 之后使用 asmcli 启用代管式数据平面。请注意,只有通过为命名空间或修订版本添加注解来启用代管式数据平面,代管式数据平面状态报告才可用。为各个 Pod 添加注解会导致这些 Pod 受管理,但如果没有为命名空间或修订版添加注解,则功能状态为 DISABLED
FAILED_PRECONDITION MANAGED_CONTROL_PLANE_REQUIRED 代管式数据平面需要有效的代管式 Anthos 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
集群项目和 environ 项目不匹配 集群必须是已注册到舰队的同一项目的一部分。
ProvisioningFailed 更新集群资源时出错 Google 无法更新集群内的资源,例如 CRD 和网络钩子。
MutatingWebhookConfiguration "istiod-asm-managed"包含网址为 ${EXISTING_URL} 的网络钩子,但预期的网址是 ${EXPECTED_URL} Google 不会覆盖现有的网络钩子,以避免中断安装。如有必要,请手动更新此设置。
ValidatingWebhookConfiguration ${NAME} 包含网址为 ${EXISTING_URL} 的网络钩子,但预期的网址是 ${EXPECTED_URL} Google 不会覆盖现有的网络钩子,以避免中断安装。如有必要,请手动更新此设置。

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

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

在这种情况下,代管式 Anthos 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"

同时,边车注入和部署任何与 Anthos 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. 重新安装代管式 Anthos Service Mesh

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