解決代管 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 & Admin」(IAM 與管理) >「IAM」(身分與存取權管理)

  2. 選取「包含 Google 提供的角色授予項目」

  3. 查看主體清單。

    如果清單中顯示服務代理人具有必要的 IAM 角色,表示已正確設定。

    如果清單中未包含服務代理人和必要角色,請繼續執行下一個步驟。

  4. 將 Anthos 服務網格服務代理人角色 (roles/anthosservicemesh.serviceAgent) 授予專案中的 Cloud Service Mesh 服務代理人。詳情請參閱「管理專案、資料夾和機構的存取權」。

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,就可能會發生錯誤。您可以使用下列指令啟用 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 如果未設定命名空間或修訂版本,則受管理的資料平面會處於這個狀態。請按照操作說明透過車隊 API 啟用代管 Cloud Service Mesh,或是在使用 asmcli 佈建代管 Cloud Service Mesh 後啟用代管資料層。請注意,您必須透過標記命名空間或修訂版本,才能啟用代管資料層,才能使用代管資料層狀態報表。為個別 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,以利進一步分析。您必須手動重新啟動 Proxy,才能進行升級。如要取得需要注意的 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 工作負載身分,就可能發生錯誤。您可以使用 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 會判斷代管控制層佈建程序是否遇到錯誤。如果是 StalledMessage 欄位會包含特定錯誤的更多資訊。如要進一步瞭解可能發生的錯誤,請參閱「停滯的代碼」。

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
不支援 ControlPlaneRevision 名稱為「{NAME}」的管道「${CHANNEL}」。預期為 ${OTHER_CHANNEL} ControlPlaneRevision 的名稱必須與 ControlPlaneRevision 的管道相符,且符合下列條件:
  • asm-managed -> 一般
  • asm-managed-rapid -> rapid
  • asm-managed-stable -> 穩定
管道不得省略或留空 Channel 是 ControlPlaneRevision 的必填欄位。自訂資源中缺少或空白。
不支援的控制平面修訂版本類型:${TYPE} managed_service 是 ControlPlaneRevisionType 欄位唯一允許的欄位。
不支援的 Kubernetes 版本:${VERSION} 支援 Kubernetes 1.15 以上版本。
未啟用工作負載身分 請為叢集啟用 Workload Identity。
不支援的工作負載集區:${POOL} 工作負載集區必須採用 ${PROJECT_ID}.svc.id.goog 的格式。
ProvisioningFailed 更新叢集資源時發生錯誤 Google 無法更新叢集內的資源,例如 CRD 和 Webhook。
MutatingWebhookConfiguration "istiod-asm-managed" 包含網址為 ${EXISTING_URL} 的 webhook,但預期為 ${EXPECTED_URL} Google 不會覆寫現有的 webhook,以免破壞安裝作業。如果這是所需行為,請手動更新。
ValidatingWebhookConfiguration ${NAME} 包含網址為 ${EXISTING_URL} 的 webhook,但預期的網址為 ${EXPECTED_URL} Google 不會覆寫現有的 webhook,以免破壞安裝作業。如果這是所需行為,請手動更新。

代管 Cloud Service Mesh 無法連線至 GKE 叢集

在 2022 年 6 月至 9 月期間,Google 完成了 Google Kubernetes Engine (GKE) 上 Authorized Networks、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. 請確認您沒有任何自動化工具會將此變更還原。如果錯誤一再發生,請更新任何相關設定或許可清單。