En este instructivo, se explica cómo puedes reducir costos mediante la implementación de un escalador automático programado en Google Kubernetes Engine (GKE). Este tipo de escalador automático aumenta o reduce la escala de los clústeres en función de un programa basado en la hora del día o el día de la semana. Un escalador automático programado es útil si tu tráfico tiene una disminución y un flujo predecibles, por ejemplo, si eres un minorista regional o si tu software es para empleados cuyo horario laboral se limita a una parte específica del día,
El instructivo es para desarrolladores y operadores que deseen escalar verticalmente los clústeres de forma confiable antes de que lleguen los aumentos repentinos, y volver a reducir la escala para ahorrar dinero por la noche, los fines de semana o en cualquier otro momento en el que haya menos usuarios en línea. En el artículo, se supone que estás familiarizado con Docker, Kubernetes, los CronJobs de Kubernetes, GKE y Linux.
Introducción
Muchas aplicaciones experimentan patrones de tráfico desiguales. Por ejemplo, si los trabajadores de una organización interactúan con una aplicación solo durante el día. Como resultado, los servidores de los centros de datos para esa aplicación se encuentran inactivos por la noche.
Más allá de otros beneficios, Google Cloud puede ayudarte a ahorrar dinero, ya que asigna la infraestructura de forma dinámica según la carga de tráfico. En algunos casos, una configuración de ajuste de escala automático simple puede administrar la asignación del tráfico desigual. Si ese es tu caso, usa esa opción. Sin embargo, en otros casos, los cambios abruptos en los patrones de tráfico requieren configuraciones más precisas para el ajuste de escala automático a fin de evitar la inestabilidad del sistema durante los escalamientos verticales y de eludir el aprovisionamiento en exceso del clúster.
En este instructivo, nos enfocaremos en situaciones en las que se conocen bien los cambios abruptos en los patrones de tráfico y se busca indicarle al escalador automático que la infraestructura está a punto de experimentar aumentos repentinos. En este documento, se muestra cómo aumentar verticalmente la escala de los clústeres de GKE a la mañana y reducirla a la noche, pero puedes usar un enfoque similar para aumentar y disminuir la capacidad de cualquier evento conocido, como los eventos de escala máxima, las campañas publicitarias, el tráfico durante el fin de semana, etcétera.
Reduce verticalmente la escala de un clúster si tienes descuentos por compromiso de uso
En este instructivo, se explica cómo disminuir los costos si reduces verticalmente la escala de tus clústeres de GKE al mínimo durante las horas de menor demanda. Sin embargo, si compraste un descuento por compromiso de uso, es importante comprender cómo funcionan estos descuentos junto con el ajuste de escala automático.
Los contratos de compromiso de uso te brindan precios muy reducidos si te comprometes a pagar por una cantidad determinada de recursos (CPU virtuales, memoria y otros). Sin embargo, a fin de determinar la cantidad de recursos para los que te comprometerás, debes saber de antemano cuántos recursos usan tus cargas de trabajo a lo largo del tiempo. Para ayudarte a reducir los costos, en el siguiente diagrama, se muestran los recursos que debes incluir y los que no en la planificación.
Como se muestra en el diagrama, la asignación de recursos en un contrato de compromiso de uso es fija. Los recursos que incluye el contrato deben estar en uso la mayor parte del tiempo para que el compromiso valga la pena. Por lo tanto, no debes incluir recursos que se usen durante los aumentos repentinos en el cálculo de tus recursos del compromiso. Para los recursos de los aumentos, te recomendamos que uses las opciones del escalador automático de GKE. Estas opciones incluyen el escalador automático programado que se analiza en este documento y otras opciones administradas que se analizan en Prácticas recomendadas para ejecutar aplicaciones de Kubernetes con optimización de costos en GKE.
Si ya tienes un contrato de compromiso de uso para una cantidad determinada de recursos, no disminuirás los costos si reduces verticalmente la escala de tu clúster por debajo de ese mínimo. En esas situaciones, te recomendamos que intentes programar algunos trabajos para llenar los vacíos durante los períodos de baja demanda de procesamiento.
Arquitectura
En el siguiente diagrama, se muestra la arquitectura de la infraestructura y el escalador automático programado que se implementa en este instructivo. El escalador automático programado consta de un conjunto de componentes que funcionan en conjunto para administrar el escalamiento en función de un programa.
En esta arquitectura, un conjunto de CronJobs de Kubernetes exporta información conocida sobre los patrones de tráfico a una métrica personalizada de Cloud Monitoring. Luego, un escalador automático horizontal de Pods (HPA) de Kubernetes lee estos datos como entrada sobre el momento en que el HPA debe escalar tu carga de trabajo. Junto con otras métricas de carga, como el uso de CPU de destino, el HPA decide cómo escalar las réplicas para una implementación determinada.
Objetivos
- Crear un clúster de GKE.
- Implementar una aplicación de ejemplo que use un HPA de Kubernetes
- Configurar los componentes del escalador automático programado y actualizar tu HPA a fin de leer desde una métrica personalizada programada.
- Configurar una alerta para que se active cuando el autoescalador programado no funcione de forma adecuada.
- Generar una carga para la aplicación.
- Examinar cómo el HPA responde a los aumentos normales del tráfico y a las métricas personalizadas programadas que configuras.
El código para este instructivo está disponible en un repositorio de GitHub.
Costos
En este documento, usarás los siguientes componentes facturables de Google Cloud:
Para generar una estimación de costos en función del uso previsto, usa la calculadora de precios.
Antes de comenzar
- Accede a tu cuenta de Google Cloud. 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.
-
Asegúrate de que la facturación esté habilitada para tu proyecto de Google Cloud.
-
Enable the GKE, Artifact Registry and the Cloud Monitoring APIs.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Asegúrate de que la facturación esté habilitada para tu proyecto de Google Cloud.
-
Enable the GKE, Artifact Registry and the Cloud Monitoring APIs.
Prepare el entorno
In the Google Cloud console, activate Cloud Shell.
At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.
En Cloud Shell, configura el ID del proyecto de Google Cloud, la dirección de correo electrónico, y la zona y la región de procesamiento:
PROJECT_ID=YOUR_PROJECT_ID ALERT_EMAIL=YOUR_EMAIL_ADDRESS gcloud config set project $PROJECT_ID gcloud config set compute/region us-central1 gcloud config set compute/zone us-central1-f
Reemplaza lo siguiente:
YOUR_PROJECT_ID
: Es el nombre del proyecto de Google Cloud para el proyecto que usas.YOUR_EMAIL_ADDRESS
: la dirección de correo electrónico para recibir notificaciones cuando el escalador automático programado no funciona como corresponde.
Si lo deseas, puedes elegir una región y una zona diferentes para este instructivo.
Clona el repositorio de GitHub
kubernetes-engine-samples
:git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples/ cd kubernetes-engine-samples/cost-optimization/gke-scheduled-autoscaler
El código de este ejemplo se organiza en las siguientes carpetas:
- Raíz: Contiene el código que usan los CronJobs para exportar métricas personalizadas a Cloud Monitoring.
k8s/
: Contiene un ejemplo de implementación que tiene un HPA de Kubernetes.k8s/scheduled-autoscaler/
: Contiene los CronJobs que exportan una métrica personalizada y una versión actualizada del HPA para leer desde una métrica personalizada.k8s/load-generator/
: Contiene una implementación de Kubernetes que tiene una aplicación para simular el uso por hora.monitoring/
: Contiene los componentes de Cloud Monitoring que configuras en este instructivo.
Crea el clúster de GKE
En Cloud Shell, crea un clúster de GKE para ejecutar el escalador automático programado:
gcloud container clusters create scheduled-autoscaler \ --enable-ip-alias \ --release-channel=stable \ --machine-type=e2-standard-2 \ --enable-autoscaling --min-nodes=1 --max-nodes=10 \ --num-nodes=1 \ --autoscaling-profile=optimize-utilization
El resultado es similar a este:
NAME LOCATION MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS scheduled-autoscaler us-central1-f 1.22.15-gke.100 34.69.187.253 e2-standard-2 1.22.15-gke.100 1 RUNNING
Esta no es una configuración de producción, pero es adecuada para este instructivo. En esta configuración, configuras el escalador automático del clúster con un mínimo de 1 nodo y un máximo de 10. También puedes habilitar el perfil
optimize-utilization
para acelerar el proceso de reducción vertical de escala.
Implementa la aplicación de ejemplo
Implementa la aplicación de ejemplo sin el escalador automático programado:
kubectl apply -f ./k8s
Abre el archivo
k8s/hpa-example.yaml
.En la siguiente lista, se muestra el contenido del archivo.
Observa que la cantidad mínima de réplicas (
minReplicas
) está configurada en 10. Esta configuración también establece el escalamiento del clúster en función del uso de CPU (la configuraciónname: cpu
ytype: Utilization
).Espera a que la aplicación esté disponible:
kubectl wait --for=condition=available --timeout=600s deployment/php-apache EXTERNAL_IP='' while [ -z $EXTERNAL_IP ] do EXTERNAL_IP=$(kubectl get svc php-apache -o jsonpath={.status.loadBalancer.ingress[0].ip}) [ -z $EXTERNAL_IP ] && sleep 10 done curl -w '\n' http://$EXTERNAL_IP
Cuando la aplicación está disponible, el resultado es el siguiente:
OK!
Verifica la configuración:
kubectl get hpa php-apache
El resultado es similar a este:
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE php-apache Deployment/php-apache 9%/60% 10 20 10 6d19h
En la columna
REPLICAS
, se muestra10
, que coincide con el valor del campominReplicas
en el archivohpa-example.yaml
.Verifica si la cantidad de nodos aumentó a 4:
kubectl get nodes
El resultado es similar a este:
NAME STATUS ROLES AGE VERSION gke-scheduled-autoscaler-default-pool-64c02c0b-9kbt Ready <none> 21S v1.17.9-gke.1504 gke-scheduled-autoscaler-default-pool-64c02c0b-ghfr Ready <none> 21s v1.17.9-gke.1504 gke-scheduled-autoscaler-default-pool-64c02c0b-gvl9 Ready <none> 21s v1.17.9-gke.1504 gke-scheduled-autoscaler-default-pool-64c02c0b-t9sr Ready <none> 21s v1.17.9-gke.1504
Cuando creaste el clúster, estableciste una configuración mínima con la marca
min-nodes=1
. Sin embargo, la aplicación que implementaste al comienzo de este procedimiento solicita más infraestructura porqueminReplicas
en el archivohpa-example.yaml
está configurado en 10.Establecer
minReplicas
en un valor como 10 es una estrategia común que usan empresas como los minoristas, que esperan un aumento repentino en el tráfico durante las primeras horas del día hábil. Sin embargo, establecer valores altos para elminReplicas
de HPA puede aumentar los costos porque el clúster no puede reducirse, ni siquiera por la noche, cuando el tráfico de la aplicación es bajo.
Configura un escalador automático programado
En Cloud Shell, instala el adaptador de métricas personalizadas de Cloud Monitoring en tu clúster de GKE:
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/k8s-stackdriver/master/custom-metrics-stackdriver-adapter/deploy/production/adapter_new_resource_model.yaml kubectl wait --for=condition=available --timeout=600s deployment/custom-metrics-stackdriver-adapter -n custom-metrics
Este adaptador habilita el ajuste de escala automático de los Pods según las métricas personalizadas de Cloud Monitoring.
Crea un repositorio en Artifact Registry y otorga permisos de lectura:
gcloud artifacts repositories create gke-scheduled-autoscaler \ --repository-format=docker --location=us-central1 gcloud auth configure-docker us-central1-docker.pkg.dev gcloud artifacts repositories add-iam-policy-binding gke-scheduled-autoscaler \ --location=us-central1 --member=allUsers --role=roles/artifactregistry.reader
Compila y envía el código del exportador de métricas personalizadas:
docker build -t us-central1-docker.pkg.dev/$PROJECT_ID/gke-scheduled-autoscaler/custom-metric-exporter . docker push us-central1-docker.pkg.dev/$PROJECT_ID/gke-scheduled-autoscaler/custom-metric-exporter
Implementa los CronJobs que exportan métricas personalizadas y, luego, implementa la versión actualizada del HPA que lee desde estas métricas personalizadas:
sed -i.bak s/PROJECT_ID/$PROJECT_ID/g ./k8s/scheduled-autoscaler/scheduled-autoscale-example.yaml kubectl apply -f ./k8s/scheduled-autoscaler
Abre y examina el archivo
k8s/scheduled-autoscaler/scheduled-autoscale-example.yaml
.En la siguiente lista, se muestra el contenido del archivo.
Esta configuración especifica que los CronJobs deben exportar el recuento de réplicas de Pods sugeridas a una métrica personalizada llamada
custom.googleapis.com/scheduled_autoscaler_example
en función de la hora del día. Para facilitar la sección de supervisión de este instructivo, la configuración del campo de programa define los aumentos y reducciones verticales de la escala por hora. Para la producción, puedes personalizar este programa a fin de que se adapte a las necesidades de tu empresa.Abre y examina el archivo
k8s/scheduled-autoscaler/hpa-example.yaml
.En la siguiente lista, se muestra el contenido del archivo.
Esta configuración especifica que el objeto HPA debe reemplazar el HPA que se implementó antes. Ten en cuenta que la configuración reduce el valor de
minReplicas
a 1. Esto significa que la carga de trabajo se puede reducir a su valor mínimo. La configuración también agrega una métrica externa (type: External
). Esta incorporación significa que el ajuste de escala automático ahora se activa por dos factores.En esta situación de varias métricas, el HPA calcula un recuento de réplicas propuesto para cada métrica y, luego, elige la métrica que muestra el valor más alto. Es importante comprender esto: el escalador automático programado puede proponer que, en un momento determinado, el recuento de Pods debería ser 1. Sin embargo, si el uso real de la CPU es mayor de lo esperado para un Pod, el HPA crea más réplicas.
Verifica la cantidad de nodos y réplicas de HPA de nuevo mediante la ejecución de cada uno de estos comandos:
kubectl get nodes kubectl get hpa php-apache
El resultado que ves depende de lo que el escalador automático programado haya hecho recientemente. En particular, los valores de
minReplicas
ynodes
serán diferentes en distintos puntos del ciclo de escalamiento.Por ejemplo, aproximadamente los minutos 51 a 60 de cada hora (que representa un período de tráfico máximo), el valor HPA para
minReplicas
será de 10 y el valor denodes
será 4.Por el contrario, para los minutos del 1 al 50 (que representan un período de menor tráfico), el valor
minReplicas
de HPA será 1 y el valornodes
será 1 o 2, según la cantidad de Pods que se asignaron y quitaron. Para los valores más bajos (los minutos del 1 a 50), el clúster puede demorar hasta 10 minutos en terminar de reducir la escala verticalmente.
Configura alertas para cuando el escalador automático programado no funcione correctamente
En un entorno de producción, por lo general, quieres saber cuándo CronJobs no propaga la métrica personalizada. Para este fin, puedes crear una alerta que se active cuando cualquier transmisión de custom.googleapis.com/scheduled_autoscaler_example
esté ausente por un período de cinco minutos.
En Cloud Shell, crea un canal de notificaciones:
gcloud beta monitoring channels create \ --display-name="Scheduled Autoscaler team (Primary)" \ --description="Primary contact method for the Scheduled Autoscaler team lead" \ --type=email \ --channel-labels=email_address=${ALERT_EMAIL}
El resultado es similar a este:
Created notification channel NOTIFICATION_CHANNEL_ID.
Con este comando, se crea un canal de notificaciones de tipo
email
para simplificar los pasos del instructivo. En entornos de producción, te recomendamos que uses una estrategia menos asíncrona. Para ello, establece el canal de notificaciones ensms
opagerduty
.Configura una variable que tenga el valor que se mostró en el marcador de posición
NOTIFICATION_CHANNEL_ID
:NOTIFICATION_CHANNEL_ID=NOTIFICATION_CHANNEL_ID
Implementa la política de alertas:
gcloud alpha monitoring policies create \ --policy-from-file=./monitoring/alert-policy.yaml \ --notification-channels=$NOTIFICATION_CHANNEL_ID
El archivo
alert-policy.yaml
contiene la especificación para enviar una alerta si la métrica está ausente durante cinco minutos.Ve a la página Alertas de Cloud Monitoring para ver la política de alertas.
Haz clic en Política del escalador automático programado y verifica los detalles de la política de alertas.
Genera una carga en la aplicación de ejemplo
En Cloud Shell, implementa el generador de cargas:
kubectl apply -f ./k8s/load-generator
En la siguiente lista, se muestra la secuencia de comandos
load-generator
.command: ["/bin/sh", "-c"] args: - while true; do RESP=$(wget -q -O- http://php-apache.default.svc.cluster.local); echo "$(date +%H)=$RESP"; sleep $(date +%H | awk '{ print "s("$0"/3*a(1))*0.5+0.5" }' | bc -l); done;
Esta secuencia de comandos se ejecuta en tu clúster hasta que borres la implementación
load-generator
. Realiza solicitudes al serviciophp-apache
cada pocos milisegundos. El comandosleep
simula cambios en la distribución de cargas durante el día. Mediante una secuencia de comandos que genera tráfico de esta manera, puedes comprender lo que sucede cuando combinas el uso de CPU y las métricas personalizadas en la configuración del HPA.
Visualiza el escalamiento como respuesta al tráfico o las métricas programadas
En esta sección, observarás las visualizaciones que te muestran los efectos del aumento y la reducción vertical de la escala.
En Cloud Shell, crea un entorno nuevo.
gcloud monitoring dashboards create \ --config-from-file=./monitoring/dashboard.yaml
Ve a la página Paneles de Cloud Monitoring:
Haz clic en Panel del escalador automático programado.
El panel muestra tres gráficos. Debes esperar al menos 2 horas (lo ideal sería 24 horas o más) para ver la dinámica de los aumentos y reducciones verticales de la escala, y para ver cómo las diferentes distribuciones de cargas durante el día afectan el ajuste de escala automático.
Estudia los siguientes gráficos, que presentan una vista de un día completo, para tener una idea de lo que muestran en general:
La métrica programada (cantidad deseada de Pods) muestra una serie temporal de la métrica personalizada que se exporta a Cloud Monitoring a través de los CronJobs que configuraste en Configura un escalador automático programado.
El Uso de CPU (solicitado o usado) muestra una serie temporal de CPU solicitada (rojo) y el uso de CPU real (azul). Cuando la carga es baja, el HPA respeta la decisión de uso del escalador automático programado. Sin embargo, cuando el tráfico aumenta, el HPA aumenta la cantidad de Pods según sea necesario, como puedes ver para los datos entre las 12:00 p.m. y las 6:00 p.m.
La Cantidad de Pods (programados o reales) + uso de CPU promedio muestra una vista similar a las anteriores. El recuento de Pods (rojo) aumenta a 10 cada hora según lo programado (azul). El recuento de Pods aumenta y disminuye de forma natural con el tiempo como respuesta a la carga (12 p.m. y 6 p.m.). El uso de CPU promedio (naranja) permanece por debajo del objetivo que estableciste (60%).
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.
Borra el proyecto
- En la consola de Google Cloud, ve a la página Administrar recursos.
- En la lista de proyectos, elige el proyecto que quieres borrar y haz clic en Borrar.
- En el diálogo, escribe el ID del proyecto y, luego, haz clic en Cerrar para borrar el proyecto.
¿Qué sigue?
- Obtén más información sobre la optimización de costos en GKE en Prácticas recomendadas para la ejecución de aplicaciones de Kubernetes con optimización de costos en GKE.
- Encuentra recomendaciones de diseño y prácticas recomendadas para optimizar el costo de las cargas de trabajo de Google Cloud en Framework de la arquitectura de Google Cloud: Optimización de costos.
- Explora arquitecturas de referencia, diagramas y prácticas recomendadas sobre Google Cloud. Consulta nuestro Cloud Architecture Center.