在 GKE Dataplane V2 中使用 Maglev 負載平衡

本文說明如何為 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 範例應用程式的五個副本。

  1. 將下列資訊清單儲存為 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
    
  2. 套用資訊清單:

    kubectl apply -f echo-backend.yaml
    

設定負載平衡 Service

您可以設定服務,使用 Maglev 負載平衡演算法或預設的隨機負載平衡演算法。這兩項 Service 都會指定上一個步驟中建立的 echo-backend Deployment。

設定 Maglev 服務

如要啟用 Maglev 負載平衡,請在建立期間將 gke.networking.io/lb-algorithm: "maglev" 註解新增至服務中繼資料。

  1. 將下列資訊清單儲存為 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
    
  2. 套用資訊清單:

    kubectl apply -f maglev-service.yaml
    

設定隨機 Service

根據預設,Service 會使用隨機負載平衡演算法。您不需要指定註解即可使用預設演算法,但以下範例會明確設定註解,以便進行比較。

  1. 將下列資訊清單儲存為 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
    
  2. 套用資訊清單:

    kubectl apply -f random-service.yaml
    

確認流量一致性

您可以部署測試用戶端 Pod,從固定來源埠傳送流量,藉此驗證 Maglev 和隨機負載平衡之間的轉送一致性差異。

確認 Maglev 流量一致性

Maglev 會將來自相同來源埠的要求,一律轉送至同一個後端 Pod。

  1. 將下列資訊清單儲存為 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 標頭則可確保用戶端能立即將來源連接埠重複用於後續要求。

  2. 套用資訊清單:

    kubectl apply -f client-maglev.yaml
    
  3. 在 Pod 執行期間,查看記錄:

    kubectl logs client-maglev
    

    預期的輸出內容:

    輸出內容會重複顯示相同的主機名稱,表示來自用戶端的所有流量都會持續路由至相同的後端 Pod:

    Hostname: echo-backend-5c78f66dbf-abcde
    Hostname: echo-backend-5c78f66dbf-abcde
    

驗證預設 (隨機) 流量分配

預設服務會將來自相同來源通訊埠的流量分配至不同的後端 Pod。

  1. 將下列資訊清單儲存為 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
    
  2. 套用資訊清單:

    kubectl apply -f client-random.yaml
    
  3. 在 Pod 執行期間,查看記錄:

    kubectl logs client-random
    

    預期的輸出內容:

    輸出內容會顯示多個不同的主機名稱,表示流量分散到不同 Pod:

    Hostname: echo-backend-5c78f66dbf-abcde
    Hostname: echo-backend-5c78f66dbf-fghij
    Hostname: echo-backend-5c78f66dbf-klmno
    ...
    

清除所用資源

如要清除本教學課程中使用的資源,請執行下列指令:

  1. 刪除用戶端 Pod、Service 和 Deployment:

    kubectl delete service maglev-service random-service
    kubectl delete deployment echo-backend
    kubectl delete pod client-maglev client-random
    
  2. 刪除 GKE 叢集:

Autopilot

gcloud container clusters delete CLUSTER_NAME --region=COMPUTE_REGION

標準

gcloud container clusters delete CLUSTER_NAME --zone=COMPUTE_ZONE