Ahora que ya te he contado cómo desplegar tus pods a través de Jobs, CronJobs, Deployments, ReplicaSets (obvié los ReplicationControllers porque deberían caer en el deuso) y los StatefulSets, para terminar la semana quería mostrarte cómo de sencillo es autoescalar tus aplicaciones dentro de Kubernetes.
HorizontalPodAutoscaler
Para que una aplicación pueda aumentar o disminuir de manera automática sus réplicas necesitas crear un objeto llamado HorizontalPodAutoscaler. Este se encargará de subir y/o bajar el número de réplicas que necesita tu aplicación en cada momento en base a unos umbrales que establezcas.
Para este ejemplo voy a utilizar un despliegue de una página web en ASP.NET Core:
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 3
selector:
matchLabels:
app: aspnet
template:
metadata:
labels:
app: aspnet
spec:
containers:
- name: web
image: mcr.microsoft.com/dotnet/core/samples:aspnetapp
resources:
requests:
cpu: "100m"
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: aspnet-svc
spec:
type: LoadBalancer
selector:
app: aspnet
ports:
- protocol: TCP
port: 80
targetPort: 80Esta tiene configurada durante su creación 3 réplicas. Ahora, para crear este objeto la forma más sencilla es a través del comando autoscale:
kubectl autoscale deployment web --cpu-percent=30 --min=1 --max=5Este recuperará todas las métricas de los pods que componen tu despliegue y hará una operación aritmética para determinar si el número de pods actual es el adecuado, en base al porcentaje establecido para el umbral, en este caso del 30%. Para este ejemplo sólo me estoy basando en el estado de la CPU, pero también es posible combinarlo con la memoria, o solamente basarnos en esta.
El proceso de muestreo no es inmediato sino que se revisan las métricas cada cierto tiempo (por defecto cada 15 segundos). Es por ello que inicialmente el valor de la operación que te contaba aparecerá como unknown y después de unos segundos comenzará a mostrar el valor actual del cálculo realizado:
Giselas-MacBook-Pro:HPA gis$ kubectl get hpa --watch
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
web Deployment/web <unknown>/30% 1 5 0 7s
web Deployment/web <unknown>/30% 1 5 3 20s
web Deployment/web 2%/30% 1 5 3 95sDe hecho, si esperas unos minutos comprobarás que de las 3 réplicas que habías establecido se quedará únicamente una al no tener actividad en la web:
Giselas-MacBook-Pro:HPA gis$ kubectl get hpa --watch
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
web Deployment/web <unknown>/30% 1 5 0 7s
web Deployment/web <unknown>/30% 1 5 3 20s
web Deployment/web 2%/30% 1 5 3 95s
web Deployment/web 3%/30% 1 5 3 2m36s
web Deployment/web 1%/30% 1 5 3 3m37s
web Deployment/web 1%/30% 1 5 3 5m24s
web Deployment/web 1%/30% 1 5 1 5m39sDate cuenta de que para que un despliegue pueda autoescalar es necesario indicar los requests de los containers del pod que estableces para el HPA, ya que de lo contrario no funcionará. Te darás cuenta porque en los Eventos del Horizontal Pods Autoscaler aparecerá lo siguiente:
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedGetResourceMetric 7s (x2 over 22s) horizontal-pod-autoscaler missing request for cpu
Warning FailedComputeMetricsReplicas 7s (x2 over 22s) horizontal-pod-autoscaler invalid metrics (1 invalid out of 1), first error is: failed to get cpu utilization: missing request for cpuAhora que ya tienes una web y un objeto HPA, vamos a intentar que el despliegue llegue hasta las 5 réplicas que tiene establecidas como máximo, haciendo que la CPU de los pods se dispare. Antes de ello, vigila en dos terminales separados lo siguiente:
#Terminal 1
kubectl get hpa --watch
#Terminal 2
kubectl get deployment --watchPara estresar mis pods voy a utilizar Apache Benchmark con el siguiente comando:
ab -n 50000 -c 200 http://IP_DEL_ASPNET_SVC/Como ves, le he pedido 50.000 peticiones simulando 200 usuarios concurrentes. Igual me he pasado un poco 😛 pero tendrás tiempo más que de sobra para ver cómo se comporta el autoescalado:
Giselas-MacBook-Pro:HPA gis$ kubectl get hpa --watch
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
web Deployment/web <unknown>/30% 1 5 0 7s
web Deployment/web <unknown>/30% 1 5 3 20s
web Deployment/web 2%/30% 1 5 3 95s
web Deployment/web 3%/30% 1 5 3 2m36s
web Deployment/web 1%/30% 1 5 3 3m37s
web Deployment/web 1%/30% 1 5 3 5m24s
web Deployment/web 1%/30% 1 5 1 5m39s
web Deployment/web 2%/30% 1 5 1 6m40s
web Deployment/web 1%/30% 1 5 1 7m41s
web Deployment/web 2%/30% 1 5 1 8m41s
web Deployment/web 366%/30% 1 5 1 9m42s
web Deployment/web 366%/30% 1 5 4 9m58s
web Deployment/web 366%/30% 1 5 5 10m
web Deployment/web 50%/30% 1 5 5 10m
web Deployment/web 65%/30% 1 5 5 11m
web Deployment/web 62%/30% 1 5 5 12m
web Deployment/web 1%/30% 1 5 5 13m
web Deployment/web 1%/30% 1 5 5 18m
web Deployment/web 1%/30% 1 5 1 18mTambién verás cómo el deployment ha ido ajustando el número de réplicas según la CPU iba aumentando o disminuyendo para tus pods:
Giselas-MacBook-Pro:HPA gis$ kubectl get deployment --watch
NAME READY UP-TO-DATE AVAILABLE AGE
web 0/3 3 0 17s
web 1/3 3 1 24s
web 2/3 3 2 25s
web 3/3 3 3 26s
web 3/1 3 3 5m28s
web 3/1 3 3 5m28s
web 1/1 1 1 5m28s
web 1/4 1 1 9m46s
web 1/4 1 1 9m46s
web 1/4 1 1 9m46s
web 1/4 4 1 9m47s
web 2/4 4 2 9m49s
web 3/4 4 3 9m49s
web 4/4 4 4 9m49s
web 4/5 4 4 10m
web 4/5 4 4 10m
web 4/5 4 4 10m
web 4/5 5 4 10m
web 5/5 5 5 10m
web 5/1 5 5 18m
web 5/1 5 5 18m
web 1/1 1 1 18mPor último si revisas los eventos del HorizontalPodAutoscaler:
kubectl describe hpa webPodrás comprobar todas las subidas y bajas que ha tenido que realizar en base a las métricas recibidas de tus pods:
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedGetResourceMetric 19m (x5 over 20m) horizontal-pod-autoscaler unable to get metrics for resource cpu: no metrics returned from resource metrics API
Warning FailedComputeMetricsReplicas 19m (x5 over 20m) horizontal-pod-autoscaler invalid metrics (1 invalid out of 1), first error is: failed to get cpu utilization: unable to get metrics for resource cpu: no metrics returned from resource metrics API
Normal SuccessfulRescale 11m horizontal-pod-autoscaler New size: 4; reason: cpu resource utilization (percentage of request) above target
Normal SuccessfulRescale 10m horizontal-pod-autoscaler New size: 5; reason: cpu resource utilization (percentage of request) above target
Normal SuccessfulRescale 2m7s (x2 over 15m) horizontal-pod-autoscaler New size: 1; reason: All metrics below targetSi bien todo esto nos permite gestionar picos de manera automatizada, la versión estable, a día de hoy, de los HorizontalPodAutoscaler solo se puede basar en las métricas CPU y memoria. En muchos escenarios son más que suficientes pero en otros se requiere vigilar algo más. Por ejemplo, si tu aplicación es más propensa a tener cuellos de botella en la red, más que en la CPU o en la memoria, seguramente te interese valorar otras métricas. Por otro lado, también puede ocurrir que necesites tener en cuenta servicios externos, como pueden ser colas de mensajerías.
A partir de Kubernetes 1.6 se añade soporte para hacer uso de métricas personalizadas y externas a través de la versión autoscaling/v2beta2. En un próximo artículo te mostraré cómo hacerlo.
¡Saludos!
Si quieres seguir aprendiendo sobre contenedores, tienes una lista de vídeos en mi canal de YouTube 👇🏻
Docker CLI: Comandos esenciales que todo developer debe conocer
Domina los Dockerfiles: De lo básico a multi-stage
4 formas de crear un Dockerfile sin empezar desde cero
¿No entiendes las redes en Docker? Mira este vídeo
Cómo NO perder tus datos en Docker: Guía definitiva
Deja de configurar contenedores a mano: Aprende Docker Compose 🐙
Cómo subir tus imágenes a Docker Hub (Guía paso a paso)
Publica y automatiza tus imágenes de Docker con GitHub


¿Qué son los contenedores? Docker desde cero para principiantes
return(GiS); julio 10, 2024 10:00 am