Questo documento mostra come configurare l'alta affidabilità elastica tra regioni per i carichi di lavoro di inferenza AI utilizzando Google Kubernetes Engine (GKE) Multi-Cluster Inference Gateway e la funzionalità di scalabilità automatica di GKE. Questa configurazione consente di bilanciare in modo intelligente il carico dei carichi di lavoro su 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 utilizzarlo per questa attività.
Assicurati che il tuo progetto disponga di una quota sufficiente per le GPU H100. Per saperne di più, consulta Quota GPU e allocazione dellerisorse.
Utilizza la versione 1.34.1-gke.1127000 o successive di GKE.
Utilizza la versione 480.0.0 o successive di gcloud CLI.
Assicurati che il account di servizio utilizzato dai nodi disponga delle autorizzazioni
roles/monitoring.metricWritereroles/stackdriver.resourceMetadata.writer.Assicurati di disporre dei ruoli Identity and Access Management (IAM)
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 di lettura.
Creare cluster e pool di nodi
Per creare due cluster GKE in regioni diverse e configurare i relativi pool di nodi:
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 pool di nodi, 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 nel pool di nodi, ad esempio10
Recupera le credenziali e crea un secret del token di 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 pool di nodi, 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 nel pool di nodi, ad esempio10
Recupera le credenziali e crea un secret per il token di Hugging Face nel 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 tuo token di accesso a Hugging Face
Registrare i cluster in un parco risorse
Registra i cluster nel parco risorse del tuo 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 consulta i 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
Abilita 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
Creare 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 riesce. Devi prima eliminare la subnet solo proxy regionale esistente. L'eliminazione di una subnet solo proxy regionale influisce su tutti i bilanciatori del carico regionali basati su Envoy in quella 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 per la 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 del secondo cluster, ad esempious-east4SUBNET_RANGE_2: l'intervallo IP della subnet per la subnet solo proxy nella regione del secondo cluster, ad esempio10.5.0.0/23
Installare le risorse personalizzate richieste
Definisci le variabili di contesto per i 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
Eseguire 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: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
Eseguire il deployment di Inference Gateway 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
Abilitare 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 Installare le risorse personalizzate richieste.
Configurare la policy di bilanciamento del carico
Questa sezione descrive come configurare la policy di bilanciamento del carico. Questa policy definisce la modalità di distribuzione del traffico tra i pool di inferenza in base alle metriche personalizzate e alle preferenze regionali. La seguente configurazione imposta us-east4 come regione preferita. Il traffico viene trasferito ad 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 del primo cluster, ad esempiogke_my-project_europe-west3-c_gke-west
Configurare la scalabilità automatica
Per assicurarti che ogni cluster possa gestire un carico crescente prima che il traffico venga trasferito ad altre regioni, devi configurare HorizontalPodAutoscaler (HPA) per i deployment del server di modelli.
Principi di configurazione chiave
Utilizza le stesse metriche personalizzate: HPA deve essere configurato per scalare in base alle stesse metriche personalizzate utilizzate in
GCPBackendPolicyper il Multi-Cluster Inference Gateway (ad esempio,vllm:kv_cache_usage_perc). Questo approccio consente di garantire che le decisioni di bilanciamento del carico e di scalabilità 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, il bilanciatore del carico lo interpreta come utilizzo del 100%, il che può causare comportamenti di routing imprevisti.Imposta un target HPA inferiore: il valore target della metrica nella configurazione HPA deve essere impostato su un valore inferiore all'impostazione
maxUtilizationPercentdefinita inGCPBackendPolicy. Impostando un utilizzo target inferiore per HPA (ad esempio, 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, utilizzo dell'80%). Questo approccio consente di massimizzare la capacità all'interno della regione preferita. Un target di utilizzo inferiore contribuisce anche a impedire il trasferimento prematuro del traffico riservando l'alta affidabilità elastica tra regioni per quando la regione corrente si avvicina effettivamente 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 Install the required custom resources.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 il tuo ID progettoSalva 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
Verificare il deployment
Recupera 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 Installare 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 Installare 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.
Eseguire 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) possa gestire.Aumenta gradualmente il tasso di richieste o la concorrenza del test di carico.
Durante l'esecuzione del test di carico, monitora il sistema nella Cloud de Confiance console o utilizzando
kubectl:- Scalabilità dei pod (HPA): controlla il numero di pod nel deployment
vllm-llama3-8b-instructin entrambi i cluster. - Scalabilità dei nodi (scalabilità automatica dei cluster): monitora il numero di nodi nei
pool di nodi
h100in entrambi i cluster. - Metriche personalizzate: osserva la metrica
vllm:kv_cache_usage_perc(per la versione vllm v0.10.2 e successive) o la metricavllm:gpu_cache_usage_perc(per la versione vllm 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 HPA nel cluster gke-east esegue 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ù su GKE Multi-Cluster Inference Gateway.
- Scopri di più su Ingress multi-cluster.