GKE 叢集上的進階負載平衡

本頁說明如何使用 Kubernetes API,為代管 Cloud Service Mesh (TD) 使用者設定 GKE 叢集上的進階負載平衡。如要透過Google Cloud API 設定進階負載平衡,請參閱這篇使用者指南

進階負載平衡功能可執行下列工作:

  • 將流量保留在服務可用區,直到當地容量用盡為止。
  • 將流量傳送至「主要」位置的服務,並在主要位置的端點數量不足或狀態不佳時,容錯移轉至次要位置。
  • 控管容錯移轉的發生時間 (根據健康狀態良好的主機百分比)。

限制

  • 在 Google Cloud apply 上使用進階負載平衡功能時,一般限制
  • 這項功能僅適用於使用 Traffic Director 做為控制層的代管 Cloud Service Mesh 使用者,且需要 1.19.10-asm.22 以上版本的資料層。
  • 受管理 Cloud Service Mesh (TD) 不支援 GCPTrafficDistributionPolicyGCPBackendPolicy 中的所有欄位。支援的欄位如下:

    • GCPTrafficDistributionPolicy
      • ServiceLbAlgorithm
      • AutoCapacityDrain
      • FailoverConfig
    • GCPBackendPolicy
      • MaxRatePerEndpoint
      • BackendPreference

    未列出的所有欄位都是不支援的欄位,且至少設定一個不支援欄位的政策,在 Cloud Service Mesh 中不會生效。

  • 進階負載平衡只能套用至由 Google Cloud上執行的工作負載支援的 Kubernetes 服務。系統不支援外部服務或工作負載 (例如 ServiceEntry)。

  • 負載平衡政策只能套用至個別 Kubernetes 服務。不支援命名空間/網格範圍的負載平衡政策。

  • 僅支援 QPS 容量。

  • 僅支援 GKE 1.31.1 以上版本。

  • 服務網格進階負載平衡政策只能套用至僅提供網格流量的服務。不得套用至做為 GKE Gateway 後端的服務。如果進階負載平衡流量目標是 Kubernetes 服務,且該服務同時處理網格流量和來自 GKE Gateway 的流量,則流量行為未定義。

設定進階負載平衡

您可以使用下列自訂資源,在 GKE 上設定進階負載平衡。如需詳細的資源定義,請參閱 gke-gateway-api repo

GCPTrafficDistributionPolicy

GCPTrafficDistributionPolicy 會為 Kubernetes 服務設定服務層級的負載平衡政策。你可以:

如果多個 GCPTrafficDistributionPolicy 指向同一項服務,系統會強制執行最舊的政策。

GCPBackendPolicy

GCPBackendPolicy 會設定影響負載平衡行為的服務後端屬性,包括:

如果多個 GCPBackendPolicy 指向叢集中的相同服務,系統會強制執行最舊的政策。

政策狀態

GCPTrafficDistributionPolicy 和 GCPBackendPolicy 都有狀態欄位,可指出政策的附加狀態。

舉例來說,執行 kubectl describe gcpbackendpolicies example-policy -n example 會產生類似以下的輸出內容:

...
Status:
  Ancestors:
    Ancestor Ref:
      Group:
      Kind:       Service
      Name:       example-svc
      Namespace:  example
    Conditions:
      Last Transition Time:  2024-10-13T01:15:03Z
      Message:
      Observed Generation:   1
      Reason:                Attached
      Status:                True
      Type:                  Attached
    Controller Name:         gsmconfig.gke.io/controller

初步設定

如要完成本指南,請先在 GKE 叢集上佈建 Cloud Service Mesh

  1. 檢查是否已安裝 CRD:

    kubectl get crd
    

    輸出內容類似如下:

    ...
    gcptrafficdistributionpolicies.networking.gke.io   2024-07-18T21:50:12Z
    gcpbackendpolicies.networking.gke.io               2024-07-18T21:50:12Z
    ...
    
  2. 如果尚未安裝,請安裝 GCPBackendPolicy CRD:

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-gateway-api/refs/heads/main/config/crd/networking.gke.io_gcpbackendpolicies.yaml
    
  3. 如果尚未安裝,請安裝 GCPTrafficDistributionPolicy CRD:

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-gateway-api/refs/heads/main/config/crd/networking.gke.io_gcptrafficdistributionpolicies.yaml
    

本使用者指南中的範例政策以命名空間 foo 中的服務 foo 為目標,僅供示範。您可以執行下列指令來建立測試服務和命名空間,也可以使用自己的服務和命名空間:

kubectl apply -f - <<EOF
kind: Namespace
apiVersion: v1
metadata:
  name: foo
  labels:
    istio-injection: enabled
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: foo
  namespace: foo
spec:
  replicas: 2
  selector:
    matchLabels:
      app: test-backend
  template:
    metadata:
      labels:
        app: test-backend
    spec:
      containers:
      - name: whereami
        image: gcr.io/google-samples/whereami:v1.2.23
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: foo
  namespace: foo
spec:
  selector:
    app: test-backend
  ports:
  - port: 8080
    targetPort: 8080
EOF

設定負載平衡演算法

根據預設,服務的流量會平均分配給 Cloud Service Mesh 服務網格中每個運作正常的服務後端。您可以建立下列 GCPTrafficDistributionPolicy,將流量分配到最接近的可用區,直到後端容量上限為止:

kubectl apply -f - <<EOF
apiVersion: networking.gke.io/v1
kind: GCPTrafficDistributionPolicy
metadata:
  name: lb-policy
  namespace: foo
spec:
  targetRefs:
  - kind: Service
    group: ""
    name: foo-service
  default:
    serviceLbAlgorithm: WATERFALL_BY_ZONE
EOF

根據預設,服務後端會視為具有無限容量。如果本機/最近的可用區有足夠的健康主機,特定用戶端地區的流量就不會分配到本機/最近的可用區以外。您可以選擇使用 GCPBackendPolicy 設定服務後端的容量,避免單一區域負載過重。

kubectl apply -f - <<EOF
apiVersion: networking.gke.io/v1
kind: GCPBackendPolicy
metadata:
  name: backend-policy
  namespace: foo
spec:
  targetRef:
    kind: Service
    group: ""
    name: foo-backend
  default:
    maxRatePerEndpoint: 5
EOF

調整容錯移轉行為

根據預設,只要主要後端中有足夠比例的主機健康狀態良好,系統就不會觸發容錯移轉。如要進一步瞭解主要後端和其他術語,請參閱進階負載平衡總覽。GCPTrafficDistributionPolicy 可讓您設定健康狀態良好的主機百分比門檻,直到流量從主要後端轉移至容錯移轉後端為止。門檻越大,越快觸發容錯移轉。舉例來說,如果希望在主要後端中,健康狀態良好的主機百分比低於 90% 時觸發容錯移轉,可以設定下列 GCPTrafficDistributionPolicy:

kubectl apply -f - <<EOF
apiVersion: networking.gke.io/v1
kind: GCPTrafficDistributionPolicy
metadata:
  name: lb-policy
  namespace: foo
spec:
  targetRefs:
  - kind: Service
    group: ""
    name: foo-service
  default:
   failoverConfig:
     failoverHealthThreshold: 90
EOF

在多叢集服務網格中設定進階負載平衡

在多叢集服務網格中,GCPTrafficDistributionPolicy 和 GCPBackendPolicy 會套用至不同範圍。

當 GCPTrafficDistributionPolicy 以多叢集服務為目標時,會定義所有叢集的服務等級負載平衡行為。特定多叢集服務只需要建立一個 GCPTrafficDistributionPolicy。如果您使用 Istio API 設定服務網格,可以在機群中的任何叢集建立 GCPTrafficDistributionPolicy。您可以檢查政策的政策狀態,確認政策是否與其他政策衝突。

當 GCPBackendPolicy 指定多叢集服務時,會為本機叢集中目標服務所選取的後端 Pod 定義後端層級設定 (例如每個 Pod 的容量)。對於同一個多叢集服務,您可以在不同叢集中定義不同的後端層級設定。

在下列範例中,叢集 A 中會建立 GCPTrafficDistributionPolicy,定義要在整個車隊中使用的負載平衡演算法,而每個叢集都有 GCPBackendPolicies。兩個 GCPBackendPolicy 都會為本機叢集中的後端 Pod 設定每個 Pod 10 qps 的容量,而叢集 A 中的 GCPBackendPolicy 會將叢集 A 中的後端 Pod 設定為偏好的後端

這些政策會共同設定傳送至服務 foo 的網格內流量負載平衡行為:

  • 來自任何位置的流量都會優先選擇叢集 A 中的後端,直到叢集 A 中的後端 Pod 需要處理每個 Pod 10 個 QPS 為止。
    • 這項行為主要由 GCPBackendPolicy 定義,該政策會將叢集 A 中的 backendPreference 設為 PREFERRED
  • 如果流量超過叢集 A 中後端的設定容量,系統會使用演算法 WATERFALL_BY_ZONE 將流量轉送至叢集 B。如要進一步瞭解偏好的後端,請參閱進階負載平衡總覽
    • 這項行為主要由 GCPTrafficDistributionPolicy 定義 (定義叢集 A 中的演算法),以及 GCPBackendPolicy 定義 (定義叢集 A 和 B 中的後端容量)。

進階負載平衡多叢集服務網格

在 Istio 中,當服務網格中有多個叢集,且服務是跨叢集界線建立時,一般 Kubernetes 服務會隱含地成為「多叢集」服務。雖然下列 GCPTrafficDistributionPolicy 以一般 Kubernetes 服務 foo 為目標,但適用於由兩個叢集中相應工作負載組成的多叢集服務 foo。

  1. 為叢集 A 建立 GCPTrafficDistributionPolicy:

    kubectl apply --context cluster-a-context -f - <<EOF
    kind: GCPTrafficDistributionPolicy
    apiVersion: networking.gke.io/v1
    metadata:
    name: foo-traffic-distribution-policy
    namespace: foo
    spec:
      targetRefs:
      - kind: Service
        group: ""
        name: foo-service
      default:
        serviceLbAlgorithm: WATERFALL_BY_ZONE
    
    EOF
    
  2. 為叢集 A 建立 GCPBackendPolicy:

    kubectl apply --context cluster-a-context -f - <<EOF
    kind: GCPBackendPolicy
    apiVersion: networking.gke.io/v1
    metadata:
    name: foo-backend-policy
    namespace: foo
    spec:
      default:
        maxRatePerEndpoint: 100
        backendPreference: PREFERRED
      targetRef:
        group: ""
        kind: Service
        name: foo-service
    EOF
    
  3. 為叢集 B 建立 GCPBackendPolicy:

    kubectl apply --context cluster-b-context -f - <<EOF
    kind: GCPBackendPolicy
    apiVersion: networking.gke.io/v1
    metadata:
    name: foo-backend-policy
    namespace: foo
    spec:
      default:
        maxRatePerEndpoint: 10
      targetRef:
        group: ""
        kind: Service
        name: foo-service
    EOF
    

後續步驟