En este instructivo, se muestra cómo reducir la escala de tus cargas de trabajo de GKE a cero pods con KEDA. Si reduces la escala de las implementaciones a cero pods, se ahorran recursos durante los períodos de inactividad (como los fines de semana y los horarios fuera de la oficina) o para las cargas de trabajo intermitentes, como los trabajos periódicos.
Objetivos
En este instructivo, se describen los siguientes casos de uso:
- Reduce la escala de tu carga de trabajo de Pub/Sub a cero: Escala la cantidad de pods en proporción a la cantidad de mensajes en cola en el tema de Pub/Sub. Cuando la cola está vacía, la carga de trabajo se reduce automáticamente a cero pods.
- Reduce la escala de tu carga de trabajo de LLM a cero. Implementa tus servidores de modelos de LLM en nodos con GPU. Cuando el servicio está inactivo, la carga de trabajo se reduce automáticamente a cero pods.
Costos
En este documento, usarás los siguientes componentes facturables de Google Cloud:
- GKE
- GPU resources used by GKE
- Pub/Sub
Para generar una estimación de costos en función del uso previsto,
usa la calculadora de precios.
Cuando completes las tareas que se describen en este documento, podrás borrar los recursos que creaste para evitar que se te siga facturando. Para obtener más información, consulta Realiza una limpieza.
Antes de comenzar
En este instructivo, usarás Cloud Shell para ejecutar comandos. Cloud Shell es un entorno de shell que se usa para administrar recursos alojados en Google Cloud. Viene preinstalado con las herramientas de línea de comando de Google Cloud CLI, kubectl, Helm y Terraform. Si no usas Cloud Shell, debes instalar Google Cloud CLI y Helm.
-
Para ejecutar los comandos de esta página, configura gcloud CLI en uno de los siguientes entornos de desarrollo:
Cloud Shell
Para usar una terminal en línea con gcloud CLI ya configurada, activa Cloud Shell.
En la parte inferior de esta página, se inicia una sesión de Cloud Shell y se muestra una ventana de línea de comandos. La sesión puede tardar unos segundos en inicializarse.
Shell local
Para usar un entorno de desarrollo local, sigue estos pasos:
- Accede a tu Google Cloud cuenta de. Si eres nuevo en Google Cloud, crea una cuenta para evaluar el rendimiento de nuestros productos en situaciones reales. Los clientes nuevos también obtienen $300 en créditos gratuitos para ejecutar, probar y, además, implementar cargas de trabajo.
-
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.
Configura tu entorno
Para configurar tu entorno con Cloud Shell, sigue estos pasos:
Establece las variables de entorno:
export PROJECT_ID=PROJECT_ID export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format 'get(projectNumber)') export LOCATION=LOCATIONReemplaza
PROJECT_IDpor tu Google Cloud ID del proyecto yLOCATIONpor las regiones o zonas en las que se debe crear tu clúster de GKE.Si no sigues todo el instructivo en una sola sesión o si las variables de entorno no están configuradas por algún motivo, asegúrate de volver a ejecutar este comando para volver a establecer las variables.
Crea un clúster de GKE estándar con el ajuste de escala automático del clúster y la federación de identidades para cargas de trabajo para GKE habilitados:
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.goog
Instala KEDA
KEDA es un componente que complementa el escalador automático de pods horizontal de Kubernetes. Con KEDA, puedes reducir la escala de una Deployment a cero pods y aumentarla de cero pods a un pod. Una implementación es un objeto de la API de Kubernetes que te permite ejecutar varias réplicas de pods que se distribuyen entre los nodos de un clúster. El algoritmo estándar del escalador automático de pods horizontal se aplica después de que GKE crea al menos un pod.
Después de que GKE reduce la escala de la Deployment a cero pods, debido a que no se ejecutan pods, el ajuste de escala automático no puede depender de las métricas de pods, como el uso de CPU. Como consecuencia, KEDA permite recuperar métricas que se originan fuera del clúster mediante una implementación de la API de métricas externas de Kubernetes. Puedes usar esta API para realizar el ajuste de escala automático en función de métricas como la cantidad de mensajes pendientes en una suscripción de Pub/Sub. Consulta la documentación de KEDA para obtener una lista de todas las fuentes de métricas admitidas.
Instala KEDA en tu clúster con Helm o con kubectl.
Helm
Ejecuta los siguientes comandos para agregar el repositorio de Helm de KEDA, instalar el gráfico de Helm de KEDA y otorgar a la cuenta de servicio de KEDA acceso de lectura 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
Ten en cuenta que este comando también configura reglas de autorización que requieren que el clúster se configure con la federación de identidades para cargas de trabajo para GKE.
kubectl
Ejecuta los siguientes comandos para instalar KEDA con kubectl apply y otorgar a la cuenta de servicio de KEDA acceso de lectura 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
Ten en cuenta que este comando también configura reglas de autorización que requieren que el clúster se configure con la federación de identidades para cargas de trabajo para GKE.
Confirma que todos los recursos de KEDA aparezcan en el espacio de nombres keda:
kubectl get all -n keda
Para obtener más información sobre el diseño y los recursos de KEDA, consulta la documentación de KEDA.
Reduce la escala de tu carga de trabajo de Pub/Sub a cero
En esta sección, se describe una carga de trabajo que procesa mensajes de una suscripción de Pub/Sub, controla cada mensaje y confirma su finalización. La carga de trabajo se escala de forma dinámica: a medida que aumenta la cantidad de mensajes no confirmados, el ajuste de escala automático crea más pods para garantizar el procesamiento oportuno.
La reducción de escala a cero garantiza que no se creen pods cuando no se hayan recibido mensajes durante un tiempo. Esto ahorra recursos, ya que ningún pod permanece inactivo durante períodos prolongados.
Implementa una carga de trabajo de Pub/Sub
Implementa una carga de trabajo de muestra que procese los mensajes en cola en un tema de Pub/Sub. Para simular una carga de trabajo realista, este programa de muestra espera tres segundos antes de confirmar un mensaje. La carga de trabajo está configurada para ejecutarse con la cuenta de servicio keda-pubsub-sa.
Ejecuta los siguientes comandos para crear el tema y la suscripción de Pub/Sub, configurar su permiso y crear la Deployment que inicia la carga de trabajo en el espacio de nombres 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
Configura la reducción de escala a cero
Para configurar tu carga de trabajo de Pub/Sub para que se reduzca a cero, usa KEDA para definir un recurso ScaledObject que especifique cómo se debe escalar la implementación.
Luego, KEDA creará y administrará automáticamente el objeto HorizontalPodAutoscaler (HPA) subyacente.
Crea el recurso
ScaledObjectpara describir el comportamiento esperado del ajuste de escala automático: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 -Esto crea el siguiente objeto:
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"Inspecciona el objeto
HorizontalPodAutoscaler(HPA) que KEDA crea en función del objetoScaledObject:kubectl get hpa keda-hpa-keda-pubsub -n keda-pubsub -o yamlPuedes leer más sobre el ajuste de escala automático en la documentación de Kubernetes.
Espera hasta que KEDA confirme que la suscripción de Pub/Sub está vacía y reduzca la escala de la Deployment a cero réplicas.
Inspecciona el escalador automático de la carga de trabajo:
kubectl describe hpa keda-hpa-keda-pubsub -n keda-pubsubObserva que, en la respuesta del comando, la condición
ScalingActivees falsa. El mensaje asociado muestra que el Horizontal Pod Autoscaler confirma que KEDA redujo la escala de la implementación a cero, momento en el que deja de funcionar hasta que la Deployment vuelva a aumentar 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 count
Activa el aumento de escala
Para estimular el aumento de escala de la Deployment, haz lo siguiente:
Pone en cola los mensajes en el tema de Pub/Sub:
for num in {1..20} do gcloud pubsub topics publish keda-echo --project=${PROJECT_ID} --message="Test" doneVerifica que la Deployment esté aumentando de escala:
kubectl get deployments -n keda-pubsubEn el resultado, observa que la columna “Ready” muestra una réplica:
NAME READY UP-TO-DATE AVAILABLE AGE keda-pubsub 1/1 1 1 2d
KEDA aumenta la escala de la Deployment después de observar que la cola no está vacía.
Reduce la escala de tu carga de trabajo de LLM a cero
En esta sección, se describe una carga de trabajo de modelo de lenguaje grande (LLM) que implementa un servidor de Ollama con una GPU adjunta. Ollama permite ejecutar LLM populares, como Gemma y Llama 2, y expone sus funciones principalmente a través de HTTP.
Instala el complemento KEDA-HTTP
Si reduces la escala de un servicio HTTP a cero pods durante los períodos de inactividad, se producen errores de solicitud, ya que no hay backend para controlar las solicitudes.
En esta sección, se muestra cómo resolver este problema con el complemento KEDA-HTTP. KEDA-HTTP inicia un proxy HTTP que recibe solicitudes de usuarios y las reenvía a los servicios configurados para reducir la escala a cero. Cuando el servicio no tiene pod, el proxy activa el aumento de escala del servicio y almacena en búfer la solicitud hasta que el servicio haya aumentado a al menos un pod.
Instala el complemento KEDA-HTTP con Helm. Para obtener más información, consulta la documentación de 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
Implementa una carga de trabajo de LLM de Ollama
Para implementar una carga de trabajo de LLM de Ollama, haz lo siguiente:
Crea un grupo de nodos que contenga nodos
g2-standard-4con GPU adjuntas y configura el ajuste de escala automático del clúster para proporcionar entre cero y dos nodos: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-autoscalingAgrega el repositorio oficial de gráficos de Helm de Ollama y actualiza el repositorio de tu cliente de Helm local:
helm repo add ollama-helm https://otwld.github.io/ollama-helm/ helm repo updateImplementa el servidor de Ollama con el gráfico de 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 configuración
helm-values-ollama.yamlespecifica los modelos de LLM que se cargarán, los requisitos de GPU y el puerto TCP para el servidor de Ollama.
Configura la reducción de escala a cero
Para configurar tu carga de trabajo de Ollama para que se reduzca a cero, KEDA-HTTP usa un
HTTPScaledObject.
Crea el recurso
HTTPScaledObjectpara describir el comportamiento esperado del ajuste de escala automático:kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/kubernetes-engine-samples/refs/heads/main/cost-optimization/gke-keda/ollama/keda-ollama-httpscaledobject.yamlEsto crea el objeto
HTTPScaledObjectque define los siguientes campos:scaleTargetRef: Especifica el servicio al que KEDA-HTTP debe reenviar las solicitudes. En este ejemplo, todas las solicitudes con el hostollama.ollamase enrutan al servidor de Ollama.scaledownPeriod: Especifica (en segundos) la velocidad con la que se debe reducir la escala cuando no se reciben solicitudes.replicas: Especifica la cantidad mínima y máxima de pods que se deben mantener para la implementación de Ollama.scalingMetric: Especifica las métricas que se usan para impulsar el ajuste de escala automático, como la tasa de solicitudes en este ejemplo. Para obtener más opciones de métricas, consulta la documentación de 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: 20Ejecuta el siguiente comando para verificar que KEDA-HTTP haya procesado correctamente el
HTTPScaledObjectcreado en el paso anterior:kubectl get hpa,scaledobject -n ollamaEl resultado muestra los recursos
HorizontalPodAutoscaler(creado por KEDA) yScaledObject(creado por 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 que la Deployment se reduzca a cero pods.
Espera el período establecido en el campo
scaledownPeriody ejecuta el comando:kubectl get deployments -n ollamaEl resultado muestra que KEDA redujo la escala de la implementación de Ollama y que no se ejecutan pods:
NAME READY UP-TO-DATE AVAILABLE AGE ollama 0/0 0 0 2d
Activa el aumento de escala
Para estimular el aumento de escala de la Deployment, llama al servicio de Ollama con el proxy configurado por el complemento KEDA-HTTP. Esto hace que aumente el valor de la métrica de tasa de solicitudes y activa la creación de un primer pod.
Usa las capacidades de reenvío de puertos de kubectl para acceder al proxy, ya que no se expone de forma externa.
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!" }'
El comando curl envía la instrucción “Hello!” a un modelo de Gemma. Observa los tokens de respuesta que regresan en la respuesta. Para obtener la especificación de la API,
consulta la guía de Ollama.
Limpia
Para evitar que se apliquen cargos a tu cuenta de Google Cloud por los recursos usados en este instructivo, borra el proyecto que contiene los recursos o conserva el proyecto y borra los recursos individuales.
Limpia la suscripción y el tema de Pub/Sub:
gcloud pubsub subscriptions delete keda-echo-read gcloud pubsub topics delete keda-echoBorra tu clúster de GKE:
gcloud container clusters delete scale-to-zero --location=${LOCATION}
¿Qué sigue?
- Obtén más información sobre el ajuste de escala automático de las cargas de trabajo de inferencia de LLM en GKE.
- Explora el repositorio de GitHub y la documentación de KEDA.