本文档介绍如何设置多集群 Google Kubernetes Engine (GKE) 推理网关,以跨多个 GKE 集群智能地对 AI/机器学习推理工作负载进行负载均衡,这些集群可以跨不同区域。此设置使用 Gateway API、多集群 Ingress 和自定义资源(例如 InferencePool 和 InferenceObjective),以帮助提高模型服务部署的可伸缩性、确保高可用性并优化资源利用率。
如需理解本文档,请熟悉以下内容:
- GKE 上的 AI/机器学习编排 。
- 生成式 AI 术语。
- GKE 网络 概念,包括:
- 中的负载均衡 Cloud de Confiance,尤其是 负载平衡器如何与 GKE 交互。
本文档适用于以下角色:
- 机器学习 (ML) 工程师、平台管理员和运维人员,或希望使用 GKE 的容器编排功能来处理 AI/机器学习工作负载的数据和 AI 专家。
- 与 GKE 网络交互的云架构师或网络专家。
如需详细了解我们在 Cloud de Confiance by S3NS 内容中提及的常见角色和示例任务,请参阅常见的 GKE Enterprise 用户角色和 任务。
准备工作
在开始之前,请确保您已执行以下任务:
- 启用 Google Kubernetes Engine API。 启用 Google Kubernetes Engine API
- 如果您要使用 Google Cloud CLI 执行此任务,请安装并初始化 gcloud CLI。 如果您之前安装了 gcloud CLI,请通过运行
gcloud components update命令来获取最新版本。较早版本的 gcloud CLI 可能不支持运行本文档中的命令。
启用 Compute Engine API、Kubernetes Engine API、Model Armor 和 Network Services API。
前往启用对 API 的访问,然后按照说明操作。
启用 Autoscaling API。
前往 Autoscaling API ,然后按照说明操作。
启用 GKE Hub API。
前往 GKE Hub API ,然后按照说明操作。
或者,使用 Google Cloud CLI:
gcloud services enable gkehub.googleapis.com --project=PROJECT_IDHugging Face 前提条件:
- 如果您还没有 Hugging Face 账号,请创建一个。
- 申请并获得在 Hugging Face 上访问 Qwen3-32B 模型 的权限。
- 在 Hugging Face 上模型的页面中签署许可协议。
- 生成至少具有
Read权限的 Hugging Face 访问令牌。
要求
- 确保您的项目具有足够的 H100 GPU 配额。如需了解详情,请参阅 规划 GPU 配额和分配配额。
- 使用 GKE 1.34.1-gke.1127000 版或更高版本。
- 使用 gcloud CLI 480.0.0 版或更高版本。
- 您的节点服务账号必须具有向 Autoscaling API 写入指标的权限。
- 您必须在项目上拥有以下 IAM 角色:
roles/container.admin和roles/iam.serviceAccountAdmin。
多端口和 NEG 限制
在多集群设置中部署多端口 InferencePool 资源时, 请考虑 Cloud de Confiance by S3NS 后端服务 NEG 限制。每个可用区中的每个端口都会创建一个专用 NEG。例如,一个具有三个可用区的区域级集群和一个配置了八个端口的 InferencePool 将使用 24 个 NEG。由于后端服务最多只能有 50 个 NEG,因此您最多只能从两个集群聚合此特定 InferencePool,然后就会达到限制。
设置多集群推理网关
如需设置多集群 GKE 推理网关,请按照以下步骤操作:
创建集群和节点池
如需托管 AI/机器学习推理工作负载并启用跨区域负载均衡,请在不同区域中创建两个 GKE 集群,每个集群都有一个 H100 GPU 节点池。
创建第一个集群:
gcloud container clusters create CLUSTER_1_NAME \ --region LOCATION \ --project=PROJECT_ID \ --gateway-api=standard \ --release-channel "rapid" \ --cluster-version=GKE_VERSION \ --machine-type="MACHINE_TYPE" \ --disk-type="DISK_TYPE" \ --enable-managed-prometheus --monitoring=SYSTEM,DCGM \ --hpa-profile=performance \ --async # Allows the command to return immediately替换以下内容:
CLUSTER_1_NAME:第一个集群的名称,例如gke-west。LOCATION:第一个集群的区域,例如europe-west3。PROJECT_ID:您的项目 ID。GKE_VERSION:要使用的 GKE 版本,例如1.34.1-gke.1127000。MACHINE_TYPE:集群节点的机器类型,例如c2-standard-16。DISK_TYPE:集群节点的磁盘类型,例如pd-standard。
为第一个集群创建 H100 节点池:
gcloud container node-pools create NODE_POOL_NAME \ --accelerator "type=nvidia-h100-80gb,count=2,gpu-driver-version=latest" \ --project=PROJECT_ID \ --location=CLUSTER_1_ZONE \ --node-locations=CLUSTER_1_ZONE \ --cluster=CLUSTER_1_NAME \ --machine-type=NODE_POOL_MACHINE_TYPE \ --num-nodes=NUM_NODES \ --spot \ --async # Allows the command to return immediately替换以下内容:
NODE_POOL_NAME:节点池的名称,例如h100。PROJECT_ID:您的项目 ID。CLUSTER_1_ZONE:第一个集群的可用区,例如europe-west3-c。CLUSTER_1_NAME:第一个集群的名称,例如gke-west。NODE_POOL_MACHINE_TYPE:节点池的机器类型,例如a3-highgpu-2g。NUM_NODES:节点池中的节点数,例如3。
获取凭据:
gcloud container clusters get-credentials CLUSTER_1_NAME \ --location CLUSTER_1_ZONE \ --project=PROJECT_ID替换以下内容:
PROJECT_ID:您的项目 ID。CLUSTER_1_NAME:第一个集群的名称,例如gke-west。CLUSTER_1_ZONE:第一个集群的可用区,例如europe-west3-c。
在第一个集群上,为 Hugging Face 令牌创建一个 Secret:
kubectl create secret generic hf-token \ --from-literal=token=HF_TOKEN将
HF_TOKEN替换为您的 Hugging Face 访问令牌。在与第一个集群不同的区域中创建第二个集群:
gcloud container clusters create gke-east --region LOCATION \ --project=PROJECT_ID \ --gateway-api=standard \ --release-channel "rapid" \ --cluster-version=GKE_VERSION \ --machine-type="MACHINE_TYPE" \ --disk-type="DISK_TYPE" \ --enable-managed-prometheus \ --monitoring=SYSTEM,DCGM \ --hpa-profile=performance \ --async # Allows the command to return immediately while the cluster is created in the background.替换以下内容:
LOCATION:第二个集群的区域。 这必须是与第一个集群不同的区域。例如,us-east4。PROJECT_ID:您的项目 ID。GKE_VERSION:要使用的 GKE 版本,例如1.34.1-gke.1127000。MACHINE_TYPE:集群节点的机器类型,例如c2-standard-16。DISK_TYPE:集群节点的磁盘类型,例如pd-standard。
为第二个集群创建 H100 节点池:
gcloud container node-pools create h100 \ --accelerator "type=nvidia-h100-80gb,count=2,gpu-driver-version=latest" \ --project=PROJECT_ID \ --location=CLUSTER_2_ZONE \ --node-locations=CLUSTER_2_ZONE \ --cluster=CLUSTER_2_NAME \ --machine-type=NODE_POOL_MACHINE_TYPE \ --num-nodes=NUM_NODES \ --spot \ --async # Allows the command to return immediately替换以下内容:
PROJECT_ID:您的项目 ID。CLUSTER_2_ZONE:第二个集群的可用区,例如us-east4-a。CLUSTER_2_NAME:第二个集群的名称,例如gke-east。NODE_POOL_MACHINE_TYPE:节点池的机器类型,例如a3-highgpu-2g。NUM_NODES:节点池中的节点数,例如3。
对于第二个集群,获取凭据并为 Hugging Face 令牌创建一个 Secret:
gcloud container clusters get-credentials CLUSTER_2_NAME \ --location CLUSTER_2_ZONE \ --project=PROJECT_ID kubectl create secret generic hf-token --from-literal=token=HF_TOKEN替换以下内容:
CLUSTER_2_NAME:第二个集群的名称,例如gke-east。CLUSTER_2_ZONE:第二个集群的可用区,例如us-east4-a。PROJECT_ID:您的项目 ID。HF_TOKEN:您的 Hugging Face 访问令牌。
将集群注册到舰队
如需启用多集群功能(例如多集群 GKE 推理网关),请将集群注册到舰队。
设置 API 端点替换值,以防止在注册期间出现 mTLS 问题。
gcloud config set api_endpoint_overrides/container https://container.googleapis.com/将这两个集群注册到项目的舰队:
gcloud container fleet memberships register CLUSTER_1_NAME \ --gke-cluster CLUSTER_1_ZONE/CLUSTER_1_NAME \ --location=global \ --project=PROJECT_ID gcloud container fleet memberships register CLUSTER_2_NAME \ --gke-cluster CLUSTER_2_ZONE/CLUSTER_2_NAME \ --location=global \ --project=PROJECT_ID替换以下内容:
CLUSTER_1_NAME:第一个集群的名称,例如gke-west。CLUSTER_1_ZONE:第一个集群的可用区,例如europe-west3-c。PROJECT_ID:您的项目 ID。CLUSTER_2_NAME:第二个集群的名称,例如gke-east。CLUSTER_2_ZONE:第二个集群的可用区,例如us-east4-a。
如需允许单个网关管理多个集群之间的流量,请启用多集群 Ingress 功能并指定配置集群:
gcloud container fleet ingress enable \ --config-membership=projects/PROJECT_ID/locations/global/memberships/CLUSTER_1_NAME替换以下内容:
PROJECT_ID:您的项目 ID。CLUSTER_1_NAME:第一个集群的名称,例如gke-west。
创建代理专用子网
对于内部网关,请在每个区域中创建一个代理专用子网。内部网关的 Envoy 代理使用这些专用子网来处理 VPC 网络中的流量。
在第一个集群的区域中创建子网:
gcloud compute networks subnets create CLUSTER_1_REGION-subnet \ --purpose=GLOBAL_MANAGED_PROXY \ --role=ACTIVE \ --region=CLUSTER_1_REGION \ --network=default \ --range=10.0.0.0/23 \ --project=PROJECT_ID在第二个集群的区域中创建子网:
gcloud compute networks subnets create CLUSTER_2_REGION-subnet \ --purpose=GLOBAL_MANAGED_PROXY \ --role=ACTIVE \ --region=CLUSTER_2_REGION \ --network=default \ --range=10.5.0.0/23 \ --project=PROJECT_ID替换以下内容:
PROJECT_ID:您的项目 ID。CLUSTER_1_REGION:第一个集群的区域,例如europe-west3。CLUSTER_2_REGION:第二个集群的区域,例如us-east4。
安装所需的 CustomResourceDefinition
多集群 GKE 推理网关使用自定义资源,例如 InferencePool 和 InferenceObjective。GKE Gateway API 控制器管理 InferencePool CustomResourceDefinition。但是,您必须在集群上手动安装 InferenceObjective CustomResourceDefinition(该资源处于 Alpha 版)。
为集群定义上下文变量:
CLUSTER1_CONTEXT="gke_PROJECT_ID_CLUSTER_1_ZONE_CLUSTER_1_NAME" CLUSTER2_CONTEXT="gke_PROJECT_ID_CLUSTER_2_ZONE_CLUSTER_2_NAME"替换以下内容:
PROJECT_ID:您的项目 ID。CLUSTER_1_ZONE:第一个集群的可用区,例如europe-west3-c。CLUSTER_1_NAME:第一个集群的名称,例如gke-west。CLUSTER_2_ZONE:第二个集群的可用区,例如us-east4-a。CLUSTER_2_NAME:第二个集群的名称,例如gke-east。
在两个集群上安装 InferenceObjective CustomResourceDefinition:
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api-inference-extension/v1.5.0/config/crd/bases/inference.networking.x-k8s.io_inferenceobjectives.yaml --context=$CLUSTER1_CONTEXT kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api-inference-extension/v1.5.0/config/crd/bases/inference.networking.x-k8s.io_inferenceobjectives.yaml --context=$CLUSTER2_CONTEXT
将资源部署到目标集群
如需在每个集群上提供 AI/机器学习推理工作负载,请部署所需的资源,例如模型服务器和 InferenceObjective 自定义资源。
将模型服务器部署到这两个集群:
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api-inference-extension/v1.5.0/config/manifests/vllm/gpu-deployment.yaml --context=$CLUSTER1_CONTEXT kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api-inference-extension/v1.5.0/config/manifests/vllm/gpu-deployment.yaml --context=$CLUSTER2_CONTEXT将 InferenceObjective 资源部署到这两个集群。将以下示例清单保存到名为
inference-objective.yaml的文件中:apiVersion: inference.networking.x-k8s.io/v1alpha2 kind: InferenceObjective metadata: name: food-review spec: priority: 10 poolRef: name: vllm-qwen3-32b group: "inference.networking.k8s.io"将清单应用于两个集群:
kubectl apply -f inference-objective.yaml --context=$CLUSTER1_CONTEXT kubectl apply -f inference-objective.yaml --context=$CLUSTER2_CONTEXT替换以下内容:
- $CLUSTER1_CONTEXT:第一个集群的上下文,例如
gke_my-project_europe-west3-c_gke-west。 - $CLUSTER2_CONTEXT:第二个集群的上下文,例如
gke_my-project_us-east4-a_gke-east。
- $CLUSTER1_CONTEXT:第一个集群的上下文,例如
使用 Helm 将 InferencePool 资源部署到这两个集群:
helm install vllm-qwen3-32b \ --kube-context $CLUSTER1_CONTEXT \ --set inferencePool.modelServers.matchLabels.app=vllm-qwen3-32b \ --set provider.name=gke \ --set inferenceExtension.monitoring.gke.enabled=true \ --version v1.5.0 \ oci://registry.k8s.io/gateway-api-inference-extension/charts/inferencepoolhelm install vllm-qwen3-32b \ --kube-context $CLUSTER2_CONTEXT \ --set inferencePool.modelServers.matchLabels.app=vllm-qwen3-32b \ --set provider.name=gke \ --set inferenceExtension.monitoring.gke.enabled=true \ --version v1.5.0 \ oci://registry.k8s.io/gateway-api-inference-extension/charts/inferencepool将 InferencePool 资源标记为在两个集群上导出。此注解使 InferencePool 可供配置集群导入,这是多集群路由的必要步骤。
kubectl annotate inferencepool vllm-qwen3-32b networking.gke.io/export="True" \ --context=$CLUSTER1_CONTEXTkubectl annotate inferencepool vllm-qwen3-32b networking.gke.io/export="True" \ --context=$CLUSTER2_CONTEXT
将资源部署到配置集群
如需定义如何在所有已注册集群中的 InferencePool 资源之间路由和负载均衡流量,请部署 Gateway、HTTPRoute 和 HealthCheckPolicy 资源。您 仅 将这些资源部署到指定的配置集群,即本文档中的 gke-west。
创建一个名为
mcig.yaml的文件,其中包含以下内容:--- apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: cross-region-gateway namespace: default spec: gatewayClassName: gke-l7-cross-regional-internal-managed-mc addresses: - type: networking.gke.io/ephemeral-ipv4-address/europe-west3 value: "europe-west3" - type: networking.gke.io/ephemeral-ipv4-address/us-east4 value: "us-east4" listeners: - name: http protocol: HTTP port: 80 --- apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: vllm-qwen3-32b-default spec: parentRefs: - name: cross-region-gateway kind: Gateway rules: - backendRefs: - group: networking.gke.io kind: GCPInferencePoolImport name: vllm-qwen3-32b --- apiVersion: networking.gke.io/v1 kind: HealthCheckPolicy metadata: name: health-check-policy namespace: default spec: targetRef: group: "networking.gke.io" kind: GCPInferencePoolImport name: vllm-qwen3-32b default: config: type: HTTP httpHealthCheck: requestPath: /health port: 8000应用清单:
kubectl apply -f mcig.yaml --context=$CLUSTER1_CONTEXT
启用自定义指标报告
如需启用自定义指标报告并帮助改进跨区域负载均衡,请从所有集群导出 KV 缓存使用情况指标。负载均衡器使用此导出的 KV 缓存使用情况数据作为自定义负载信号。使用此自定义负载信号可以根据每个集群的实际工作负载做出更智能的负载均衡决策。
创建一个名为
metrics.yaml的文件,其中包含以下内容:apiVersion: autoscaling.gke.io/v1beta1 kind: AutoscalingMetric metadata: name: gpu-cache namespace: default spec: selector: matchLabels: app: vllm-qwen3-32b endpoints: - port: 8000 path: /metrics metrics: - name: vllm:kv_cache_usage_perc # For vLLM versions v0.10.2 and newer exportName: kv-cache - name: vllm:gpu_cache_usage_perc # For vLLM versions v0.6.2 and newer exportName: kv-cache-old将指标配置应用于这两个集群:
kubectl apply -f metrics.yaml --context=$CLUSTER1_CONTEXT kubectl apply -f metrics.yaml --context=$CLUSTER2_CONTEXT
配置负载均衡政策
如需优化 AI/机器学习推理请求在 GKE 集群中的分配方式,请配置负载均衡政策。适当的均衡模式有助于确保高效的资源利用率,防止单个集群过载,并有助于提高推理服务的性能和响应能力。
配置超时
如果您的请求预计持续时间较长,请为负载均衡器配置更长的超时时间。在 GCPBackendPolicy 中,将 timeoutSec 字段设置为至少是您估计的 P99 请求延迟时间的两倍。
例如,以下清单将负载均衡器超时时间设置为 100 秒。
apiVersion: networking.gke.io/v1
kind: GCPBackendPolicy
metadata:
name: my-backend-policy
spec:
targetRef:
group: "networking.gke.io"
kind: GCPInferencePoolImport
name: vllm-qwen3-32b
default:
timeoutSec: 100
balancingMode: CUSTOM_METRICS
trafficDuration: LONG
customMetrics:
- name: gke.named_metrics.kv-cache
dryRun: false
maxUtilizationPercent: 60
如需了解详情, 请参阅 多集群网关限制。
由于自定义指标 和正在处理的请求数 负载均衡模式是互斥的,因此请在 GCPBackendPolicy 中仅配置其中一种模式。
为您的部署选择负载均衡模式。
自定义指标
如需实现最佳负载均衡,请从 60% 的目标利用率开始。如需实现此目标,请在 GCPBackendPolicy 的 customMetrics 配置中设置 maxUtilizationPercent: 60。
创建一个名为
backend-policy.yaml的文件,其中包含以下内容,以启用基于kv-cache自定义指标的负载均衡:apiVersion: networking.gke.io/v1 kind: GCPBackendPolicy metadata: name: my-backend-policy spec: targetRef: group: "networking.gke.io" kind: GCPInferencePoolImport name: vllm-qwen3-32b default: balancingMode: CUSTOM_METRICS trafficDuration: LONG customMetrics: - name: gke.named_metrics.kv-cache dryRun: false maxUtilizationPercent: 60应用新政策:
kubectl apply -f backend-policy.yaml --context=$CLUSTER1_CONTEXT
正在处理的请求数
如需使用正在处理的请求数均衡模式,请估计每个后端可以处理的正在处理的请求数,并明确配置容量值。
创建一个名为
backend-policy.yaml的文件,其中包含以下内容,以启用基于正在处理的请求数的负载均衡:kind: GCPBackendPolicy apiVersion: networking.gke.io/v1 metadata: name: my-backend-policy spec: targetRef: group: "networking.gke.io" kind: GCPInferencePoolImport name: vllm-qwen3-32b default: balancingMode: IN_FLIGHT trafficDuration: LONG maxInFlightRequestsPerEndpoint: 1000 dryRun: false应用新政策:
kubectl apply -f backend-policy.yaml --context=$CLUSTER1_CONTEXT
验证部署
如需验证内部负载均衡器,您必须从 VPC 网络内发送请求,因为内部负载均衡器使用专用 IP 地址。在一个集群内运行临时 Pod,以从 VPC 网络发送请求并验证内部负载均衡器:
在新 Shell 中,获取网关 IP 地址:
GW_IP=$(kubectl get gateway/cross-region-gateway -n default --context=$CLUSTER1_CONTEXT -o jsonpath='{.status.addresses[0].value}')从集群内的临时 Pod 发送测试请求:
kubectl run -it --rm --image=curlimages/curl curly --context=$CLUSTER1_CONTEXT -- \ curl -i -X POST ${GW_IP}:80/v1/completions -H 'Content-Type: application/json' -d '{ "model": "Qwen/Qwen3-32B", "prompt": "What is the best pizza in the world?", "max_tokens": 100, "temperature": 0 }'
后续步骤
- 详细了解 GKE Gateway API。
- 详细了解 多集群 GKE Inference Gateway。
- 详细了解多集群 Ingress。