本文說明如何為 GKE Dataplane V2 中的 Service 設定及驗證 Maglev 負載平衡。
Maglev 是一致性雜湊演算法,可提供高處理量和低延遲的負載平衡。當後端 Pod 擴充、更新或重新排程時,Maglev 可確保相同流程一律對應至相同後端,盡量減少封包遺失和連線中斷的情況。
詳情請參閱 Maglev 一致雜湊演算法研究論文。
如果工作負載具有長期連線或有狀態應用程式,且後端變更不應中斷現有流程,建議使用這項功能。
如要瞭解資源負荷和擴充性考量事項,請參閱「GKE Dataplane V2 概念」。
事前準備
開始之前,請務必先完成下列工作:
- 啟用 Google Kubernetes Engine API。 啟用 Google Kubernetes Engine API
- 如要使用 Google Cloud CLI 執行這項工作,請安裝並初始化 gcloud CLI。如果您先前已安裝 gcloud CLI,請執行
gcloud components update指令,取得最新版本。較舊的 gcloud CLI 版本可能不支援執行本文件中的指令。
必要條件和限制
- GKE 版本:1.36.0-gke.2882000 以上版本
- GKE Dataplane V2:已啟用
- 叢集模式:Autopilot 和 Standard
使用 GKE Dataplane V2 建立 GKE 叢集
如要使用 Maglev,您必須擁有已啟用 GKE Dataplane V2 的 GKE 叢集。
Autopilot
Autopilot 叢集預設會啟用 GKE Dataplane V2。如要建立 Autopilot 叢集並擷取其設定,請執行下列指令:
gcloud container clusters create-auto CLUSTER_NAME \
--region=COMPUTE_REGION \
--release-channel=rapid
gcloud container clusters get-credentials CLUSTER_NAME \
--region=COMPUTE_REGION
標準
如要在標準叢集上啟用 GKE Dataplane V2,請使用 --enable-dataplane-v2 標記。如要建立標準叢集並擷取其設定,請執行下列指令:
gcloud container clusters create CLUSTER_NAME \
--zone=COMPUTE_ZONE \
--enable-dataplane-v2 \
--cluster-version=1.36.0-gke.2882000
gcloud container clusters get-credentials CLUSTER_NAME \
--zone=COMPUTE_ZONE
部署後端應用程式
設定負載平衡 Service 前,請先部署後端應用程式來處理流量。這個 Deployment 會執行 hello-app 範例應用程式的五個副本。
將下列資訊清單儲存為
echo-backend.yaml:apiVersion: apps/v1 kind: Deployment metadata: name: echo-backend spec: replicas: 5 selector: matchLabels: app: echo-backend template: metadata: labels: app: echo-backend spec: containers: - name: hello image: "us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0" ports: - containerPort: 8080套用資訊清單:
kubectl apply -f echo-backend.yaml
設定負載平衡 Service
您可以設定服務,使用 Maglev 負載平衡演算法或預設的隨機負載平衡演算法。這兩項 Service 都會指定上一個步驟中建立的 echo-backend Deployment。
設定 Maglev 服務
如要啟用 Maglev 負載平衡,請在建立期間將 gke.networking.io/lb-algorithm: "maglev" 註解新增至服務中繼資料。
將下列資訊清單儲存為
maglev-service.yaml:apiVersion: v1 kind: Service metadata: name: maglev-service annotations: gke.networking.io/lb-algorithm: "maglev" spec: selector: app: echo-backend ports: - protocol: TCP port: 80 targetPort: 8080套用資訊清單:
kubectl apply -f maglev-service.yaml
設定隨機 Service
根據預設,Service 會使用隨機負載平衡演算法。您不需要指定註解即可使用預設演算法,但以下範例會明確設定註解,以便進行比較。
將下列資訊清單儲存為
random-service.yaml:apiVersion: v1 kind: Service metadata: name: random-service annotations: gke.networking.io/lb-algorithm: "random" spec: selector: app: echo-backend ports: - protocol: TCP port: 80 targetPort: 8080套用資訊清單:
kubectl apply -f random-service.yaml
確認流量一致性
您可以部署測試用戶端 Pod,從固定來源埠傳送流量,藉此驗證 Maglev 和隨機負載平衡之間的轉送一致性差異。
確認 Maglev 流量一致性
Maglev 會將來自相同來源埠的要求,一律轉送至同一個後端 Pod。
將下列資訊清單儲存為
client-maglev.yaml:apiVersion: v1 kind: Pod metadata: name: client-maglev spec: restartPolicy: Never containers: - name: curl image: curlimages/curl:8.2.0 command: ["/bin/sh", "-c"] args: - | while true; do curl -s -H "Connection: close" http://maglev-service:80 --local-port 54321 | grep Hostname sleep 0.5 done--local-port標記會強制使用來源連接埠,而Connection: close標頭則可確保用戶端能立即將來源連接埠重複用於後續要求。套用資訊清單:
kubectl apply -f client-maglev.yaml在 Pod 執行期間,查看記錄:
kubectl logs client-maglev預期的輸出內容:
輸出內容會重複顯示相同的主機名稱,表示來自用戶端的所有流量都會持續路由至相同的後端 Pod:
Hostname: echo-backend-5c78f66dbf-abcde Hostname: echo-backend-5c78f66dbf-abcde
驗證預設 (隨機) 流量分配
預設服務會將來自相同來源通訊埠的流量分配至不同的後端 Pod。
將下列資訊清單儲存為
client-random.yaml:apiVersion: v1 kind: Pod metadata: name: client-random spec: restartPolicy: Never containers: - name: curl image: curlimages/curl:8.2.0 command: ["/bin/sh", "-c"] args: - | while true; do curl -s -H "Connection: close" http://random-service:80 --local-port 54321 | grep Hostname sleep 0.5 done套用資訊清單:
kubectl apply -f client-random.yaml在 Pod 執行期間,查看記錄:
kubectl logs client-random預期的輸出內容:
輸出內容會顯示多個不同的主機名稱,表示流量分散到不同 Pod:
Hostname: echo-backend-5c78f66dbf-abcde Hostname: echo-backend-5c78f66dbf-fghij Hostname: echo-backend-5c78f66dbf-klmno ...
清除所用資源
如要清除本教學課程中使用的資源,請執行下列指令:
刪除用戶端 Pod、Service 和 Deployment:
kubectl delete service maglev-service random-service kubectl delete deployment echo-backend kubectl delete pod client-maglev client-random刪除 GKE 叢集:
Autopilot
gcloud container clusters delete CLUSTER_NAME --region=COMPUTE_REGION
標準
gcloud container clusters delete CLUSTER_NAME --zone=COMPUTE_ZONE