Questo tutorial mostra come ridurre la scalabilità dei workload GKE a zero pod utilizzando KEDA. Il ridimensionamento dei deployment a zero pod consente di risparmiare risorse durante i periodi di inattività (come i fine settimana e l'orario non lavorativo) o per i workload intermittenti, come i job periodici.
Obiettivi
Questo tutorial descrive i seguenti casi d'uso:
- Scala il carico di lavoro Pub/Sub a zero: scala il numero di pod in proporzione al numero di messaggi in coda nell'argomento Pub/Sub. Quando la coda è vuota, il carico di lavoro viene ridimensionato automaticamente a zero pod.
- Scala il carico di lavoro LLM a zero. Esegui il deployment dei server di modelli LLM sui nodi con GPU. Quando il servizio è inattivo, il workload viene ridotto automaticamente a zero pod.
Costi
In questo documento vengono utilizzati i seguenti componenti fatturabili di Google Cloud:
- GKE
- GPU resources used by GKE
- Pub/Sub
Per generare una stima dei costi in base all'utilizzo previsto,
utilizza il Calcolatore prezzi.
Al termine delle attività descritte in questo documento, puoi evitare l'addebito di ulteriori costi eliminando le risorse che hai creato. Per saperne di più, consulta Esegui la pulizia.
Prima di iniziare
In questo tutorial utilizzerai Cloud Shell per eseguire i comandi. Cloud Shell è un ambiente shell per la gestione delle risorse ospitate su Google Cloud. È preinstallato con gli strumenti a riga di comando Google Cloud CLI, kubectl, Helm e Terraform. Se non utilizzi Cloud Shell, devi installare Google Cloud CLI e Helm.
-
Per eseguire i comandi in questa pagina, configura gcloud CLI in uno dei seguenti ambienti di sviluppo:
Cloud Shell
Per utilizzare un terminale online con gcloud CLI già configurata, attiva Cloud Shell:
Nella parte inferiore di questa pagina viene avviata una sessione di Cloud Shell e viene visualizzato un prompt della riga di comando. L'inizializzazione della sessione può richiedere alcuni secondi.
Shell locale
Per utilizzare un ambiente di sviluppo locale:
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
-
Enable the Resource Manager, Compute Engine, GKE, Pub/Sub APIs.
Roles required to enable APIs
To enable APIs, you need the Service Usage Admin IAM role (
roles/serviceusage.serviceUsageAdmin), which contains theserviceusage.services.enablepermission. Learn how to grant roles. -
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
-
Enable the Resource Manager, Compute Engine, GKE, Pub/Sub APIs.
Roles required to enable APIs
To enable APIs, you need the Service Usage Admin IAM role (
roles/serviceusage.serviceUsageAdmin), which contains theserviceusage.services.enablepermission. Learn how to grant roles. Imposta le variabili di ambiente:
export PROJECT_ID=PROJECT_ID export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format 'get(projectNumber)') export LOCATION=LOCATIONSostituisci
PROJECT_IDcon il tuo Google Cloud ID progetto eLOCATIONcon le regioni o zone in cui deve essere creato il tuo cluster GKE.Se non segui l'intero tutorial in una sola sessione o se le variabili di ambiente non sono impostate per qualche motivo, assicurati di eseguire di nuovo questo comando per impostarle di nuovo.
Crea un cluster GKE Standard con scalabilità automatica del cluster e federazione delle identità per i carichi di lavoro per GKE abilitata:
gcloud container clusters create scale-to-zero \ --project=${PROJECT_ID} --location=${LOCATION} \ --machine-type=n1-standard-2 \ --enable-autoscaling --min-nodes=1 --max-nodes=5 \ --workload-pool=${PROJECT_ID}.svc.id.googCrea la risorsa
ScaledObjectper descrivere il comportamento previsto della scalabilità automatica:curl https://raw.githubusercontent.com/GoogleCloudPlatform/kubernetes-engine-samples/refs/heads/main/cost-optimization/gke-keda/cloud-pubsub/deployment/keda-pubsub-scaledobject.yaml | envsubst | kubectl apply -f -Viene creato il seguente oggetto:
apiVersion: keda.sh/v1alpha1 kind: ScaledObject metadata: name: keda-pubsub namespace: keda-pubsub spec: maxReplicaCount: 5 scaleTargetRef: name: keda-pubsub triggers: - type: gcp-pubsub authenticationRef: name: keda-auth metadata: subscriptionName: "projects/${PROJECT_ID}/subscriptions/keda-echo-read"Esamina l'oggetto
HorizontalPodAutoscaler(HPA) creato da KEDA in base all'oggettoScaledObject:kubectl get hpa keda-hpa-keda-pubsub -n keda-pubsub -o yamlPer saperne di più sulla scalabilità automatica, consulta la documentazione di Kubernetes.
Attendi che KEDA riconosca che l'abbonamento Pub/Sub è vuoto e che aumenti il deployment a zero repliche.
Ispeziona il gestore della scalabilità automatica del workload:
kubectl describe hpa keda-hpa-keda-pubsub -n keda-pubsubNota che nella risposta al comando, la condizione
ScalingActiveè false. Il messaggio associato mostra che Horizontal Pod Autoscaler riconosce che KEDA ha scalato il deployment a zero, a quel punto smette di funzionare finché il deployment non viene scalato di nuovo a un pod.Name: keda-hpa-keda-pubsub Namespace: keda-pubsub Metrics: ( current / target ) "s0-gcp-ps-projects-[...]]" (target average value): 0 / 10 Min replicas: 1 Max replicas: 5 Deployment pods: 5 current / 5 desired Conditions: Type Status Reason Message ---- ------ ------ ------- AbleToScale True ScaleDownStabilized recent recommendations were higher than current one [...] ScalingActive False ScalingDisabled scaling is disabled since the replica count of the target is zero ScalingLimited True TooManyReplicas the desired replica count is more than the maximum replica countMetti in coda i messaggi nell'argomento Pub/Sub:
for num in {1..20} do gcloud pubsub topics publish keda-echo --project=${PROJECT_ID} --message="Test" doneVerifica che il deployment stia aumentando:
kubectl get deployments -n keda-pubsubNell'output, osserva che la colonna "Pronto" mostra una replica:
NAME READY UP-TO-DATE AVAILABLE AGE keda-pubsub 1/1 1 1 2dCrea un pool di nodi contenente
g2-standard-4nodi con GPU collegate e configura la scalabilità automatica del cluster in modo da fornire da zero a due nodi:gcloud container node-pools create gpu --machine-type=g2-standard-4 \ --location=${LOCATION} --cluster=scale-to-zero \ --min-nodes 0 --max-nodes 2 --num-nodes=1 --enable-autoscalingAggiungi il repository ufficiale del grafico Helm di Ollama e aggiorna il repository del client Helm locale:
helm repo add ollama-helm https://otwld.github.io/ollama-helm/ helm repo updateEsegui il deployment del server Ollama utilizzando il grafico Helm:
helm install ollama ollama-helm/ollama --create-namespace --namespace ollama \ -f https://raw.githubusercontent.com/GoogleCloudPlatform/kubernetes-engine-samples/refs/heads/main/cost-optimization/gke-keda/ollama/helm-values-ollama.yamlLa configurazione
helm-values-ollama.yamlspecifica i modelli LLM da caricare, i requisiti della GPU e la porta TCP per il server Ollama.Crea la risorsa
HTTPScaledObjectper descrivere il comportamento previsto della scalabilità automatica:kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/kubernetes-engine-samples/refs/heads/main/cost-optimization/gke-keda/ollama/keda-ollama-httpscaledobject.yamlIn questo modo viene creato l'oggetto
HTTPScaledObjectche definisce i seguenti campi:scaleTargetRef: specifica il servizio a cui KEDA-HTTP deve inoltrare le richieste. In questo esempio, tutte le richieste con l'hostollama.ollamavengono indirizzate al server Ollama.scaledownPeriod: specifica (in secondi) la velocità di fare lo scale down quando non vengono ricevute richieste.replicas: specifica il numero minimo e massimo di pod da mantenere per il deployment di Ollama.scalingMetric: specifica le metriche utilizzate per la scalabilità automatica, ad esempio latasso di richiestee in questo esempio. Per ulteriori opzioni di metrica, consulta la documentazione di KEDA-HTTP.
kind: HTTPScaledObject apiVersion: http.keda.sh/v1alpha1 metadata: namespace: ollama name: ollama spec: hosts: - ollama.ollama scaleTargetRef: name: ollama kind: Deployment apiVersion: apps/v1 service: ollama port: 11434 replicas: min: 0 max: 2 scaledownPeriod: 3600 scalingMetric: requestRate: targetValue: 20Esegui questo comando per verificare che KEDA-HTTP abbia elaborato correttamente
HTTPScaledObjectcreato nel passaggio precedente:kubectl get hpa,scaledobject -n ollamaL'output mostra le risorse
HorizontalPodAutoscaler(create da KEDA) eScaledObject(create da KEDA-HTTP):NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE horizontalpodautoscaler.autoscaling/keda-hpa-ollama Deployment/ollama 0/100 (avg) 1 2 1 2d NAME SCALETARGETKIND SCALETARGETNAME MIN MAX TRIGGERS AUTHENTICATION READY ACTIVE FALLBACK PAUSED AGE scaledobject.keda.sh/ollama apps/v1.Deployment ollama 0 2 external-push True False False Unknown 2dVerifica che il deployment venga ridotto a zero pod.
Attendi il periodo di tempo impostato nel campo
scaledownPerioded esegui il comando:kubectl get deployments -n ollamaL'output mostra che KEDA ha ridotto lo scale down del deployment di Ollama e che non sono in esecuzione pod:
NAME READY UP-TO-DATE AVAILABLE AGE ollama 0/0 0 0 2dEsegui la pulizia dell'argomento e della sottoscrizione Pub/Sub:
gcloud pubsub subscriptions delete keda-echo-read gcloud pubsub topics delete keda-echoElimina il cluster GKE:
gcloud container clusters delete scale-to-zero --location=${LOCATION}- Scopri di più sulla scalabilità automatica dei workload di inferenza LLM in GKE.
- Esplora il repository GitHub e la documentazione di KEDA.
Configurazione dell'ambiente
Per configurare l'ambiente con Cloud Shell:
Installa KEDA
KEDA è un componente che integra la scalabilità automatica pod orizzontale di Kubernetes. Con KEDA, puoi scalare un deployment a zero pod e da zero pod a un pod. Un deployment è un oggetto API Kubernetes che ti consente di eseguire più repliche di pod distribuite tra i nodi di un cluster. L'algoritmo Horizontal Pod Autoscaler standard viene applicato dopo che GKE ha creato almeno un pod.
Dopo che GKE ha scalato il deployment a zero pod, poiché non sono in esecuzione pod, la scalabilità automatica non può fare affidamento sulle metriche dei pod, come l'utilizzo della CPU. Di conseguenza, KEDA consente di recuperare le metriche provenienti dall'esterno del cluster utilizzando un'implementazione dell'API External Metrics di Kubernetes. Puoi utilizzare questa API per la scalabilità automatica in base a metriche come il numero di messaggi in attesa in una sottoscrizione Pub/Sub. Consulta la documentazione di KEDA per un elenco di tutte le origini delle metriche supportate.
Installa KEDA sul tuo cluster con Helm o con kubectl.
Helm
Esegui i seguenti comandi per aggiungere il repository Helm di KEDA, installare il grafico Helm di KEDA e concedere all'account di servizio KEDA l'accesso in lettura a Cloud Monitoring:
helm repo add kedacore https://kedacore.github.io/charts
helm repo update
helm install keda kedacore/keda --create-namespace --namespace keda
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}.svc.id.goog/subject/ns/keda/sa/keda-operator
Tieni presente che questo comando configura anche le regole di autorizzazione che richiedono la configurazione del cluster con la federazione delle identità per i carichi di lavoro per GKE.
kubectl
Esegui questi comandi per installare KEDA utilizzando kubectl apply e per concedere
all'account di servizio KEDA l'accesso in lettura a Cloud Monitoring:
kubectl apply --server-side -f https://github.com/kedacore/keda/releases/download/v2.15.1/keda-2.15.1.yaml
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}.svc.id.goog/subject/ns/keda/sa/keda-operator
Tieni presente che questo comando configura anche le regole di autorizzazione che richiedono la configurazione del cluster con la federazione delle identità per i carichi di lavoro per GKE.
Verifica che tutte le risorse KEDA vengano visualizzate nello spazio dei nomi keda:
kubectl get all -n keda
Per ulteriori informazioni sulla progettazione e sulle risorse di KEDA, consulta la documentazione di KEDA.
Scalare il carico di lavoro Pub/Sub fino a zero
Questa sezione descrive un carico di lavoro che elabora i messaggi di una sottoscrizione Pub/Sub, gestendo ogni messaggio e confermando il completamento. Il carico di lavoro viene scalato in modo dinamico: man mano che aumenta il numero di messaggi non riconosciuti, la scalabilità automatica crea più pod per garantire l'elaborazione tempestiva.
Lo scale-to-zero garantisce che non vengano create istanze di pod quando non vengono ricevuti messaggi per un po' di tempo. In questo modo, si risparmiano risorse perché nessun pod rimane inattivo per lunghi periodi di tempo.
Esegui il deployment di un carico di lavoro Pub/Sub
Esegui il deployment di un carico di lavoro di esempio che elabora i messaggi in coda in un argomento Pub/Sub. Per simulare un carico di lavoro realistico, questo programma di esempio attende tre secondi
prima di riconoscere un messaggio. Il carico di lavoro è configurato per essere eseguito con l'account di servizio
keda-pubsub-sa.
Esegui i seguenti comandi per creare l'argomento e la sottoscrizione Pub/Sub,
configura le relative autorizzazioni e crea il deployment che avvia il carico di lavoro
nello spazio dei nomi keda-pubsub.
gcloud pubsub topics create keda-echo
gcloud pubsub subscriptions create keda-echo-read --topic=keda-echo
gcloud projects add-iam-policy-binding projects/${PROJECT_ID} \
--role=roles/pubsub.subscriber \
--member=principal://iam.googleapis.com/projects/${PROJECT_NUMBER}/locations/global/workloadIdentityPools/${PROJECT_ID}.svc.id.goog/subject/ns/keda-pubsub/sa/keda-pubsub-sa
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/kubernetes-engine-samples/refs/heads/main/cost-optimization/gke-keda/cloud-pubsub/deployment/keda-pubsub-with-workload-identity.yaml
Configurare la scalabilità fino a zero
Per configurare il workload Pub/Sub in modo che venga scalato a zero, utilizza KEDA per
definire una risorsa ScaledObject per specificare come deve essere scalato il deployment.
KEDA creerà e gestirà automaticamente l'oggetto
HorizontalPodAutoscaler (HPA) sottostante.
Attivare lo scale up
Per stimolare lo scale up del deployment:
KEDA aumenta le dimensioni del deployment dopo aver osservato che la coda non è vuota.
Scalare a zero il carico di lavoro LLM
Questa sezione descrive un workload di modello linguistico di grandi dimensioni (LLM) che esegue il deployment di un server Ollama con GPU collegata. Ollama consente di eseguire LLM popolari come Gemma e Llama 2 ed espone le sue funzionalità principalmente tramite HTTP.
Installa il componente aggiuntivo KEDA-HTTP
La riduzione di un servizio HTTP a zero pod durante i periodi di inattività causa errori di richiesta, poiché non esiste un backend per gestire le richieste.
Questa sezione mostra come risolvere il problema utilizzando il componente aggiuntivo KEDA-HTTP. KEDA-HTTP avvia un proxy HTTP che riceve le richieste degli utenti e le inoltra ai servizi configurati per lo scale-to-zero. Quando il servizio non ha pod, il proxy attiva lo scale up del servizio e memorizza nel buffer la richiesta finché il servizio non è stato scalato fino ad almeno un pod.
Installa il componente aggiuntivo KEDA-HTTP utilizzando Helm. Per saperne di più, consulta la documentazione di KEDA-HTTP.
helm repo add ollama-helm https://otwld.github.io/ollama-helm/
helm repo update
# Set the proxy timeout to 120s, giving Ollama time to start.
helm install http-add-on kedacore/keda-add-ons-http \
--create-namespace --namespace keda \
--set interceptor.responseHeaderTimeout=120s
Esegui il deployment di un carico di lavoro LLM Ollama
Per eseguire il deployment di un carico di lavoro LLM Ollama:
Configurare la scalabilità fino a zero
Per configurare il tuo workload Ollama in modo che venga scalato a zero, KEDA-HTTP utilizza un
HTTPScaledObject.
Attivare lo scale up
Per stimolare lo scale up del deployment, chiama il servizio Ollama utilizzando il proxy configurato dal componente aggiuntivo KEDA-HTTP. Ciò fa aumentare il valore della metrica Tasso di richieste e attiva la creazione di un primo pod.
Utilizza le funzionalità di port forwarding di kubectl per accedere al proxy perché il proxy
non è esposto esternamente.
kubectl port-forward svc/keda-add-ons-http-interceptor-proxy -n keda 8080:8080 &
# Set the 'Host' HTTP header so that the proxy routes requests to the Ollama server.
curl -H "Host: ollama.ollama" \
http://localhost:8080/api/generate \
-d '{ "model": "gemma:7b", "prompt": "Hello!" }'
Il comando curl invia il prompt "Hello!" a un modello Gemma. Osserva
i token di risposta che vengono restituiti nella risposta. Per le specifiche dell'API,
consulta la guida di Ollama.
Esegui la pulizia
Per evitare che al tuo account Google Cloud vengano addebitati costi relativi alle risorse utilizzate in questo tutorial, elimina il progetto che contiene le risorse oppure mantieni il progetto ed elimina le singole risorse.