Questo documento mostra come configurare l'alta affidabilità cross-region elastica per i carichi di lavoro di inferenza AI utilizzando il gateway di inferenza multicluster Google Kubernetes Engine (GKE) e la funzionalità di scalabilità automatica di GKE. Questa configurazione ti consente di bilanciare il carico in modo intelligente tra più cluster GKE in regioni diverse.
Per saperne di più su GKE Multi-Cluster Inference Gateway, consulta Informazioni su GKE Multi-Cluster Inference Gateway.
Prima di iniziare
Abilita l'API Google Kubernetes Engine.
Installa e inizializza Google Cloud CLI se prevedi di utilizzarla per questa attività.
Assicurati che il tuo progetto disponga di una quota sufficiente per le GPU H100. Per saperne di più, consulta Quota delle GPU e Allocazione delle risorse.
Utilizza GKE 1.34.1-gke.1127000 o versioni successive.
Utilizza gcloud CLI versione 480.0.0 o successive.
Assicurati che il account di servizio utilizzato dai nodi disponga delle autorizzazioni
roles/monitoring.metricWritereroles/stackdriver.resourceMetadata.writer.Assicurati di disporre dei ruoli IAM (Identity and Access Management)
roles/container.admineroles/iam.serviceAccountAdminnel progetto.Completa i seguenti prerequisiti di Hugging Face:
- Crea un account Hugging Face.
- Richiedi e ottieni l'approvazione per l'accesso al modello Llama 3.1 su Hugging Face.
- Firma il contratto di consenso alla licenza nella pagina del modello su Hugging Face.
- Genera un token di accesso a Hugging Face con almeno le autorizzazioni in lettura.
Crea cluster e node pool
Per creare due cluster GKE in regioni diverse e configurare i relativi pool di nodi, segui questi passaggi:
Crea il primo cluster:
gcloud container clusters create gke-west --zone \ CLUSTER_1_ZONE \ --project=PROJECT_ID \ --gateway-api=standard \ --cluster-version=GKE_VERSION \ --machine-type="MACHINE_TYPE" \ --disk-type="DISK_TYPE" \ --enable-managed-prometheus --monitoring=SYSTEM,DCGM \ --hpa-profile=performance \ --workload-pool=PROJECT_ID.s3ns.svc.id.goog \ --asyncSostituisci quanto segue:
PROJECT_ID: il tuo ID progettoCLUSTER_1_ZONE: la zona del primo cluster, ad esempioeurope-west3-cGKE_VERSION: la versione di GKE da utilizzare, ad esempio1.34.1-gke.1127000MACHINE_TYPE: il tipo di macchina per i nodi del cluster, ad esempioc2-standard-16DISK_TYPE: il tipo di disco per i nodi del cluster, ad esempiopd-standard
Crea un pool di nodi H100 nel primo cluster:
gcloud container node-pools create h100 \ --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 \ --min-nodes=MIN_NUM_NODES \ --max-nodes=MAX_NUM_NODES \ --enable-autoscaling \ --asyncSostituisci quanto segue:
PROJECT_ID: il tuo ID progettoCLUSTER_1_ZONE: la zona del primo cluster, ad esempioeurope-west3-cCLUSTER_1_NAME: il nome del primo cluster, ad esempiogke-westNODE_POOL_MACHINE_TYPE: il tipo di macchina per il pool di nodi, ad esempioa3-highgpu-2gNUM_NODES: il numero di nodi nel node pool, ad esempio3MIN_NUM_NODES: il numero minimo di nodi per la scalabilità automatica nel pool di nodi, ad esempio1MAX_NUM_NODES: il numero massimo di nodi per la scalabilità automatica nelpool di nodil, ad esempio10
Ottieni le credenziali e crea un secret del token Hugging Face nel primo cluster:
gcloud container clusters get-credentials CLUSTER_1_NAME \ --location CLUSTER_1_ZONE \ --project=PROJECT_ID kubectl create secret generic hf-token \ --from-literal=token=HF_TOKENSostituisci quanto segue:
PROJECT_ID: il tuo ID progettoCLUSTER_1_NAME: il nome del primo cluster, ad esempiogke-westCLUSTER_1_ZONE: la zona del primo cluster, ad esempioeurope-west3-cHF_TOKEN: il tuo token di accesso a Hugging Face
Crea il secondo cluster in una regione diversa dal primo:
gcloud container clusters create gke-east --zone CLUSTER_2_ZONE \ --project=PROJECT_ID \ --gateway-api=standard \ --cluster-version=GKE_VERSION \ --machine-type="MACHINE_TYPE" \ --disk-type="DISK_TYPE" \ --enable-managed-prometheus \ --monitoring=SYSTEM,DCGM \ --hpa-profile=performance \ --workload-pool=PROJECT_ID.s3ns.svc.id.goog \ --asyncSostituisci
CLUSTER_2_ZONEcon la zona del secondo cluster, ad esempious-east4-a.Crea un pool di nodi H100 per il secondo cluster:
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 \ --min-nodes=MIN_NUM_NODES \ --max-nodes=MAX_NUM_NODES \ --enable-autoscaling \ --asyncSostituisci quanto segue:
PROJECT_ID: il tuo ID progettoCLUSTER_2_ZONE: la zona del secondo cluster, ad esempious-east4-aCLUSTER_2_NAME: il nome del secondo cluster, ad esempiogke-eastNODE_POOL_MACHINE_TYPE: il tipo di macchina per il pool di nodi, ad esempioa3-highgpu-2gNUM_NODES: il numero di nodi nel node pool, ad esempio3MIN_NUM_NODES: il numero minimo di nodi per la scalabilità automatica nel pool di nodi, ad esempio1MAX_NUM_NODES: il numero massimo di nodi per la scalabilità automatica nelpool di nodil, ad esempio10
Recupera le credenziali e crea un secret per il token Hugging Face sul secondo cluster:
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_TOKENSostituisci quanto segue. Per le definizioni di altre variabili, consulta i passaggi precedenti:
HF_TOKEN: il token di accesso a Hugging Face
Registra i cluster in un parco risorse
Registra i cluster nel parco risorse del progetto:
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_IDSostituisci quanto segue e fai riferimento ai passaggi precedenti per le definizioni di altre variabili:
CLUSTER_1_NAME: il nome del primo cluster, ad esempiogke-westCLUSTER_2_NAME: il nome del secondo cluster, ad esempiogke-east
Attiva la funzionalità Ingress multi-cluster e designa un cluster di configurazione:
gcloud container fleet ingress enable \ --config-membership=projects/PROJECT_ID/locations/global/memberships/CLUSTER_1_NAMESostituisci quanto segue. Per le definizioni di altre variabili, consulta i passaggi precedenti:
PROJECT_ID: il tuo ID progettoCLUSTER_1_NAME: il nome del primo cluster, ad esempiogke-west
Crea subnet solo proxy
Avviso: Cloud de Confiance by S3NS consente a ogni rete VPC di avere una sola
subnet solo proxy per regione. Se la regione di destinazione contiene già una subnet solo proxy con l'impostazione purpose=REGIONAL_MANAGED_PROXY, la creazione della subnet GLOBAL_MANAGED_PROXY non va a buon fine. Devi prima eliminare la subnet solo proxy regionale esistente. L'eliminazione di una subnet solo proxy a livello di regione influisce su tutti i bilanciatori del carico basati su Envoy a livello di regione che la utilizzano, quindi pianifica la modifica di conseguenza.
Crea una subnet nella regione del primo cluster:
gcloud compute networks subnets create CLUSTER_1_REGION-subnet \ --purpose=GLOBAL_MANAGED_PROXY \ --role=ACTIVE \ --region=CLUSTER_1_REGION \ --network=default \ --range=SUBNET_RANGE_1 \ --project=PROJECT_IDSostituisci quanto segue:
PROJECT_ID: il tuo ID progettoCLUSTER_1_REGION: la regione del primo cluster, ad esempioeurope-west3SUBNET_RANGE_1: l'intervallo IP della subnet solo proxy nella regione del primo cluster, ad esempio10.0.0.0/23
Crea una subnet nella regione del secondo cluster:
gcloud compute networks subnets create CLUSTER_2_REGION-subnet \ --purpose=GLOBAL_MANAGED_PROXY \ --role=ACTIVE \ --region=CLUSTER_2_REGION \ --network=default \ --range=SUBNET_RANGE_2 \ --project=PROJECT_IDSostituisci quanto segue:
PROJECT_ID: il tuo ID progettoCLUSTER_2_REGION: la regione per il secondo cluster, ad esempious-east4SUBNET_RANGE_2: l'intervallo IP della subnet solo proxy nella regione del secondo cluster, ad esempio10.5.0.0/23
Installa le risorse personalizzate richieste
Definisci le variabili di contesto per i tuoi cluster:
CLUSTER1_CONTEXT="gke_PROJECT_ID_CLUSTER_1_ZONE_CLUSTER_1_NAME" CLUSTER2_CONTEXT="gke_PROJECT_ID_CLUSTER_2_ZONE_CLUSTER_2_NAME"Sostituisci quanto segue:
PROJECT_ID: il tuo ID progettoCLUSTER_1_ZONE: la zona del primo cluster, ad esempioeurope-west3-cCLUSTER_1_NAME: il nome del primo cluster, ad esempiogke-westCLUSTER_2_ZONE: la zona del secondo cluster, ad esempious-east4-aCLUSTER_2_NAME: il nome del secondo cluster, ad esempiogke-east
Installa la risorsa personalizzata InferencePool e InferenceObjective su entrambi i cluster:
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api-inference-extension/releases/download/v1.0.1/manifests.yaml --context=$CLUSTER1_CONTEXT kubectl apply -f https://github.com/kubernetes-sigs/gateway-api-inference-extension/releases/download/v1.0.1/manifests.yaml --context=$CLUSTER2_CONTEXT
Esegui il deployment delle risorse nei cluster di destinazione
Esegui il deployment dei server di modelli in entrambi i cluster:
kubectl apply -f \ https://raw.githubusercontent.com/kubernetes-sigs/gateway-api-inference-extension/release-1.0/config/manifests/vllm/gpu-deployment.yaml \ --context=$CLUSTER1_CONTEXT kubectl apply -f \ https://raw.githubusercontent.com/kubernetes-sigs/gateway-api-inference-extension/release-1.0/config/manifests/vllm/gpu-deployment.yaml \ --context=$CLUSTER2_CONTEXTSalva il seguente manifest in un file denominato
inference-objective.yaml:apiVersion: inference.networking.x-k8s.io/v1alpha2 kind: InferenceObjective metadata: name: food-review spec: priority: 10 poolRef: name: llama3-8b-instruct group: "inference.networking.k8s.io"Applica il manifest a entrambi i cluster:
kubectl apply -f inference-objective.yaml --context=$CLUSTER1_CONTEXT kubectl apply -f inference-objective.yaml --context=$CLUSTER2_CONTEXTEsegui il deployment delle risorse InferencePool in entrambi i cluster utilizzando Helm:
helm install vllm-llama3-8b-instruct \ --kube-context $CLUSTER1_CONTEXT \ --set inferencePool.modelServers.matchLabels.app=vllm-llama3-8b-instruct \ --set provider.name=gke \ --set inferenceExtension.monitoring.gke.enabled=true \ --version v1.0.1 \ oci://registry.k8s.io/gateway-api-inference-extension/charts/inferencepool helm install vllm-llama3-8b-instruct \ --kube-context $CLUSTER2_CONTEXT \ --set inferencePool.modelServers.matchLabels.app=vllm-llama3-8b-instruct \ --set provider.name=gke \ --set inferenceExtension.monitoring.gke.enabled=true \ --version v1.0.1 \ oci://registry.k8s.io/gateway-api-inference-extension/charts/inferencepoolIn entrambi i cluster, contrassegna le risorse
InferencePoolcome esportate in entrambi i cluster:kubectl annotate inferencepool vllm-llama3-8b-instruct networking.gke.io/export="True" \ --context=$CLUSTER1_CONTEXT kubectl annotate inferencepool vllm-llama3-8b-instruct networking.gke.io/export="True" \ --context=$CLUSTER2_CONTEXT
Esegui il deployment del gateway di inferenza tra regioni
Salva il seguente manifest come
mygateway.yaml:--- kind: Gateway apiVersion: gateway.networking.k8s.io/v1beta1 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 allowedRoutes: kinds: - kind: HTTPRoute namespaces: from: All --- apiVersion: gateway.networking.k8s.io/v1beta1 kind: HTTPRoute metadata: name: vllm-llama3-8b-instruct-default spec: parentRefs: - name: cross-region-gateway kind: Gateway rules: - backendRefs: - group: networking.gke.io kind: GCPInferencePoolImport name: vllm-llama3-8b-instruct --- kind: HealthCheckPolicy apiVersion: networking.gke.io/v1 metadata: name: health-check-policy namespace: default spec: targetRef: group: "networking.gke.io" kind: GCPInferencePoolImport name: vllm-llama3-8b-instruct default: config: type: HTTP httpHealthCheck: requestPath: /health port: 8000Applica il manifest al cluster di configurazione:
kubectl apply -f mygateway.yaml --context=CLUSTER1_CONTEXTSostituisci quanto segue:
CLUSTER1_CONTEXT: il contesto del primo cluster, ad esempiogke_my-project_europe-west3-c_gke-west
Attiva i report sulle metriche personalizzate
Crea un file denominato
metrics.yamlcon i seguenti contenuti:apiVersion: autoscaling.gke.io/v1beta1 kind: AutoscalingMetric metadata: name: gpu-cache namespace: default spec: selector: matchLabels: app: vllm-llama3-8b-instruct endpoints: - port: 8000 path: /metrics metrics: - name: vllm:kv_cache_usage_perc exportName: kv-cache - name: vllm:gpu_cache_usage_perc exportName: kv-cache-oldPer ogni cluster, applica la configurazione delle metriche:
kubectl apply -f metrics.yaml --context=CLUSTER1_CONTEXT kubectl apply -f metrics.yaml --context=CLUSTER2_CONTEXTPer le definizioni di
CLUSTER1_CONTEXTeCLUSTER2_CONTEXT, consulta Installa le risorse personalizzate richieste.
Configura la policy di bilanciamento del carico
Questa sezione descrive come configurare la policy di bilanciamento del carico. Questa policy definisce il modo in cui il traffico viene distribuito tra i pool di inferenza in base a metriche personalizzate e preferenze regionali. La seguente configurazione imposta us-east4 come
regione preferita. Il traffico si riversa in altre regioni solo quando la metrica personalizzata gke.named_metrics.kv-cache nella regione us-east4 raggiunge l'80% di utilizzo.
- Per le versioni di vLLM v0.10.2 e successive, utilizza la metrica
gke.named_metrics.kv-cache. - Per le versioni precedenti, utilizza la metrica
gke.named_metrics.kv-cache-old.
Crea un file denominato
backend-policy.yamlcon i seguenti contenuti:kind: GCPBackendPolicy apiVersion: networking.gke.io/v1 metadata: name: my-backend-policy spec: targetRef: group: "networking.gke.io" kind: GCPInferencePoolImport name: vllm-llama3-8b-instruct default: timeoutSec: 600 balancingMode: CUSTOM_METRICS trafficDuration: LONG customMetrics: - name: gke.named_metrics.kv-cache maxUtilizationPercent: 80 dryRun: false scopes: - selector: gke.io/region: "us-east4" backendPreference: PREFERREDApplica la nuova policy:
kubectl apply -f backend-policy.yaml --context=CLUSTER1_CONTEXTSostituisci
CLUSTER1_CONTEXTcon il contesto per il primo cluster, ad esempiogke_my-project_europe-west3-c_gke-west.
Configura scalabilità automatica
Per garantire che ogni cluster possa gestire un carico crescente prima che il traffico si riversi in altre regioni, devi configurare Horizontal-Pod-Autoscaler (HPA) per i deployment del server di modelli.
Principi di configurazione chiave
Utilizza le stesse metriche personalizzate: l'HPA deve essere configurato per scalare in base alle stesse metriche personalizzate utilizzate in
GCPBackendPolicyper il gateway di inferenza multicluster (ad esempio,vllm:kv_cache_usage_perc). Questo approccio contribuisce a garantire che le decisioni relative al bilanciamento del carico e allo scaling siano basate sullo stesso segnale dei server di inferenza. Le metriche scelte devono avere un valore compreso tra 0 e 1 per rappresentare l'utilizzo. Se il valore della metrica è maggiore di 1, viene interpretato come un utilizzo del 100% da parte del bilanciatore del carico, il che può causare comportamenti di routing imprevisti.Imposta un target HPA inferiore: il valore target per la metrica nella configurazione HPA deve essere impostato su un valore inferiore all'impostazione
maxUtilizationPercentdefinita inGCPBackendPolicy. Impostando un utilizzo target inferiore per l'HPA (ad esempio, l'HPA scala con un utilizzo medio del 50%), consenti al cluster di aggiungere più repliche prima che venga raggiunta la soglia del bilanciatore del carico (ad esempio, un utilizzo dell'80%). Questo approccio consente di massimizzare la capacità all'interno della regione preferita. Un target di utilizzo inferiore contribuisce anche a prevenire lo spillover prematuro del traffico riservando l'alta affidabilità cross-region elastica per quando la regione attuale si avvicina realmente ai suoi limiti.
Concedi all'utente la possibilità di creare i ruoli di autorizzazione richiesti:
kubectl create clusterrolebinding cluster-admin-binding \ --clusterrole cluster-admin --user "$(gcloud config get-value account)" --context=CLUSTER1_CONTEXT kubectl create clusterrolebinding cluster-admin-binding \ --clusterrole cluster-admin --user "$(gcloud config get-value account)" --context=CLUSTER2_CONTEXTLe variabili
CLUSTER1_CONTEXTeCLUSTER2_CONTEXTsono definite nella sezione Installa le risorse personalizzate richieste.Per ogni cluster, applica il manifest:
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/k8s-stackdriver/master/custom-metrics-stackdriver-adapter/deploy/production/adapter_new_resource_model.yaml --context=CLUSTER1_CONTEXT kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/k8s-stackdriver/master/custom-metrics-stackdriver-adapter/deploy/production/adapter_new_resource_model.yaml --context=CLUSTER2_CONTEXTConsenti al account di servizio
custom-metrics-stackdriver-adapterdi leggere le metriche di Cloud Monitoring:PROJECT_NUMBER=$(gcloud projects describe PROJECT_ID --format="value(projectNumber)") gcloud projects add-iam-policy-binding projects/PROJECT_ID \ --role roles/monitoring.viewer \ --member=principal://iam.googleapis.com/projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.s3ns.svc.id.goog/subject/ns/custom-metrics/sa/custom-metrics-stackdriver-adapterSostituisci
PROJECT_IDcon l'ID progetto.Salva il seguente manifest in un file denominato
pod-monitoring.yaml:apiVersion: monitoring.googleapis.com/v1 kind: PodMonitoring metadata: name: inference-server-podmon spec: selector: matchLabels: app: vllm-llama3-8b-instruct endpoints: - port: 8000 path: /metrics interval: 5sApplica il manifest a entrambi i cluster:
kubectl apply -f pod-monitoring.yaml --context=CLUSTER1_CONTEXT kubectl apply -f pod-monitoring.yaml --context=CLUSTER2_CONTEXTSalva il seguente manifest in un file denominato
hpa.yaml:apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: inference-server-hpa spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: vllm-llama3-8b-instruct minReplicas: 1 maxReplicas: 10 metrics: - type: Pods pods: metric: name: prometheus.googleapis.com|vllm:gpu_cache_usage_perc|gauge target: type: AverageValue averageValue: "0.5"Applica il manifest a entrambi i cluster:
kubectl apply -f hpa.yaml --context=CLUSTER1_CONTEXT kubectl apply -f hpa.yaml --context=CLUSTER2_CONTEXT
Verifica il deployment
Ottieni l'indirizzo IP del gateway:
export GW_IP=$(kubectl get gateway/cross-region-gateway -n default --context=CLUSTER1_CONTEXT -o jsonpath='{.status.addresses[0].value}') echo ${GW_IP}La variabile
CLUSTER1_CONTEXTè definita nella sezione Installa le risorse personalizzate richieste.Avvia una sessione
shinterattiva in un pod temporaneo:kubectl run -it --rm --image=curlimages/curl curly --context=CLUSTER1_CONTEXT -- /bin/shLa variabile
CLUSTER1_CONTEXTè definita nella sezione Installa le risorse personalizzate richieste.Dall'interno del pod
curly, invia una richiesta di test:curl -i -X POST <var>GW_IP</var>:80/v1/completions \ -H 'Content-Type: application/json' \ -d '{ "model": "food-review-1", "prompt": "What is the best pizza in the world?", "max_tokens": 100, "temperature": 0 }'Sostituisci
GW_IPcon l'indirizzo IP del gateway del passaggio precedente.
Esegui il test di carico del gateway
Applica un carico sostenuto all'indirizzo IP del gateway utilizzando un generatore di carico all'interno della stessa rete VPC.
Inizia con un carico moderato che prevedi che la regione preferita (
us-east4) gestisca.Aumenta gradualmente il tasso di richieste o la concorrenza del test di carico.
Durante l'esecuzione del test di carico, monitora il sistema nella console Cloud de Confiance o utilizzando
kubectl:- Scalabilità dei pod (HPA): controlla il numero di pod nel deployment
vllm-llama3-8b-instructin entrambi i cluster. - Scalabilità dei nodi (gestore della scalabilità automatica del cluster): monitora il numero di nodi nei pool di nodi
h100in entrambi i cluster. - Metriche personalizzate: monitora la metrica
vllm:kv_cache_usage_perc(per vllm versione v0.10.2 e successive) o la metricavllm:gpu_cache_usage_perc(per vllm versione precedente alla v.0.10.2) in Monitoring per i deployment del server di modelli in entrambi i cluster. - Metriche del bilanciatore del carico: esamina le metriche del bilanciatore del carico
associato a
cross-region-gatewayin Monitoring.
- Scalabilità dei pod (HPA): controlla il numero di pod nel deployment
Man mano che aumenti il carico, l'utilizzo in us-east4 aumenta. Quando l'HPA nel cluster gke-east fa lo scale out e l'utilizzo medio si avvicina al valore maxUtilization (80%) definito in GCPBackendPolicy, il bilanciatore del carico inizia a instradare le richieste al cluster gke-west in europe-west3.
Passaggi successivi
- Scopri di più sull'API GKE Gateway.
- Scopri di più sul gateway di inferenza multicluster GKE.
- Scopri di più su Ingress multi-cluster.