GKE 叢集的進階負載平衡

本頁面說明如何使用 Kubernetes API,為採用代管 Cloud Service Mesh (TD) 的使用者,在 GKE 叢集中設定進階負載平衡。如需使用Google Cloud API 設定進階負載平衡功能的對應使用者指南,請參閱「設定進階負載平衡」一文。

您可以使用進階負載平衡功能執行下列操作:

  • 將流量導向服務區,直到當地運算資源用盡為止。
  • 將流量傳送至「主要」位置的服務,並在主要位置的端點出現大量不健康情況時,將流量移轉至次要位置。
  • 控管容錯移轉的時間 (根據健康主機的百分比)。

限制

  • Google Cloud 適用一般限制,不適用於使用進階負載平衡功能。
  • 這項功能僅適用於使用 Traffic Director 做為控制層的代管 Cloud Service Mesh 使用者,且需要資料層版本 1.19.10-asm.22 以上版本。
  • 受管理的 Cloud Service Mesh (TD) 不支援 GCPTrafficDistributionPolicy 和 GCPBackendPolicy 中的部分欄位。支援的欄位如下:
    • GCPTrafficDistributionPolicy
      • ServiceLbAlgorithm
      • AutoCapacityDrain
      • FailoverConfig
    • GCPBackendPolicy
      • MaxRatePerEndpoint
      • BackendPreference
  • 進階負載平衡功能只能套用至由 Google Cloud上執行的工作負載支援的 Kubernetes 服務。不支援外部服務或工作負載 (例如 ServiceEntry)。
  • 負載平衡政策只能套用至個別 Kubernetes 服務。不支援全命名空間/全網狀結構負載平衡政策。
  • 僅支援 QPS 容量。
  • 僅支援 GKE 1.31.1 以上版本。
  • 服務網格進階負載平衡政策只能套用至只提供網格流量的服務。請勿將其套用至用於提供 GKE Gateway 後端的服務。當進階負載平衡流量指定的 Kubernetes 服務同時提供網格流量和 GKE 閘道流量時,流量行為會不明確。

設定進階負載平衡

您可以使用下列自訂資源,在 GKE 上設定進階負載平衡功能。如需詳細資源定義,請前往 gke-gateway-api 存放區

GCPTrafficDistributionPolicy

GCPTrafficDistributionPolicy 會為 Kubernetes 服務設定服務層級負載平衡政策。這項功能可讓您:

如果多個 GCPTrafficDistributionPolicy 指定相同的服務,系統會強制執行最早的政策。

GCPBackendPolicy

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

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

政策狀態

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 的容量)。對於相同的多叢集服務,您可以在不同叢集中定義不同的後端層級設定。

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

這些政策會一併設定傳送至 Service foo 的內部網狀結構流量負載平衡行為:

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

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

在 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
    

後續步驟