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
 
 - 未列出的所有字段都是不受支持的字段,并且配置了至少一个不受支持的字段的政策在 Cloud Service Mesh 中不会生效。 
- GCPTrafficDistributionPolicy
- 高级负载均衡只能应用于由 Google Cloud上运行的工作负载提供支持的 Kubernetes 服务。不支持外部服务或工作负载(例如 ServiceEntry)。 
- 负载均衡政策只能应用于单个 Kubernetes 服务。不支持命名空间级/网格级负载均衡政策。 
- 仅支持 QPS 容量。 
- 仅支持 GKE 1.31.1 版及更高版本。 
- 服务网格高级负载均衡政策必须仅应用于仅提供网格流量的服务。不得将其应用于用作 GKE 网关后端的服务。如果高级负载均衡流量的目标是同时提供网格流量和来自 GKE 网关的流量的 Kubernetes 服务,则流量行为未定义。 
配置高级负载均衡
您可以使用以下自定义资源在 GKE 上配置高级负载均衡。您可以在 gke-gateway-api 代码库中找到详细的资源定义。
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。
- 检查是否已安装 CRD: - kubectl get crd- 输出类似于以下内容: - ... gcptrafficdistributionpolicies.networking.gke.io 2024-07-18T21:50:12Z gcpbackendpolicies.networking.gke.io 2024-07-18T21:50:12Z ...
- 安装 GCPBackendPolicy CRD(如果尚未安装): - kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-gateway-api/refs/heads/main/config/crd/networking.gke.io_gcpbackendpolicies.yaml
- 安装 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,以定义要在整个舰队中使用的负载均衡算法,同时每个集群中都有 GCPBackendPolicy。这两个 GCPBackendPolicy 都为其本地集群中的后端 Pod 配置了每 Pod 10qps 的容量,而集群 A 中的 GCPBackendPolicy 将集群 A 中的后端 Pod 配置为首选后端。
这些政策共同配置了发送到服务 foo 的网格内流量的负载均衡行为:
- 来自任何位置的流量都会优先发送到集群 A 中的后端,直到集群 A 中的每个后端 Pod 需要处理 10 qps。- 此行为主要由将集群 A 中的 backendPreference设置为PREFERRED的 GCPBackendPolicy 定义。
 
- 此行为主要由将集群 A 中的 
- 超出集群 A 中的后端配置容量的流量会使用算法 WATERFALL_BY_ZONE路由到集群 B。如需详细了解首选后端,请参阅高级负载均衡概览。- 此行为主要由 GCPTrafficDistributionPolicy 和 GCPBackendPolicy 定义,前者在集群 A 中定义算法,后者在集群 A 和 B 中定义后端容量。
 
在 Istio 中,当服务网格中有多个集群且服务跨集群边界创建时,常规 Kubernetes 服务会隐式地变为“多集群”。虽然以下 GCPTrafficDistributionPolicy 以常规 Kubernetes 服务 foo 为目标,但它会应用于由两个集群中的相应工作负载组成的多集群服务 foo。
- 为集群 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
- 为集群 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
- 为集群 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
后续步骤
- 详细了解高级负载均衡