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)
  • kubectl instalado y configurado para comunicarse con tu clúster
  • metrics-server desplegado (la mayoría de los clústeres administrados lo incluyen por defecto)
  • Familiaridad básica con Deployments y Services
  • Un deployment con requests de 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:

  1. Obtiene los valores de métricas actuales de la API de métricas para todos los pods en la carga de trabajo objetivo
  2. 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 $$

  1. Compara las réplicas deseadas con las réplicas actuales
  2. 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étricaFuenteEjemplo
Resourcemetrics-serverUtilización de CPU, memoria
PodsAPI de métricas personalizadasSolicitudes por segundo por pod
ExternalAPI de métricas externasProfundidad 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ísticaHPAVPACluster Autoscaler
Qué escalaNúmero de réplicas de podsSolicitudes de CPU/memoria por podNúmero de nodos del clúster
DirecciónHorizontal (más pods)Vertical (pods más grandes)Horizontal (más nodos)
Métricas usadasCPU, memoria, personalizadas, externasUso histórico de recursosPods pendientes de programación
Requiere reinicioNoSí (recrea pods)No (agrega nodos)
Mejor paraApps sin estado, escalables horizontalmenteApps de instancia única con recursos variablesAcomodar el escalado de HPA
Se puede combinarSí, con Cluster AutoscalerNo con HPA en la misma métricaSí, con HPA
Velocidad de reacciónSegundos a minutosMinutos (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.
  • selectPolicyMax elige la política que permite más cambio (agresivo), Min elige la más conservadora, Disabled previene 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 requests de CPU y memoria en tus contenedores — HPA no puede funcionar sin ellos
  • Usa la API autoscaling/v2 para 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

Artículos Relacionados