El Horizontal Pod Autoscaler (HPA) de Kubernetes ajusta automáticamente el número de réplicas de pods en un deployment, replica set o stateful set basándose en métricas observadas. En lugar de escalar manualmente las cargas de trabajo cuando el tráfico aumenta a las 2 AM, HPA lo maneja por ti. En esta guía aprenderás cómo funciona HPA internamente, cómo configurarlo con métricas de CPU, memoria y personalizadas, y cómo ajustar las políticas de escalado para cargas de trabajo en producción.
Requisitos Previos
Antes de configurar HPA, asegúrate de tener:
- Un clúster de Kubernetes en funcionamiento (v1.23+) — minikube, kind, o un clúster administrado (EKS, GKE, AKS)
kubectlinstalado y configurado para comunicarse con tu clústermetrics-serverdesplegado (la mayoría de los clústeres administrados lo incluyen por defecto)- Familiaridad básica con Deployments y Services
- Un deployment con
requestsde CPU/memoria definidos (HPA no puede calcular la utilización sin ellos)
Verifica que metrics-server esté ejecutándose:
kubectl get deployment metrics-server -n kube-system
kubectl top nodes
kubectl top pods
Si kubectl top devuelve métricas, estás listo para continuar.
Cómo Funciona HPA
HPA se ejecuta como un bucle de control en el controller manager de Kubernetes, verificando métricas en un intervalo configurable (por defecto: 15 segundos). En cada iteración:
- Obtiene los valores de métricas actuales de la API de métricas para todos los pods en la carga de trabajo objetivo
- Calcula el conteo de réplicas deseado usando la fórmula:
$$ \text{réplicasDeseadas} = \lceil \text{réplicasActuales} \times \frac{\text{valorMétricaActual}}{\text{valorMétricaDeseado}} \rceil $$
- Compara las réplicas deseadas con las réplicas actuales
- Escala la carga de trabajo hacia arriba o abajo si la proporción excede una tolerancia configurable (por defecto ±10%)
Por ejemplo, si tu deployment tiene 3 réplicas ejecutándose al 75% de CPU promedio y tu objetivo es 50%:
$$ \text{deseado} = \lceil 3 \times \frac{75}{50} \rceil = \lceil 4.5 \rceil = 5 $$
HPA escalaría el deployment a 5 réplicas.
Comportamiento de cooldown: HPA usa ventanas de estabilización para prevenir fluctuaciones. Por defecto, los eventos de escala hacia abajo usan una ventana de estabilización de 5 minutos — HPA elige el conteo de réplicas más alto recomendado de los últimos 5 minutos. La escala hacia arriba no tiene ventana de estabilización por defecto, reaccionando inmediatamente a los aumentos de carga.
Configuración de HPA con Métricas de CPU
Configuración Rápida con kubectl
La forma más rápida de crear un HPA:
kubectl autoscale deployment my-app \
--cpu-percent=50 \
--min=2 \
--max=10
Esto le dice a Kubernetes: mantén la utilización promedio de CPU al 50% en todos los pods, con un mínimo de 2 y máximo de 10 réplicas.
Manifiesto YAML Completo
Para producción, define HPA como un manifiesto YAML que puedas versionar:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: my-app-hpa
namespace: default
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: my-app
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 70
Aplica y monitorea:
kubectl apply -f hpa.yaml
kubectl get hpa my-app-hpa --watch
La salida se ve así:
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS
my-app-hpa Deployment/my-app 32%/50%, 45%/70% 2 10 3
Importante: Los contenedores de tu deployment deben tener solicitudes de recursos definidas, o HPA no puede calcular porcentajes de utilización:
resources:
requests:
cpu: "250m"
memory: "256Mi"
limits:
cpu: "500m"
memory: "512Mi"
Métricas Personalizadas y Métricas Externas
CPU y memoria a menudo son insuficientes para decisiones de escalado. Un servicio web puede tener bajo CPU pero una gran cola de solicitudes. HPA v2 soporta tres tipos de métricas:
| Tipo de Métrica | Fuente | Ejemplo |
|---|---|---|
| Resource | metrics-server | Utilización de CPU, memoria |
| Pods | API de métricas personalizadas | Solicitudes por segundo por pod |
| External | API de métricas externas | Profundidad de cola SQS, backlog de Pub/Sub |
Configuración de Métricas Personalizadas con Prometheus Adapter
Instala prometheus-adapter para exponer métricas de Prometheus a través de la API de métricas personalizadas de Kubernetes:
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm install prometheus-adapter prometheus-community/prometheus-adapter \
--namespace monitoring \
--set prometheus.url=http://prometheus-server.monitoring.svc
Luego configura un HPA usando una métrica personalizada:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: my-app-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: my-app
minReplicas: 2
maxReplicas: 20
metrics:
- type: Pods
pods:
metric:
name: http_requests_per_second
target:
type: AverageValue
averageValue: "100"
Escalado por Profundidad de Cola Externa
Para arquitecturas dirigidas por eventos, escala basándote en una métrica externa como una cola SQS:
metrics:
- type: External
external:
metric:
name: sqs_queue_length
selector:
matchLabels:
queue: "order-processing"
target:
type: Value
value: "30"
Esto escala tus pods consumidores para mantener la longitud de la cola alrededor de 30 mensajes.
HPA vs VPA vs Cluster Autoscaler
| Característica | HPA | VPA | Cluster Autoscaler |
|---|---|---|---|
| Qué escala | Número de réplicas de pods | Solicitudes de CPU/memoria por pod | Número de nodos del clúster |
| Dirección | Horizontal (más pods) | Vertical (pods más grandes) | Horizontal (más nodos) |
| Métricas usadas | CPU, memoria, personalizadas, externas | Uso histórico de recursos | Pods pendientes de programación |
| Requiere reinicio | No | Sí (recrea pods) | No (agrega nodos) |
| Mejor para | Apps sin estado, escalables horizontalmente | Apps de instancia única con recursos variables | Acomodar el escalado de HPA |
| Se puede combinar | Sí, con Cluster Autoscaler | No con HPA en la misma métrica | Sí, con HPA |
| Velocidad de reacción | Segundos a minutos | Minutos (reinicio de pod) | Minutos (aprovisionamiento de nodo) |
Combinación recomendada: Usa HPA para escalado de cargas de trabajo + Cluster Autoscaler para escalado de infraestructura. Evita usar HPA y VPA en la misma métrica para el mismo deployment — entrarán en conflicto.
Escenario del Mundo Real
Considera una plataforma de comercio electrónico que ve 10x más tráfico durante ventas flash. Tu deployment checkout-service normalmente maneja 50 solicitudes/segundo con 3 réplicas.
Sin HPA: Tu ingeniero de guardia recibe una alerta a medianoche, escala manualmente a 20 réplicas, y luego olvida reducir. Pagas por recursos ociosos durante 3 días.
Con HPA configurado:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: checkout-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: checkout-service
minReplicas: 3
maxReplicas: 30
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60
- type: Pods
pods:
metric:
name: http_requests_per_second
target:
type: AverageValue
averageValue: "50"
behavior:
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100
periodSeconds: 60
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 10
periodSeconds: 60
Esta configuración:
- Escala hacia arriba agresivamente — duplicando réplicas cada 60 segundos cuando CPU supera 60% o la tasa de solicitudes supera 50 req/s por pod
- Escala hacia abajo conservadoramente — eliminando solo 10% de réplicas por minuto con una ventana de estabilización de 5 minutos
- Previene reducción prematura después de ráfagas cortas de tráfico
Durante la venta flash, HPA escala de 3 a 25 réplicas en menos de 5 minutos. Después de que el tráfico disminuye, reduce gradualmente a 3 en aproximadamente 30 minutos.
Políticas de Escalado y Comportamiento
El campo behavior (autoscaling/v2) te da control preciso sobre la velocidad de escalado:
behavior:
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100
periodSeconds: 15
- type: Pods
value: 4
periodSeconds: 15
selectPolicy: Max
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 10
periodSeconds: 60
selectPolicy: Min
Campos clave:
- stabilizationWindowSeconds — cuánto tiempo HPA mira hacia atrás para elegir la recomendación más conservadora. Establece en 0 para escalado inmediato hacia arriba; 300 (5 min) para reducción cautelosa.
- policies — define la velocidad de escalado como porcentaje de réplicas actuales o un número absoluto de pods por período de tiempo.
- selectPolicy —
Maxelige la política que permite más cambio (agresivo),Minelige la más conservadora,Disabledpreviene el escalado en esa dirección.
Patrones Comunes de Políticas
Escalado rápido hacia arriba, lento hacia abajo (recomendado para la mayoría de apps web):
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100
periodSeconds: 15
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Pods
value: 1
periodSeconds: 60
Prevenir escalado hacia abajo completamente (trabajos batch):
scaleDown:
selectPolicy: Disabled
Problemas Comunes y Casos Especiales
Retraso de métricas: Metrics-server recopila datos cada 15 segundos, y HPA evalúa cada 15 segundos. Esto significa que hay un retraso de 15–30 segundos entre un pico de carga y la primera decisión de escalado. Para servicios sensibles a la latencia, considera comenzar con más minReplicas.
Solicitudes de recursos faltantes: Si tus contenedores no definen requests de CPU o memoria, HPA reporta <unknown> para utilización y no escalará. Siempre define requests.
Las sondas de disponibilidad importan: HPA cuenta solo los pods Ready al calcular métricas. Si los nuevos pods tardan 60 segundos en estar listos, HPA puede sobre-aprovisionar porque los pods existentes permanecen sobrecargados durante el inicio. Ajusta las sondas de disponibilidad y considera sondas de inicio para aplicaciones de arranque lento.
Conflictos con PodDisruptionBudget: Un PDB que permite cero pods no disponibles puede bloquear la reducción si HPA intenta eliminar réplicas durante una interrupción voluntaria. Asegúrate de que minAvailable de tu PDB sea menor que minReplicas de tu HPA.
Interacción de múltiples métricas: Cuando HPA evalúa múltiples métricas, calcula el conteo de réplicas deseado para cada métrica independientemente y elige el valor más alto. Esto significa que un pico en una sola métrica puede activar el escalado aunque otras métricas estén bajas.
Latencia de HPA y Cluster Autoscaler: HPA crea nuevos pods inmediatamente, pero si ningún nodo tiene capacidad, los pods permanecen en Pending hasta que Cluster Autoscaler aprovisione nuevos nodos (típicamente 2–5 minutos en proveedores de nube). Ten esto en cuenta en tu estrategia de escalado.
Métrica de objeto vs métrica de pods: Usa el tipo Pods cuando la métrica es por pod (tasa de solicitudes). Usa el tipo Object cuando la métrica proviene de un solo objeto de Kubernetes como un Ingress.
Resumen
- HPA escala automáticamente las réplicas de pods basándose en métricas de CPU, memoria, personalizadas o externas
- La fórmula de escalado es
réplicasDeseadas = ceil(réplicasActuales × métricaActual / métricaObjetivo) - Siempre define
requestsde CPU y memoria en tus contenedores — HPA no puede funcionar sin ellos - Usa la API
autoscaling/v2para escalado multi-métrica y políticas de comportamiento - Configura escalado agresivo hacia arriba y conservador hacia abajo para cargas de producción
- Combina HPA con Cluster Autoscaler para escalado elástico completo — evita combinar HPA y VPA en la misma métrica
- Las métricas personalizadas vía prometheus-adapter desbloquean el escalado basado en métricas de negocio como tasa de solicitudes o profundidad de cola
- Prueba tu configuración de HPA bajo carga realista antes de depender de ella en producción