本文档介绍了如何为 GKE Dataplane V2 中的 Service 配置和验证 Maglev 负载均衡。
Maglev 是一种一致哈希算法,可提供高吞吐量和低延迟的负载均衡。Maglev 有助于确保同一流始终映射到同一后端,从而在后端 Pod 扩缩、更新或重新调度时最大限度地减少数据包丢弃和连接中断。
如需了解详情,请参阅 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
标准
如需在 Standard 集群上启用 GKE Dataplane V2,请使用 --enable-dataplane-v2 标志。如需创建 Standard 集群并检索其配置,请运行以下命令:
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
部署后端应用
在配置负载均衡服务之前,请先部署后端应用来处理流量。此 Deployment 运行 hello-app 示例应用的 5 个副本。
将以下清单保存为
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
配置负载均衡服务
您可以将服务配置为使用 Maglev 负载均衡算法或默认的随机负载均衡算法。这两个服务都以在上一步中创建的 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
配置随机服务
默认情况下,服务使用随机负载均衡算法。您无需指定注解即可使用默认算法,但以下示例明确配置了该算法以进行比较。
将以下清单保存为
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