Horizontal Pod Autoscaler
En la lección de Deployments escalaste a mano con kubectl scale. Funciona, pero exige que alguien esté mirando. El Horizontal Pod Autoscaler (HPA) cierra el bucle: compara el consumo real de los Pods con un objetivo que tú declaras y ajusta las réplicas solo.
El capítulo de escalado del libro presenta los tres autoescaladores de Kubernetes (HPA, VPA y el de nodos) y por qué resuelven problemas distintos. Este módulo pone en marcha los dos primeros.
⚠️ Esta lección es opcional y algo más caprichosa que el resto: depende del ciclo de métricas de metrics-server (unos 15 segundos) y de la ventana de decisión del HPA, así que entre generar carga y ver réplicas nuevas pueden pasar de 1 a 3 minutos. Es el comportamiento real del autoscaling, no un fallo del laboratorio.
El HPA necesita saber cuánto consume cada Pod, y esa información la sirve metrics-server, que k3s trae instalado. Compruébalo desde la pestaña dev-machine:
kubectl top nodes
kubectl top pods -A
Ese kubectl top que acabas de usar es, además, la herramienta básica de observabilidad de recursos del día a día.
Paso 1: Un Deployment con requests (obligatorio) y su Service
El HPA de CPU calcula porcentajes sobre los requests del Pod. Sin requests no hay porcentaje posible, y el HPA queda inservible: es la razón práctica definitiva para declararlos siempre. Crea api.yaml con las dos piezas:
cat << 'EOF' > api.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: api
spec:
replicas: 1
selector:
matchLabels:
app: api
template:
metadata:
labels:
app: api
spec:
containers:
- name: nginx
image: ghcr.io/iximiuz/labs/nginx:alpine
ports:
- containerPort: 80
resources:
requests:
cpu: 20m
memory: 64Mi
---
apiVersion: v1
kind: Service
metadata:
name: api
spec:
selector:
app: api
ports:
- port: 80
targetPort: 80
EOF
Todo en este archivo lo has escrito ya en lecciones anteriores; el único detalle nuevo es la intención: ese cpu: 20m deliberadamente bajo hará que un poco de carga se convierta en un porcentaje alto, para que el laboratorio escale rápido.
kubectl apply -f api.yaml
Paso 2: El HPA
Crea hpa.yaml:
cat << 'EOF' > hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: api-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: api
minReplicas: 1
maxReplicas: 4
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
EOF
El YAML, explicado con preguntas y respuestas
¿Qué señala scaleTargetRef?
El objeto al que el HPA moverá las réplicas. No gestiona Pods directamente: modifica el campo replicas del Deployment y deja que la maquinaria que ya conoces (Deployment, ReplicaSet) haga el resto.
¿Qué significa averageUtilization: 50?
El objetivo: que la media de CPU de los Pods ronde el 50 por ciento de sus requests. Con requests de 20m, eso son 10m de consumo medio. Si la media sube, el HPA añade réplicas para repartir; si baja, retira.
¿Para qué sirven minReplicas y maxReplicas?
Son las barandillas. El mínimo garantiza servicio aun sin carga; el máximo protege al clúster (y a tu factura) de un pico o de una métrica enloquecida.
¿Por qué autoscaling/v2 y no v1?
La v2 es la API actual y admite varias métricas a la vez, incluidas memoria y métricas personalizadas. La v1 solo entendía CPU.
Aplícalo y observa su primer cálculo (tarda unos segundos en dejar de decir unknown):
kubectl apply -f hpa.yaml
kubectl get hpa api-hpa
Paso 3: Carga y despegue
Genera tráfico continuo con un Pod que no deja de pedir la página:
kubectl run generador --image=ghcr.io/iximiuz/labs/nginx:alpine --command -- \
sh -c 'for i in 1 2 3 4 5; do (while true; do wget -qO- http://api >/dev/null 2>&1; done) & done; wait'
Y ponte cómodo a mirar el instrumento clave:
kubectl get hpa api-hpa --watch
Verás la columna TARGETS pasar de un porcentaje bajo a superar el 50 por ciento, y poco después la columna REPLICAS subir. Paciencia: el ciclo completo (metrics-server mide, HPA decide, Deployment despliega) tarda entre 1 y 3 minutos.
Cuando pase la verificación, ejecuta el experimento inverso: borra el generador (kubectl delete pod generador) y deja el watch abierto. La vuelta a 1 réplica tardará bastante más, unos 5 minutos: el HPA reduce con una ventana de estabilización deliberadamente conservadora, porque quedarse corto de réplicas duele más que ir sobrado.
Resumen
- El HPA ajusta las réplicas de un Deployment comparando consumo real contra un objetivo declarado.
- Sin requests no hay HPA de CPU: el porcentaje se calcula sobre ellos.
- metrics-server es el proveedor de la señal, y
kubectl toptu ventana a ella. - Escalar hacia arriba es rápido; hacia abajo, prudente. Es diseño, no lentitud.
Y con esto termina el curso. Has recorrido el camino completo: del primer Pod a un clúster que se repara, se configura, se protege y ahora también se dimensiona solo.
- Previous lesson
- Jobs y CronJobs
- Next lesson
- Vertical Pod Autoscaler