本文將引導您在不同區域的兩個 GKE 叢集部署範例應用程式,並說明多叢集閘道如何在流量超出服務容量限制時,智慧地轉送流量。
容量型負載平衡是多叢集閘道的功能,可協助您建構高度可靠且具備容錯能力的應用程式。定義服務容量可避免服務超載,確保使用者享有穩定一致的體驗。當某個叢集中的服務達到容量上限時,負載平衡器會自動將流量重新導向至另一個有可用容量的叢集。如要進一步瞭解流量管理,請參閱「GKE 流量管理」。
在本教學課程中,您將使用範例 store 應用程式模擬實際情況,也就是線上購物服務由不同團隊擁有及營運,並部署在共用 GKE 叢集的機群中。
事前準備
部署多叢集閘道前,需要先完成一些環境準備作業。繼續操作前,請按照「準備多叢集閘道環境」一文的步驟操作:
最後,請先查看 GKE Gateway 控制器的限制和已知問題,再於環境中使用控制器。
部署以容量為基礎的負載平衡
本節的練習會跨不同地區的兩個 GKE 叢集部署應用程式,藉此說明全域負載平衡和服務容量的概念。系統會以各種每秒要求數 (RPS) 層級傳送產生的流量,顯示流量在叢集和區域間的負載平衡方式。
下圖顯示您將部署的拓撲,以及流量超出服務容量時,流量如何在叢集和區域之間溢出:
準備環境
請按照「準備環境以使用多叢集閘道」一文的說明準備環境。
確認 GatewayClass 資源已安裝在設定叢集上:
kubectl get gatewayclasses --context=gke-west-1輸出結果會與下列內容相似:
NAME CONTROLLER ACCEPTED AGE gke-l7-global-external-managed networking.gke.io/gateway True 16h gke-l7-global-external-managed-mc networking.gke.io/gateway True 14h gke-l7-gxlb networking.gke.io/gateway True 16h gke-l7-gxlb-mc networking.gke.io/gateway True 14h gke-l7-regional-external-managed networking.gke.io/gateway True 16h gke-l7-regional-external-managed-mc networking.gke.io/gateway True 14h gke-l7-rilb networking.gke.io/gateway True 16h gke-l7-rilb-mc networking.gke.io/gateway True 14h
部署應用程式
將範例網頁應用程式伺服器部署至這兩個叢集:
kubectl apply --context gke-west-1 -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/master/gateway/docs/store-traffic-deploy.yaml
kubectl apply --context gke-east-1 -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/master/gateway/docs/store-traffic-deploy.yaml
輸出結果會與下列內容相似:
namespace/store created
deployment.apps/store created
部署服務、閘道和 HTTPRoute
將下列
Service資訊清單套用至gke-west-1和gke-east-1叢集:cat << EOF | kubectl apply --context gke-west-1 -f - apiVersion: v1 kind: Service metadata: name: store namespace: traffic-test annotations: networking.gke.io/max-rate-per-endpoint: "10" spec: ports: - port: 8080 targetPort: 8080 name: http selector: app: store type: ClusterIP --- kind: ServiceExport apiVersion: net.gke.io/v1 metadata: name: store namespace: traffic-test EOFcat << EOF | kubectl apply --context gke-east-1 -f - apiVersion: v1 kind: Service metadata: name: store namespace: traffic-test annotations: networking.gke.io/max-rate-per-endpoint: "10" spec: ports: - port: 8080 targetPort: 8080 name: http selector: app: store type: ClusterIP --- kind: ServiceExport apiVersion: net.gke.io/v1 metadata: name: store namespace: traffic-test EOF服務會加上
max-rate-per-endpoint註解,並將每秒要求數設為 10。每個叢集有 2 個副本,因此每個叢集中的每個服務都有 20 RPS 的容量。如要進一步瞭解如何為服務選擇服務容量等級,請參閱「判斷服務容量」。
將下列
Gateway資訊清單套用至設定叢集,在本範例中為gke-west-1:cat << EOF | kubectl apply --context gke-west-1 -f - kind: Gateway apiVersion: gateway.networking.k8s.io/v1 metadata: name: store namespace: traffic-test spec: gatewayClassName: gke-l7-global-external-managed-mc listeners: - name: http protocol: HTTP port: 80 allowedRoutes: kinds: - kind: HTTPRoute EOF資訊清單說明外部全域多叢集閘道,可部署具備公開存取 IP 位址的外部應用程式負載平衡器。
將下列
HTTPRoute資訊清單套用至設定叢集,在本範例中為gke-west-1:cat << EOF | kubectl apply --context gke-west-1 -f - kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1 metadata: name: store namespace: traffic-test labels: gateway: store spec: parentRefs: - kind: Gateway namespace: traffic-test name: store rules: - backendRefs: - name: store group: net.gke.io kind: ServiceImport port: 8080 EOF資訊清單說明 HTTPRoute,該 HTTPRoute 會使用路由規則設定 Gateway,將所有流量導向商店 ServiceImport。
storeServiceImport 會將兩個叢集中的storeService Pod 分組,並允許負載平衡器將這些 Pod 視為單一 Service。幾分鐘後,您可以查看 Gateway 的事件,確認是否已完成部署:
kubectl describe gateway store -n traffic-test --context gke-west-1輸出結果會與下列內容相似:
... Status: Addresses: Type: IPAddress Value: 34.102.159.147 Conditions: Last Transition Time: 2023-10-12T21:40:59Z Message: The OSS Gateway API has deprecated this condition, do not depend on it. Observed Generation: 1 Reason: Scheduled Status: True Type: Scheduled Last Transition Time: 2023-10-12T21:40:59Z Message: Observed Generation: 1 Reason: Accepted Status: True Type: Accepted Last Transition Time: 2023-10-12T21:40:59Z Message: Observed Generation: 1 Reason: Programmed Status: True Type: Programmed Last Transition Time: 2023-10-12T21:40:59Z Message: The OSS Gateway API has altered the "Ready" condition semantics and reservedit for future use. GKE Gateway will stop emitting it in a future update, use "Programmed" instead. Observed Generation: 1 Reason: Ready Status: True Type: Ready Listeners: Attached Routes: 1 Conditions: Last Transition Time: 2023-10-12T21:40:59Z Message: Observed Generation: 1 Reason: Programmed Status: True Type: Programmed Last Transition Time: 2023-10-12T21:40:59Z Message: The OSS Gateway API has altered the "Ready" condition semantics and reservedit for future use. GKE Gateway will stop emitting it in a future update, use "Programmed" instead. Observed Generation: 1 Reason: Ready Status: True Type: Ready Name: http Supported Kinds: Group: gateway.networking.k8s.io Kind: HTTPRoute Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ADD 12m mc-gateway-controller traffic-test/store Normal SYNC 6m43s mc-gateway-controller traffic-test/store Normal UPDATE 5m40s (x4 over 12m) mc-gateway-controller traffic-test/store Normal SYNC 118s (x6 over 10m) mc-gateway-controller SYNC on traffic-test/store was a success這項輸出內容顯示閘道已成功部署。閘道部署完成後,流量可能仍需幾分鐘才會開始傳輸。記下這項輸出內容中的 IP 位址,因為後續步驟會用到。
確認流量
使用 curl 指令測試 Gateway IP 位址,確認流量是否傳遞至應用程式:
curl GATEWAY_IP_ADDRESS
輸出結果會與下列內容相似:
{
"cluster_name": "gke-west-1",
"host_header": "34.117.182.69",
"pod_name": "store-54785664b5-mxstv",
"pod_name_emoji": "👳🏿",
"project_id": "project",
"timestamp": "2021-11-01T14:06:38",
"zone": "us-west1-a"
}
這項輸出內容會顯示 Pod 中繼資料,指出要求服務的區域。
使用負載測試驗證流量
如要確認負載平衡器是否正常運作,可以在 gke-west-1 叢集中部署流量產生器。流量產生器會產生不同負載程度的流量,以展示負載平衡器的容量和溢位功能。以下步驟會示範三種負載等級:
- 10 RPS,低於商店服務在
gke-west-1中的容量。 - 30 RPS,超過
gke-west-1商店服務的容量,導致流量溢出至gke-east-1。 - 60 RPS,超過兩個叢集內服務的容量。
設定資訊主頁
取得 Gateway 的基礎 URLmap 名稱:
kubectl get gateway store -n traffic-test --context=gke-west-1 -o=jsonpath="{.metadata.annotations.networking\.gke\.io/url-maps}"輸出結果會與下列內容相似:
/projects/PROJECT_NUMBER/global/urlMaps/gkemcg1-traffic-test-store-armvfyupay1t前往 Google Cloud 控制台的「指標探索器」頁面。
在「選取指標」下方,按一下「程式碼:MQL」。
輸入下列查詢,觀察兩個叢集中商店服務的流量指標:
fetch https_lb_rule | metric 'loadbalancing.googleapis.com/https/backend_request_count' | filter (resource.url_map_name == 'GATEWAY_URL_MAP') | align rate(1m) | every 1m | group_by [resource.backend_scope], [value_backend_request_count_aggregate: aggregate(value.backend_request_count)]將
GATEWAY_URL_MAP替換為上一步的 URLmap 名稱。按一下「Run query」(執行查詢)。在下一節中部署負載產生器後,請等待至少 5 分鐘,圖表才會顯示指標。
以每秒 10 個要求的速度進行測試
將 Pod 部署至
gke-west-1叢集:kubectl run --context gke-west-1 -i --tty --rm loadgen \ --image=cyrilbkr/httperf \ --restart=Never \ -- /bin/sh -c 'httperf \ --server=GATEWAY_IP_ADDRESS \ --hog --uri="/zone" --port 80 --wsess=100000,1,1 --rate 10'將
GATEWAY_IP_ADDRESS替換為上一步的閘道 IP 位址。輸出內容會與下列內容相似,表示流量產生器正在傳送流量:
If you don't see a command prompt, try pressing enter.負載產生器會持續將 10 RPS 傳送至閘道。即使流量來自 Google Cloud 區域內部,負載平衡器仍會將其視為來自美國西岸的用戶端流量。為模擬真實的用戶端多樣性,負載產生器會將每個 HTTP 要求做為新的 TCP 連線傳送,也就是說,流量會更平均地分配到後端 Pod。
產生器最多需要 5 分鐘,才能為資訊主頁產生流量。
查看 Metrics Explorer 資訊主頁。系統會顯示兩條線,指出負載平衡至各叢集的流量:

您應該會看到
us-west1-a接收到大約 10 RPS 的流量,而us-east1-b未收到任何流量。由於流量產生器是在us-west1中執行,因此所有流量都會傳送至gke-west-1叢集中的服務。使用 Ctrl+C 停止負載產生器,然後刪除 Pod:
kubectl delete pod loadgen --context gke-west-1
以每秒 30 個要求的速度進行測試
再次部署負載產生器,但設定為傳送 30 RPS:
kubectl run --context gke-west-1 -i --tty --rm loadgen \ --image=cyrilbkr/httperf \ --restart=Never \ -- /bin/sh -c 'httperf \ --server=GATEWAY_IP_ADDRESS \ --hog --uri="/zone" --port 80 --wsess=100000,1,1 --rate 30'產生器最多需要 5 分鐘,才能為資訊主頁產生流量。
查看 Cloud Ops 資訊主頁。

您應該會看到大約有 20 RPS 傳送至
us-west1-a,以及 10 RPS 傳送至us-east1-b。這表示gke-west-1中的服務已充分利用,且流量溢出 10 RPS 至gke-east-1中的服務。使用 Ctrl+C 停止負載產生器,然後刪除 Pod:
kubectl delete pod loadgen --context gke-west-1
以 60 RPS 進行測試
部署設定為傳送 60 RPS 的負載產生器:
kubectl run --context gke-west-1 -i --tty --rm loadgen \ --image=cyrilbkr/httperf \ --restart=Never \ -- /bin/sh -c 'httperf \ --server=GATEWAY_IP_ADDRESS \ --hog --uri="/zone" --port 80 --wsess=100000,1,1 --rate 60'等待 5 分鐘,然後查看 Cloud Ops 資訊主頁。現在應該會顯示兩個叢集都大約收到 30 RPS。由於全球所有服務都過度使用,因此不會有流量溢出,服務會吸收所有可吸收的流量。

使用 Ctrl+C 停止負載產生器,然後刪除 Pod:
kubectl delete pod loadgen --context gke-west-1
清除所用資源
完成本文件的練習後,請按照下列步驟移除資源,以免您的帳戶產生不必要的費用:
刪除叢集。
如果叢集不需要註冊用於其他用途,請取消註冊機群叢集。
停用
multiclusterservicediscovery功能:gcloud container fleet multi-cluster-services disable停用多叢集 Ingress:
gcloud container fleet ingress disable停用 API:
gcloud services disable \ multiclusterservicediscovery.googleapis.com \ multiclusteringress.googleapis.com \ trafficdirector.googleapis.com \ --project=PROJECT_ID
疑難排解
沒有健康的上游
症狀:
建立閘道但無法存取後端服務時 (503 回應碼),可能會發生下列問題:
no healthy upstream
原因:
這則錯誤訊息表示健康狀態檢查探測器找不到健康狀態良好的後端服務。後端服務可能運作正常,但您可能需要自訂健康狀態檢查。
解決方法:
如要解決這個問題,請使用 HealthCheckPolicy,根據應用程式的需求自訂健康狀態檢查 (例如 /health)。
後續步驟
- 進一步瞭解 Gateway 控制器。