翻新設定更新
如果相容性檢查標記了代管 Cloud Service Mesh 叢集,您必須按照本文說明更新設定,才能在支援終止期限前,從已淘汰的 ISTIOD 控制層,翻新至 TRAFFIC_DIRECTOR 控制層。
以下列出可能需要更新的設定,以便為叢集現代化做好準備。如需更新操作說明,請參閱各節內容:
- 多叢集
- 啟用 Workload Identity Federation for GKE
- 啟用代管 CNI
- 在 Sidecar 中使用非標準二進位檔
- 遷移至 Istio Ingress 閘道
- 更新 EnvoyFilter 壓縮器設定
- 啟用網際網路的網路端點群組
- Shared VPC 權限
- 缺少控制層設定
如要進一步瞭解現代化工作流程,請參閱「代管控制層現代化」頁面。
從 Istio Secret 遷移至 multicluster_mode
如果叢集使用 TRAFFIC_DIRECTOR 控制層,則不支援多叢集 Secret。本文說明如何從使用 Istio 多叢集 Secret 翻新為使用 multicluster_mode。
Istio 密鑰與宣告式 API 總覽
開放原始碼 Istio 多叢集端點探索功能會使用 istioctl 或其他工具,在叢集中建立 Kubernetes Secret。這組 Secret 可讓叢集將流量負載平衡至網格中的其他叢集。ISTIOD 控制層會讀取這個 Secret,並開始將流量轉送至其他叢集。
Cloud Service Mesh 具有宣告式 API,可控制多叢集流量,而不必直接建立 Istio 密鑰。這個 API 會將 Istio 密鑰視為實作詳細資料,比手動建立 Istio 密鑰更可靠。未來的 Cloud Service Mesh 功能將依賴宣告式 API,您無法直接搭配 Istio 密鑰使用這些新功能。宣告式 API 是唯一支援的未來發展方向。
如果您使用的是 Istio Secret,請盡快改用宣告式 API。請注意,multicluster_mode 設定會指示每個叢集將流量導向網格中的所有其他叢集。使用 Secret 可讓設定更具彈性,您可以為每個叢集設定應將流量導向網格中的哪個叢集。如要查看宣告式 API 和 Istio 密鑰支援功能的完整差異清單,請參閱「使用 Istio API 的支援功能」。
從 Istio 密鑰遷移至宣告式 API
如果您是使用機群功能 API,透過自動管理功能佈建 Cloud Service Mesh,則不必按照這些操作說明進行。這些步驟僅適用於使用 asmcli --managed 註冊的情況。
請注意,這項程序會變更指向叢集的 Secret。在這個過程中,端點會先移除再重新加入。在移除和新增端點之間,流量會短暫恢復在本機轉送,而非負載平衡至其他叢集。詳情請參閱 GitHub 問題。
如要從使用 Istio 密鑰改為使用宣告式 API,請按照下列步驟操作。同時或快速連續執行下列步驟:
如要為機群中的每個叢集啟用多叢集端點探索功能,請設定
multicluster_mode=connected,啟用宣告式 API。請注意,如果您不希望叢集可供偵測,則必須明確設定multicluster_mode=disconnected。使用下列指令,為叢集選擇加入多叢集端點探索功能:
kubectl patch configmap/asm-options -n istio-system --type merge -p '{"data":{"multicluster_mode":"connected"}}'使用下列指令,即可讓叢集退出端點探索:
kubectl patch configmap/asm-options -n istio-system --type merge -p '{"data":{"multicluster_mode":"disconnected"}}'刪除舊密鑰。
在叢集上設定
multicluster_mode=connected後,每個叢集都會為其他也設定multicluster_mode=connected的叢集產生新的 Secret。Secret 會放在 istio-system 命名空間中,格式如下:istio-remote-secret-projects-PROJECT_NAME-locations-LOCATION-memberships-MEMBERSHIPS每個密鑰也會套用
istio.io/owned-by: mesh.googleapis.com標籤。建立新密鑰後,您可以刪除使用
istioctl create-remote-secret手動建立的任何密鑰:kubectl delete secret SECRET_NAME -n istio-system
遷移完成後,請檢查要求指標,確認是否按照預期轉送。
啟用 Workload Identity Federation for GKE
建議您使用 Workload Identity Federation,以安全的方式處理 Google Kubernetes Engine 工作負載。這可讓您存取 Google Cloud 服務,例如 Compute Engine、BigQuery 和機器學習 API。Workload Identity Federation 採用 IAM 政策,因此不需要手動設定,也不必使用服務帳戶金鑰檔案等安全性較低的方法。如要進一步瞭解 Workload Identity Federation,請參閱「Workload Identity Federation for GKE 的運作方式」。
下一節將說明如何啟用 Workload Identity Federation。
在叢集上啟用 Workload Identity Federation
確認叢集已啟用 Workload Identity Federation。為此,請確認 GKE 叢集已設定 Workload Identity Federation 集區,這對 IAM 憑證驗證至關重要。
使用下列指令,檢查叢集的 workload identity pool 設定:
gcloud container clusters describe CLUSTER_NAME \ --format="value(workloadIdentityConfig.workloadPool)"將
CLUSTER_NAME替換為 GKE 叢集名稱。如果您尚未指定 gcloud 的預設可用區或區域,執行這項指令時可能也需要指定--region或--zone旗標。如果輸出內容空白,請按照「更新現有叢集」中的操作說明,在現有 GKE 叢集啟用 Workload Identity。
在節點集區啟用 Workload Identity Federation
在叢集啟用 Workload Identity Federation 後,必須將節點集區設為使用 GKE 中繼資料伺服器。
列出 Standard 叢集的所有節點集區。執行 gcloud container node-pools list 指令:
gcloud container node-pools list --cluster CLUSTER_NAME將
CLUSTER_NAME替換為 GKE 叢集名稱。如果您尚未指定 gcloud 的預設可用區或區域,執行這項指令時可能也需要指定--region或--zone旗標。確認每個節點集區都使用 GKE 中繼資料伺服器:
gcloud container node-pools describe NODEPOOL_NAME \ --cluster=CLUSTER_NAME \ --format="value(config.workloadMetadataConfig.mode)"更改下列內容:
NODEPOOL_NAME:節點集區的名稱。CLUSTER_NAME:GKE 叢集名稱。
如果輸出內容不含
GKE_METADATA,請按照「更新現有節點集區」指南更新節點集區。
啟用代管容器網路介面 (CNI)
本節將逐步引導您在 Google Kubernetes Engine 上,為 Cloud Service Mesh 啟用代管 CNI。
代管 CNI 總覽
代管容器網路介面 (CNI) 是 Google 代管的 Istio CNI 實作項目。CNI 外掛程式會設定 iptables 規則,簡化 Pod 網路。這樣一來,流量就能在應用程式和 Envoy Proxy 之間重新導向,不必為管理 iptables 所需的 init-container 授予特殊權限。
Istio CNI 外掛程式會取代 istio-init 容器。istio-init 容器先前負責設定 Pod 的網路環境,以便為 Istio sidecar 啟用流量攔截功能。CNI 外掛程式會執行相同的網路重新導向功能,但額外的好處是可減少對進階權限的需求,進而提升安全性。
因此,為了提升安全性和可靠性,並簡化管理和疑難排解作業,所有代管 Cloud Service Mesh 部署項目都必須使用代管 CNI。
對 init 容器的影響
Init 容器是專門用來在應用程式容器執行前,執行設定工作的容器。設定工作可能包括下載設定檔、與外部服務通訊,或執行預先應用程式初始化。如果叢集啟用代管 CNI,依賴網路存取權的 init 容器可能會發生問題。
使用代管 CNI 設定 Pod 的程序如下:
- CNI 外掛程式會設定 Pod 網路介面、指派 Pod IP,並將流量重新導向至尚未啟動的 Istio Sidecar Proxy。
- 所有 init 容器都會執行並完成。
- Istio Sidecar Proxy 會與應用程式容器一併啟動。
因此,如果 init 容器嘗試建立傳出網路連線,或連線至網格中的服務,來自 init 容器的網路要求可能會遭到捨棄或轉送錯誤。這是因為提出要求時,Istio sidecar Proxy (管理 Pod 的網路流量) 並未執行。詳情請參閱 Istio CNI 說明文件。
為叢集啟用代管 CNI
請按照本節中的步驟,在叢集上啟用代管 CNI。
從 init 容器中移除網路依附元件。請考慮採用以下替代方案:
- 修改應用程式邏輯或容器:您可以修改服務,移除對需要網路要求的 init 容器的依賴,或在 Sidecar Proxy 啟動後,在應用程式容器內執行網路作業。
- 使用 Kubernetes ConfigMap 或 Secret:將網路要求擷取的設定資料儲存在 Kubernetes ConfigMap 或 Secret 中,並掛接至應用程式容器。如需替代解決方案,請參閱 Istio 說明文件。
在叢集上啟用代管 CNI:
進行下列設定變更:
執行下列指令,找出
controlPlaneRevision。kubectl get controlplanerevision -n istio-system在
ControlPlaneRevision(CPR) 自訂資源 (CR) 中,將標籤mesh.cloud.google.com/managed-cni-enabled設為true。kubectl label controlplanerevision CPR_NAME \ -n istio-system mesh.cloud.google.com/managed-cni-enabled=true \ --overwrite將
CPR_NAME替換為上一步輸出內容中「NAME」欄的值。在 asm-options ConfigMap 中,將
ASM_OPTS值設為CNI=on。kubectl patch configmap asm-options -n istio-system \ -p '{"data":{"ASM_OPTS":"CNI=on"}}'在
ControlPlaneRevision(CPR) 自訂資源 (CR) 中,將註解mesh.cloud.google.com/force-reprovision設為true。這項操作會觸發控制層重新啟動。kubectl annotate controlplanerevision CPR_NAME \ -n istio-system mesh.cloud.google.com/force-reprovision=true \ --overwrite
查看功能狀態。使用下列指令擷取功能狀態:
gcloud container fleet mesh describe --project FLEET_PROJECT_ID將
FLEET_PROJECT_ID替換為機群主機專案 ID。一般來說,FLEET_PROJECT_ID的名稱與專案相同。- 確認
MANAGED_CNI_NOT_ENABLED條件已從servicemesh.conditions移除。 - 請注意,狀態最多可能需要 15 到 20 分鐘才會更新。請稍候幾分鐘,然後重新執行指令。
- 確認
當叢集功能狀態中的
controlPlaneManagement.state為Active時,請重新啟動 Pod。
停止在 Sidecar 中使用非標準二進位檔
本節提供一些方法,協助您確保部署作業與無發行版 Envoy Proxy 映像檔相容。
Distroless Envoy Proxy Sidecar 映像檔
Cloud Service Mesh 會根據控制層設定,使用兩種 Envoy Proxy sidecar 映像檔:default Proxy 映像檔 (包含各種偵錯二進位檔) 和 distroless Proxy 映像檔。
如果叢集採用代管 TRAFFIC_DIRECTOR 控制層:
- 直接上線的叢集:預設使用
distroless映像檔。 - 從 CSM-ISTIOD 遷移的叢集:預設使用
default映像檔。您可以明確選擇加入distroless映像檔,提升資安態勢。
如要為從 CSM-ISTIOD 遷移的叢集選擇加入 distroless 映像檔,您可以在 MeshConfig 中使用 defaultConfig.image.imageType: distroless 進行全域設定,或使用 sidecar.istio.io/proxyImageType: distroless Pod 註解為個別工作負載設定。
Distroless 基本映像檔是最小的容器映像檔,僅包含必要元件,優先考量安全性和資源最佳化。攻擊面會縮小,有助於防範安全漏洞。詳情請參閱 Distroless Proxy 映像檔的說明文件。
二進位檔相容性
最佳做法是將容器執行階段的內容限制為僅包含必要套件。這種做法可提高安全性,以及常見安全漏洞與弱點 (CVE) 掃描器的訊噪比。Distroless Sidecar 映像檔具有最少的依附元件,不含所有非必要的執行檔、程式庫和偵錯工具。因此,您無法在容器中執行殼層指令,或使用 curl、ping 或其他偵錯公用程式 (例如 kubectl exec)。
讓叢集與無發行版映像檔相容
- 從設定中移除任何不支援的二進位檔 (例如 bash 或 curl) 參照。特別是 istio-proxy、istio-init 或 istio-validation 容器中的 Readiness、Startup 和 Liveness 探測,以及 Lifecycle PostStart 和 PreStop 掛鉤。
- 在某些用途中,請考慮使用 holdApplicationUntilProxyStarts 等替代方案。
- 如要偵錯,您可以使用臨時容器,附加至執行中的工作負載 Pod。接著,您可以檢查該容器並執行自訂指令。如需範例,請參閱「收集 {service_mesh_name} 記錄」。
如果找不到特定用途的解決方案,請前往「取得支援」頁面,與 Google Cloud支援團隊聯絡。
遷移至 Istio Ingress 閘道
本節說明如何遷移至 Istio Ingress 閘道。遷移至 Istio Ingress 閘道的方法有兩種:
透過流量拆分階段式遷移
這個方法會優先盡可能減少中斷情形,逐步將流量傳送至新的 Istio 閘道,讓您監控一小部分要求的效能,並在必要時快速還原。請注意,對某些應用程式來說,設定第 7 層流量拆分可能相當困難,因此您必須在轉換期間同時管理兩個閘道系統。如需相關步驟,請參閱「透過流量拆分功能分階段遷移」。
直接遷移
這個方法會在您完成測試後,同時將所有流量重新轉送至新的 Istio 閘道。這種做法的優點是能與舊閘道的基礎架構完全分離,因此可彈性設定新閘道,不受現有設定限制。不過,如果新閘道在轉換期間發生非預期的問題,停機時間可能會增加。如需相關步驟,請參閱「直接遷移」。
下列遷移範例假設您在應用程式命名空間 (預設) 中執行 HTTP 服務 (httpbin),並使用 Kubernetes Gateway API 對外公開。相關設定如下:
- 閘道:
k8-api-gateway(位於istio-ingress命名空間) - 設定為監聽通訊埠 80 上任何以.example.com結尾的主機名稱 HTTP 流量。 - HTTPRoute:
httpbin-route(位於default命名空間) - 將主機名稱為httpbin.example.com且路徑開頭為/get的任何 HTTP 要求,導向至default命名空間中的httpbin服務。 - 您可以使用外部 IP 34.57.246.68 存取 httpbin 應用程式。
透過流量拆分進行階段式遷移
佈建新的 Istio Ingress 閘道
按照「部署範例閘道」一節中的步驟部署新的輸入閘道,並根據需求自訂範例設定。anthos-service-mesh 存放區中的範例用於部署
istio-ingressgateway負載平衡器服務和對應的ingress-gatewayPod。閘道資源範例 (istio-ingressgateway.yaml)
apiVersion: networking.istio.io/v1beta1 kind: Gateway metadata: name: istio-api-gateway namespace: GATEWAY_NAMESPACE spec: selector: istio: ingressgateway # The selector should match the ingress-gateway pod labels. servers: - port: number: 80 name: http protocol: HTTP hosts: # or specific hostnames if needed - "httpbin.example.com"套用閘道設定來管理流量:
kubectl apply -f istio-ingressgateway.yaml -n GATEWAY_NAMESPACE請確認閘道資源中的「spec.selector」與
ingress-gatewayPod 的標籤相符。舉例來說,如果ingress-gatewayPod 具有istio=ingressgateway標籤,則閘道設定也必須選取這個istio=ingressgateway標籤。
設定新閘道的初始轉送
使用 Istio VirtualService 定義應用程式的初始路由規則。
VirtualService 範例 (my-app-vs-new.yaml):
apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: httpbin-vs namespace: APPLICATION_NAMESPACE spec: gateways: - istio-ingress/istio-api-gateway # Replace with <gateway-namespace/gateway-name> hosts: - httpbin.example.com http: - match: - uri: prefix: /get route: - destination: host: httpbin port: number: 8000套用 VirtualService:
kubectl apply -f my-app-vs-new.yaml -n MY_APP_NAMESPACE
透過新部署的 Istio Ingress 閘道存取後端 (httpbin) 服務
將 Ingress 主機環境變數設為與最近部署的
istio-ingressgateway負載平衡器相關聯的外部 IP 位址:export INGRESS_HOST=$(kubectl -n GATEWAY_NAMESPACE get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')確認可透過新閘道存取應用程式 (httpbin):
curl -s -I -HHost:httpbin.example.com "http://$INGRESS_HOST/get"輸出內容大致如下:
HTTP/1.1 200 OK
修改現有的 Ingress 以拆分流量
確認新閘道 (例如 istio-api-gateway) 設定成功後,即可開始透過該閘道轉送部分流量。如要這麼做,請更新目前的 HTTPRoute,將一小部分流量導向新閘道,大部分流量則繼續使用現有閘道 (k8-api-gateway)。
開啟 httproute 進行編輯:
kubectl edit httproute httpbin-route -n MY_APP_NAMESPACE新增指向新 Ingress 閘道負載平衡器服務的後端參照,初始權重為 10%,並更新舊閘道後端的權重。
apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: httpbin-route namespace: MY_APP_NAMESPACE # your application's namespace spec: parentRefs: - name: k8-api-gateway namespace: istio-ingress hostnames: ["httpbin.example.com"] rules: - matches: - path: type: PathPrefix value: /get backendRefs: - name: httpbin port: 8000 weight: 90 - name: istio-ingressgateway # Newly deployed load balancer service namespace: GATEWAY_NAMESPACE port: 80 weight: 10使用 ReferenceGrant 授予跨命名空間參照權限。
如要允許應用程式命名空間 (預設) 中的
HTTPRoute存取閘道命名空間 (istio-ingress) 中的loadbalancer服務,您可能需要建立參照授權。這項資源可做為安全性控管機制,明確定義允許哪些跨命名空間參照。下列
istio-ingress-grant.yaml說明參考授權範例:apiVersion: gateway.networking.k8s.io/v1beta1 kind: ReferenceGrant metadata: name: istio-ingressgateway-grant namespace: istio-ingress # Namespace of the referenced resource spec: from: - group: gateway.networking.k8s.io kind: HTTPRoute namespace: MY_APP_NAMESPACE # Namespace of the referencing resource to: - group: "" # Core Kubernetes API group for Services kind: Service name: istio-ingressgateway # Loadbalancer Service of the new ingress gateway套用參考授權:
kubectl apply -f istio-ingress-grant.yaml -n GATEWAY_NAMESPACE確認傳送至現有外部 IP 位址 (例如 34.57.246.68) 失敗。下列
check-traffic-flow.sh說明用於檢查要求失敗的指令碼:# Update the following values based on your application setup external_ip="34.57.246.68" # Replace with existing external IP url="http://$external_ip/get" host_name="httpbin.example.com" # Counter for successful requests success_count=0 # Loop 50 times for i in {1..50}; do # Perform the curl request and capture the status code status_code=$(curl -s -HHost:"$host_name" -o /dev/null -w "%{http_code}" "$url") # Check if the request was successful (status code 200) if [ "$status_code" -eq 200 ]; then ((success_count++)) # Increment the success counter else echo "Request $i: Failed with status code $status_code" fi done # After the loop, check if all requests were successful if [ "$success_count" -eq 50 ]; then echo "All 50 requests were successful!" else echo "Some requests failed. Successful requests: $success_count" fi執行指令碼,確認無論流量路徑為何,都不會有要求失敗:
chmod +x check-traffic-flow.sh ./check-traffic-flow.sh
慢慢提高流量百分比
如果現有外部 IP 位址 (例如 34.57.246.68) 沒有要求失敗,請調整 HTTPRoute 中的後端權重,逐步將更多流量轉移至新的 Istio 輸入閘道。以 10%、20% 等小幅增量,提高 istio-ingressgateway 的權重,並降低舊閘道的權重。
使用下列指令更新現有的 HTTPRoute:
kubectl edit httproute httpbin-route -n MY_APP_NAMESPACE
全面遷移流量並移除舊閘道
當新的 Istio Ingress 閘道效能穩定,且能成功處理要求時,請將所有流量轉移至該閘道。更新
HTTPRoute,將舊閘道的後端權重設為0,新閘道的後端權重設為100。流量完全轉送至新閘道後,請更新應用程式主機名稱 (例如
httpbin.example.com) 的外部 DNS 記錄,指向在「佈建新的 Istio Ingress 閘道」中建立的負載平衡器服務外部 IP 位址。最後,刪除舊閘道和相關聯的資源:
kubectl delete gateway OLD_GATEWAY -n GATEWAY_NAMESPACE kubectl delete service OLD_GATEWAY_SERVICE -n GATEWAY_NAMESPACE
直接遷移
佈建新的 Istio Ingress 閘道
按照「部署範例閘道」一節中的步驟部署新的輸入閘道,並根據需求自訂範例設定。anthos-service-mesh 存放區中的範例用於部署
istio-ingressgateway負載平衡器服務和對應的ingress-gatewayPod。閘道資源範例 (istio-ingressgateway.yaml)
apiVersion: networking.istio.io/v1beta1 kind: Gateway metadata: name: istio-api-gateway namespace: GATEWAY_NAMESPACE spec: selector: istio: ingressgateway # The selector should match the ingress-gateway pod labels. servers: - port: number: 80 name: http protocol: HTTP hosts: # or specific hostnames if needed - "httpbin.example.com"套用閘道設定來管理流量:
kubectl apply -f istio-ingressgateway.yaml -n GATEWAY_NAMESPACE請確認閘道資源中的「spec.selector」與
ingress-gatewayPod 的標籤相符。舉例來說,如果ingress-gatewayPod 具有istio=ingressgateway標籤,則閘道設定也必須選取這個istio=ingressgateway標籤。
設定新閘道的初始轉送
使用 Istio VirtualService 定義應用程式的初始路由規則。
VirtualService 範例 (my-app-vs-new.yaml):
apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: httpbin-vs namespace: APPLICATION_NAMESPACE spec: gateways: - istio-ingress/istio-api-gateway # Replace with <gateway-namespace/gateway-name> hosts: - httpbin.example.com http: - match: - uri: prefix: /get route: - destination: host: httpbin port: number: 8000套用 VirtualService:
kubectl apply -f my-app-vs-new.yaml -n MY_APP_NAMESPACE
透過新部署的 Istio Ingress 閘道存取後端 (httpbin) 服務
將 Ingress 主機環境變數設為與最近部署的
istio-ingressgateway負載平衡器相關聯的外部 IP 位址:export INGRESS_HOST=$(kubectl -n GATEWAY_NAMESPACE get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')確認可透過新閘道存取應用程式 (httpbin):
curl -s -I -HHost:httpbin.example.com "http://$INGRESS_HOST/get"輸出內容大致如下:
HTTP/1.1 200 OK
測試及監控新閘道
測試所有路由規則,驗證 TLS 設定、安全性政策和其他功能。執行負載測試,確認新閘道可以處理預期流量。
完整測試新的閘道後,請更新應用程式主機名稱 (例如
httpbin.example.com) 的外部 DNS 記錄,指向在「佈建新的 Istio Ingress 閘道」中建立的負載平衡器服務外部 IP 位址。監控要求成功率、延遲時間、錯誤率和應用程式 Pod 的資源使用率等重要指標,確認新 Istio Ingress Gateway 的穩定性。穩定後,即可刪除舊閘道和相關資源
kubectl delete gateway OLD_GATEWAY -n GATEWAY_NAMESPACE kubectl delete service OLD_GATEWAY_SERVICE -n GATEWAY_NAMESPACE
重要注意事項:如果應用程式需要 HTTPS,請確保新的 Istio Ingress Gateway 已正確設定 TLS 憑證和設定。詳情請參閱「在輸入閘道中設定 TLS 終止」。
修正多個控制層
Cloud Service Mesh 先前支援使用 asmcli (已淘汰) 進行新手上路,不會阻止佈建多個控制層。Cloud Service Mesh 現在會強制執行最佳做法,每個叢集只部署一個與叢集管道相符的管道,且不支援在同一個叢集使用多個已部署的管道。
如要在快速版網格的新版本推出穩定版或一般版之前,先進行初期測試部署,則須使用兩個不同的叢集,每個叢集都有獨立的管道。請注意,管道是由 GKE 叢集管道控制,Mesh 沒有與其相關聯的獨立管道。
您可以查看會員資格的 UNSUPPORTED_MULTIPLE_CONTROL_PLANES 狀態條件,確認是否有多個管道。如果沒有看到這則警告,表示您不受影響,可以略過本節。
執行下列指令,檢查叢集是否有多個控制層管道:
gcloud container fleet mesh describe輸出內容大致如下:
... projects/.../locations/global/memberships/my-membership: servicemesh: conditions: - code: UNSUPPORTED_MULTIPLE_CONTROL_PLANES details: 'Using multiple control planes is not supported. Please remove a control plane from your cluster.' documentationLink: https://cloud.google.com/service-mesh/v1.30/docs/migrate/modernization-configuration-updates#multiple_control_planes severity: WARNING controlPlaneManagement: details: - code: REVISION_READY details: 'Ready: asm-managed-stable' implementation: ISTIOD state: ACTIVE ...如果出現
UNSUPPORTED_MULTIPLE_CONTROL_PLANES條件,請判斷叢集有哪些管道:kubectl get controlplanerevisions -n istio-system輸出內容大致如下:
NAME RECONCILED STALLED AGE asm-managed-stable True False 97d asm-managed True False 97d asm-managed-rapid True False 97d在這個範例中,三個管道都已佈建:
- asm-managed-stable -> STABLE
- asm-managed -> REGULAR
- asm-managed-rapid -> RAPID
如果只顯示 1 個結果,代表叢集只佈建一個管道,您可以略過其餘步驟。
如果出現 2 個以上的結果,請按照其餘步驟移除多餘的頻道。
將工作負載整合至單一管道
如要移除其他管道,請先確認工作負載只使用單一管道。
找出叢集中使用的所有標籤:
kubectl get namespaces -l istio.io/rev=RELEASE_CHANNEL根據前一個指令的輸出內容,將 RELEASE_CHANNEL 替換為
asm-managed-stable、asm-managed或asm-managed-rapid。針對每個已佈建的管道重複這個步驟。輸出內容大致如下:
NAME STATUS AGE default Active 110d請注意,在這個範例中,預設命名空間會插入一般版。
如果所有工作負載都已使用相同管道,您可以跳到「移除額外管道」步驟。否則,請繼續閱讀本節。
變更標籤,只使用一個管道:
- 在某些情況下,Pod 也可以直接透過
sidecar.istio.io/inject標籤插入。請務必一併檢查這些項目。 - 在這個步驟中,您可以忽略
istio-injection=enabled標籤。具有該標籤的命名空間會自動變更,以符合叢集中留下的任何管道。 - 選取要保留的管道時,請盡量選取與 GKE 叢集管道相同的管道。如果沒有這個管道,請選取任何一個有效管道。
- 您選取的實際管道並不重要。GKE 叢集管道會決定您取得的網格版本,而非網格管道。
- 檢查使用中的任何有效管道之間的 meshconfig 設定,確保兩者之間沒有差異。每個管道都會使用個別的 configmap 進行設定,因此將兩個管道合併為一個,應可確保兩個管道之間的行為一致。
kubectl get configmap istio-asm-managed{-rapid | -stable} -n istio-system -o yaml
kubectl label namespace NAMESPACE istio.io/rev- istio-injection=enabled --overwrite將 NAMESPACE 替換為命名空間名稱。
最佳做法是使用
istio-injection=enabled。不過,如果您不想使用該標籤,也可以使用istio.io/rev=RELEASE_CHANNEL。變更命名空間 / Pod 的標籤後,您必須重新啟動所有工作負載,才能由正確的控制層插入。
- 在某些情況下,Pod 也可以直接透過
移除多餘的管道
確認所有工作負載都在單一管道上執行後,即可移除未使用的額外管道。如果三個發布管道都已佈建,請記得為每個管道執行下列指令。
刪除多餘的
ControlPlaneRevision資源:kubectl delete controlplanerevision RELEASE_CHANNEL -n istio-system將 RELEASE_CHANNEL 替換為
asm-managed-stable、asm-managed或asm-managed-rapid。刪除
MutatingWebhookConfiguration:kubectl delete mutatingwebhookconfiguration istiod-RELEASE_CHANNEL刪除
meshconfigconfigmap:kubectl delete configmap istio-RELEASE_CHANNEL
啟用自動管理功能
執行下列指令,啟用自動管理功能:
gcloud container fleet mesh update \ --management automatic \ --memberships MEMBERSHIP_NAME \ --project PROJECT_ID \ --location MEMBERSHIP_LOCATION更改下列內容:
- MEMBERSHIP_NAME 是您確認叢集已註冊至機群時,列出的成員資格名稱。
- PROJECT_ID 是專案 ID。
- MEMBERSHIP_LOCATION 是會員資格的位置 (區域或
global)。您可以使用gcloud container fleet memberships list --project PROJECT_ID查看會員資格的位置。
確認已啟用自動管理功能:
gcloud container fleet mesh describe輸出內容大致如下:
... membershipSpecs: projects/.../locations/us-central1/memberships/my-member: mesh: management: MANAGEMENT_AUTOMATIC membershipStates: projects/.../locations/us-central1/memberships/my-member: servicemesh: conditions: - code: VPCSC_GA_SUPPORTED details: This control plane supports VPC-SC GA. documentationLink: http://cloud.google.com/service-mesh/v1.30/docs/managed/vpc-sc severity: INFO controlPlaneManagement: details: - code: REVISION_READY details: 'Ready: asm-managed' implementation: TRAFFIC_DIRECTOR state: ACTIVE dataPlaneManagement: details: - code: OK details: Service is running. state: ACTIVE state: code: OK description: |- Revision ready for use: asm-managed. All Canonical Services have been reconciled successfully. ...
更新 EnvoyFilter 壓縮器設定
如果您使用 envoy.extensions.filters.http.compressor.v3.Compressor 篩選器,Envoy 已淘汰多個頂層欄位,並移至 response_direction_config.common_config 和 request_direction_config.common_config。
如要瞭解如何將 EnvoyFilter 資源更新為新式支援格式,請參閱「更新 EnvoyFilter 壓縮器設定」指南。
啟用必要的組織政策
Cloud Service Mesh 必須啟用特定政策,才能順利運作。
必要政策
compute.disableInternetNetworkEndpointGroup
Cloud Service Mesh 必須能建立網際網路網路端點群組 (NEG)。這些 NEG 是將流量轉送至 Google Cloud外部服務的重要元件。
constraints/compute.disableInternetNetworkEndpointGroup 限制可能會阻止建立這些必要的網際網路 NEG。
如果對專案、資料夾或組織強制執行這項組織政策,Cloud Service Mesh 將無法與 Traffic Director 控制層正常運作。這會導致無法遷移至這項 Cloud Service Mesh 設定,或無法成功執行。
如果 Enforced 設為 true,則無法建立網際網路 NEG。
如何得知自己是否受到影響?
您可以使用 Google Cloud 控制台或 Google Cloud CLI,查看專案的有效政策。如需查看組織政策的操作說明,請參閱官方說明文件的「查看組織政策」一節。
舉例來說,您可以使用下列 Google Cloud CLI 指令:
gcloud resource-manager org-policies describe constraints/compute.disableInternetNetworkEndpointGroup --project YOUR_PROJECT_ID --effective
如果政策顯示 enforced: true 值,表示您會受到影響。
constraint: constraints/compute.disableInternetNetworkEndpointGroup
booleanPolicy:
enforced: true
如果政策顯示其他值或空白,則不會受到影響。
constraint: constraints/compute.disableInternetNetworkEndpointGroup
booleanPolicy: {}
解決問題
如果強制執行政策,您必須在組織、資料夾或專案層級停用這項限制 (設為 false)。
如需修改組織政策 (包括這類布林限制) 的詳細操作說明,請參閱「建立及管理組織政策」指南。您通常需要 roles/orgpolicy.policyAdmin 角色才能進行這些變更。
Shared VPC 權限
如果使用代管 Cloud Service Mesh 搭配 Shared VPC,且叢集位於服務專案,虛擬私有雲網路位於主專案,則必須為機群專案中的 Cloud Service Mesh 服務代理授予額外權限。
遷移至TRAFFIC_DIRECTOR控制層時,Cloud Service Mesh 需要主專案中的防火牆規則管理權限,才能確保健康狀態檢查和網路功能正常運作。先前的 ISTIOD 控制層不需要這項設定。
如何得知自己是否受到影響?
如果符合下列情況,您就會受到影響:
- GKE 叢集位於服務專案中。
- 這些叢集使用託管於「不同」專案 (虛擬私有雲主機專案) 的共用虛擬私有雲網路。
- 機群專案 Cloud Service Mesh 服務代理沒有權限,無法管理虛擬私有雲主機專案中的防火牆規則。
機群功能狀態可能會顯示代碼為 SHARED_VPC_MISSING_PERMISSIONS 的警告訊息。如要進一步瞭解及解決這個問題,包括系統管理和使用者管理的選項,請參閱「瞭解健康狀態檢查」。
缺少控制層設定
Cloud Service Mesh 管理服務網格的最佳做法,是使用 Google Kubernetes Engine Fleet API 將「Management」欄位設為 AUTOMATIC。這項功能可完全自動管理許多網格功能,例如 Webhook 和控制層。此外,系統也會設定叢集,在新的更新和功能推出時自動接收。部分舊版安裝方法並未以這種方式設定 Cloud Service Mesh,您必須手動修補。
如何得知自己是否受到影響?
檢查叢集中是否有 ControlPlaneRevision:
kubectl get controlplanerevisions -n istio-system
如果叢集中已有 ControlPlaneRevision,則不適用本指南。如果您沒有 ControlPlaneRevision,請按照本指南將叢集現代化。
如果收到 MISSING_CONTROL_PLANE_CONFIG 警告,但不想使用 Cloud Service Mesh,請停用 Cloud Service Mesh。
翻新步驟
請按照下列步驟操作,判斷需要採取哪些行動,才能讓設定符合現行標準。
gcloud container fleet mesh describe --project PROJECT_ID
根據輸出內容執行下列步驟:
| 輸出內容 | 執行步驟 |
|---|---|
API [gkehub.googleapis.com] not enabled on project [my-project]. Would you like to enable and retry (this will take a few minutes)? (y/N)? |
請回覆y,然後再試一次。 |
ERROR: (gcloud.container.fleet.mesh.describe) Service Mesh Feature for project [my-project] is not enabled |
請前往「1. 啟用網格功能。 |
... resourceState: state: ACTIVE ... |
繼續執行 2. 將叢集註冊至機群。 |
1. 啟用網格功能
您可以使用下列指令啟用網格功能。這樣一來,Cloud Service Mesh 就能在您的專案中執行。如要瞭解詳情和潛在副作用,請參閱「佈建服務網格」。
gcloud container fleet mesh enable --project PROJECT_ID
啟用網格功能後,請前往「2. 將叢集註冊至機群。
2. 將叢集註冊至機群
確認叢集是否已註冊至機群:
gcloud container fleet memberships list --project PROJECT_ID
如果叢集未列在清單中,請按照這篇文章的操作說明註冊叢集。
將叢集註冊至機群後,該叢集就能透過機群管理 Cloud Service Mesh 等功能。
3. 判斷網狀網路頻道
Cloud Service Mesh 依賴叢集的 Google Kubernetes Engine 管道,而非獨立的網格管道。過去,Cloud Service Mesh 支援選擇一或多個網格管道 (與 Google Kubernetes Engine 叢集管道不同)。您的網格設定中可能仍有這些管道的參照。
首先,請判斷你使用的管道。如果您使用多個管道,請按照「修正多個控制層」中的操作說明,將用量減少至單一管道。
如要判斷您使用的網格管道,請查看命名空間的標籤。請注意,如果您已在工作負載上特別新增注入標籤,可能也需要檢查工作負載。下列指令會檢查叢集中的所有工作負載,並篩選輸出內容,顯示這些工作負載使用的控制層和插入標記。
kubectl get namespaces,pods,deployments,statefulsets,daemonsets --all-namespaces --show-labels | grep -E "istio.io/rev|istio-injection"
如果您手動建立了任何自訂標記或 Webhook,也需要檢查這些項目。
輸出內容大致如下:
namespace/default Active 153d istio-injection=enabled,istio.io/rev=asm-managed,kubernetes.io/metadata.name=default
namespace/payments Active 42d istio.io/rev=asm-managed-stable,kubernetes.io/metadata.name=payments
default pod/frontend-847f569874-v9kjz 2/2 Running 0 2m app=frontend,istio.io/rev=asm-managed,pod-template-hash=847f569874
payments pod/checkout-0 2/2 Running 0 5d app=checkout,istio.io/rev=asm-managed-stable,controller-revision-hash=5c68b9487
default deployment.apps/frontend 1/1 1 1 153d app=frontend,istio.io/rev=asm-managed
payments statefulset.apps/checkout 1/1 1 1 42d app=checkout,istio.io/rev=asm-managed-stable
請記下 istio.io/rev={channel} 的值。名稱會以這種方式與管道對應。如果使用多個版本,請按照「修正多個控制層」一節的操作說明,減少至單一版本:
| 值 | 管道 |
|---|---|
asm-managed-stable |
穩定 |
asm-managed |
一般 |
asm-managed-rapid |
快速 |
如果網格管道與 Google Kubernetes Engine 叢集管道相符,請跳至步驟 5。
4. 為網格管道建立 ControlPlaneRevision 資源
如果網格管道與 Google Kubernetes Engine 叢集管道相符,可以略過這個步驟。如果管道與叢集管道相符,啟用自動控制層管理功能後,系統會自動建立這個 ControlPlaneRevision 資源。
為使用的網格管道建立 ControlPlaneRevision 資源:
穩定
kubectl create ns istio-system
cat <<EOF | kubectl apply -f -
apiVersion: mesh.cloud.google.com/v1beta1
kind: ControlPlaneRevision
metadata:
name: asm-managed-stable
namespace: istio-system
spec:
type: managed_service
channel: stable
EOF
一般
kubectl create ns istio-system
cat <<EOF | kubectl apply -f -
apiVersion: mesh.cloud.google.com/v1beta1
kind: ControlPlaneRevision
metadata:
name: asm-managed
namespace: istio-system
spec:
type: managed_service
channel: regular
EOF
快速
kubectl create ns istio-system
cat <<EOF | kubectl apply -f -
apiVersion: mesh.cloud.google.com/v1beta1
kind: ControlPlaneRevision
metadata:
name: asm-managed-rapid
namespace: istio-system
spec:
type: managed_service
channel: rapid
EOF
5. 啟用自動管理
如要停用多叢集端點探索功能,請先按照「端點探索宣告式 API」中的「停用」操作說明,再啟用自動控制層管理功能。
如要停用代管資料層,請按照「停用代管資料層」中的操作說明進行。
如要啟用自動管理功能,請執行下列指令。這樣一來,Fleet 代管的 Cloud Service Mesh 就能管理叢集的控制層設定。
gcloud container fleet mesh update --management automatic --memberships MY_CLUSTER_MEMBERSHIP --project PROJECT_ID
將 MY_CLUSTER_MEMBERSHIP 替換為叢集的成員資格名稱。
6. 驗證安裝
執行下列指令:
gcloud container fleet mesh describe --project PROJECT_ID
輸出內容大致如下:
createTime: '2025-02-24T22:10:10.826263363Z'
etag: XjjRZB3-ZsueoaKihEBUupYhMDUjvoSyUHTVD2YgR6k
membershipSpecs:
projects/1234567890/locations/us-central1/memberships/my-cluster-membership:
mesh:
management: MANAGEMENT_AUTOMATIC # See item 1 below
membershipStates:
projects/1234567890/locations/us-central1/memberships/my-cluster-membership:
servicemesh:
conditions: [] # See item 2 below
controlPlaneManagement: # See item 3 below
details:
- code: REVISION_READY
details: 'Ready: asm-managed'
implementation: TRAFFIC_DIRECTOR
state: ACTIVE
dataPlaneManagement: # See item 4 below
details:
- code: OK
details: Service is running.
state: ACTIVE
state:
code: OK
description: |-
Revision ready for use: asm-managed.
All Canonical Services have been reconciled successfully.
updateTime: '2025-06-17T23:39:05.267540058Z'
name: projects/my-project/locations/global/features/servicemesh
resourceState:
state: ACTIVE
spec: {}
updateTime: '2025-02-25T04:12:16.280672401Z'
- 在
membershipSpecs中,機群中的每個成員資格都有獨立的規格。請確認每個成員的管理設定都正確設為MANAGEMENT_AUTOMATIC。 - 每個成員資格都有一份相關聯的狀態條件清單。請確認這裡沒有任何錯誤或警告,並按照提供的說明文件連結解決問題。
controlPlaneManagement包含控制層的狀態。確認控制層處於ACTIVE狀態。dataPlaneManagement包含資料層的狀態。建議啟用這項功能。