Introducción
En arquitecturas Kubernetes basadas en eventos, las métricas tradicionales de CPU y memoria no siempre reflejan la carga real del sistema. Un pod de worker puede aparecer inactivo en términos de uso de recursos mientras miles de mensajes se acumulan en una cola de Amazon SQS. En otros casos, los pods pueden seguir ejecutándose mucho después de que el pico de tráfico haya pasado. Para workloads asincronos y basados en colas, el backlog es la señal de escalado real, no la utilización de infraestructura.
El problema es concreto: si el escalado se basa en métricas de recursos, el sistema reacciona tarde ante picos de mensajes o desperdicia recursos cuando las colas están vacías. Esto impacta directamente en la experiencia de usuario y en los costos operativos, especialmente en entornos cloud donde cada vCPU y GB de RAM tienen un costo asociado.
Qué ocurrió
El article de CNCF demuestra cómo usar KEDA (un proyecto de la Cloud Native Computing Foundation) para escalar pods de Kubernetes automáticamente según la profundidad de una cola SQS. KEDA actúa como un controlador de escalado que observa métricas externas —en este caso, el número de mensajes en una cola SQS— y ajusta el Horizontal Pod Autoscaler (HPA) de Kubernetes en función del backlog.
El flujo es simple: cuando la cola tiene muchos mensajes, KEDA aumenta el número de pods para procesarlos más rápido; cuando la cola está vacía, escala a cero para ahorrar recursos. Este enfoque alinea el escalado con la demanda real de trabajo, no con métricas indirectas como el uso de CPU.
Impacto para DevOps / Infraestructura / Cloud / Seguridad
Para equipos de DevOps e infraestructura, implementar este patrón tiene beneficios directos:
Eficiencia en costos: En entornos como Amazon EKS, escalar a cero cuando no hay mensajes reduce el gasto en nodos innecesarios. Según estudios de CNCF, hasta el 65% de los clusters Kubernetes tienen pods sobreprovisionados, y el autoscaling basado en workload puede reducir el desperdicio de recursos entre un 30% y 50%. Respuesta más rápida a picos: El escalado basado en backlog reacciona antes que el basado en CPU. En pruebas con colas SQS, KEDA escaló de 1 a 10 pods en menos de 30 segundos ante un ingrego repentino de 500 mensajes, mientras que un HPA tradicional basados en CPU tardó más de 2 minutos en detectar el aumento de carga. Resiliencia mejorada: Al escalar según la cantidad de trabajo pendiente, el sistema maneja mejor las ráfagas de tráfico sin colapsar. Esto es crítico para aplicaciones de procesamiento de eventos, como sistemas de pagos, IoT o flujos de datos en tiempo real.Para seguridad, el modelo requiere configurar permisos IAM mínimos para que KEDA pueda consultar las métricas de SQS. Esto introduce un nuevo vector de attack si las credenciales se ven comprometidas, por lo que es clave seguir el principio de least privilege y usar mecanismos como IRSA (IAM Roles for Service Accounts) en EKS.
Detalles técnicos
Componentes involucrados
- KEDA 2.14+: Versión mínima recomendada para integrar con Amazon SQS. KEDA es un operador de Kubernetes que implementa el patón event-driven autoscaling mediante CRDs (Custom Resource Definitions).
- Amazon SQS: Servicio de colas de AWS. KEDA utiliza las métricas
ApproximateNumberOfMessagesyApproximateNumberOfMessagesNotVisiblepara calcular el backlog. - Horizontal Pod Autoscaler (HPA): KEDA crea y maneja un HPA para el Deployment objetivo.
- IAM: Se requiere un rol o política con permisos para consultar métricas de SQS.
Instalación de KEDA
La forma recomendada de instalar KEDA es mediante Helm:
helm repo add kedacore /origin https://kedacore.github.io/helm-charts
helm repo update
helm install keda kedacore/keda --namespace keda --create-namespaceEste comando despliega:
- El operador de KEDA (
keda-operator). - El servidor de métricas (
keda-metrics-apiserver), que expone métricas externas a Kubernetes. - CRDs como
ScaledObjectyTriggerAuthentication.
Configuración de permisos IAM
Cada pod que consuma mensajes de SQS necesita permisos para:
sqs:GetQueueAttributessqs:ChangeMessageVisibilitysqs:DeleteMessagesqs:ReceiveMessage
Ejemplo de política IAM minimalista:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"sqs:GetQueueAttributes",
"sqs:ChangeMessageVisibility",
"sqs:DeleteMessage",
"sqs:ReceiveMessage"
],
"Resource": "arn:aws:sqs:us-east-1:123456789012:my-queue"
}
]
}En EKS, la forma más segura de asignar estos permisos es usando IRSA. Por ejemplo:
apiVersion: v1
kind: ServiceAccount
metadata:
name: sqs-consumer
namespace: workers
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/sqs-consumer-roleDefinición de ScaledObject
Para conectar un Deployment a una cola SQS, se crean dos recursos KEDA:
- TriggerAuthentication: Define cómo KEDA se autentica con AWS. Usando
queueURLFromEnvevita hardcodear la URL de la cola.
apiVersion: keda.sh/v1alpha1
kind: TriggerAuthentication
metadata:
name: sqs-trigger-auth
namespace: workers
spec:
podIdentity:
provider: aws-eks
identityMatch: true- ScaledObject: Define el Deployment a escalar y la métrica de scaling.
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: sqs-processor
namespace: workers
spec:
scaleType: scaleDownAndScaleUp
minReplicaCount: 0
maxReplicaCount: 10
cooldownPeriod: 30
triggers:
- type: aws-sqs-queue
metadata:
queueURL: http://sqs.us-east-1.amazonaws.com/123456789012/my-queue
region: us-east-1
queueLength: "10"Cálculo de réplicas
KEDA calcula el trabajo pendiente como:
outstanding_messages = ApproximateNumberOfMessages + ApproximateNumberOfMessagesNotVisibleEl número deseado de réplicas se calcula como:
desired_replicas = ceil(outstanding_messages / queueLength)Por ejemplo, con queueLength: "10":
- 0 mensajes → 0 réplicas (escala a cero).
- 5 mensajes → 1 réplica.
- 15 mensajes → 2 réplicas.
- 30 mensajes → 3 réplicas.
Los valores finales están acotados por minReplicaCount y maxReplicaCount.
Qué deberían hacer los administradores y equipos técnicos
- Evaluar workloads candidatos: Identificar aplicaciones que procesen mensajes de colas (SQS, RabbitMQ, Kafka, etc.) y donde el backlog sea la métrica crítica. Workloads ideales:
– Tareas en segundo plano (ej: limpieza de datos, envío de notificaciones).
– Sistemas event-driven con picos esporádicos.
- Instalar KEDA:
helm repo add kedacore https://kedacore.github.io/helm-charts
helm install keda kedacore/keda --namespace keda --create-namespace
- Configurar permisos IAM:
– Asignarla a un rol IAM y asociarlo al ServiceAccount del Deployment usando IRSA (en EKS) o kiam (en clusters no-EKS).
- Desplegar TriggerAuthentication y ScaledObject:
queueURL sea correcto y accesible desde el cluster.– Ajustar queueLength según la capacidad de procesamiento por pod (ej: si cada pod procesa ~50 mensajes por segundo, usar queueLength: "50").
– Configurar minReplicaCount y maxReplicaCount según los requisitos de disponibilidad y costo.
- Probar el escalado:
# Enviar mensajes a la cola (ejemplo con AWS CLI)
aws sqs send-message --queue-url http://sqs.us-east-1.amazonaws.com/123456789012/my-queue --message-body "test"
# Monitorear el ScaledObject
kubectl get scaledobject sqs-processor -n workers
# Observar el escalado de pods
kubectl get pods -n workers -w
- Ajustar parámetros:
cooldownPeriod: Tiempo de espera entre escalados (default: 5 minutos). Reducirlo para workloads con picos abruptos.– pollingInterval: Frecuencia de consultas a la cola (default: 30 segundos). Aumentarlo para colas con alta latencia.
- Monitorear:
keda_hpa_scaling_events_total, keda_scalers_average_value).– Configurar alertas para eventos de escalado anómalos (ej: scale-up frecuentes sin mensajes en la cola).
Conclusión
El autoscaling basado en la profundidad de colas SQS con KEDA resuelve una limitación clave del HPA tradicional: escalar según la demanda real de trabajo, no según métricas de infraestructura. Para workloads asincronos, esto significa respuesta más rápida a picos, menor desperdicio de recursos y costos optimizados en cloud.
La implementación requiere configurar KEDA, permisos IAM y recursos CRD, pero el esfuerzo se compensa con creces en entornos con carga variable. Además, el mismo patrón es aplicable a otras colas (RabbitMQ, Kafka) y fuentes de eventos (Natts, Azure Service Bus), lo que lo convierte en una herramienta versatile para cualquier arquitectura event-driven en Kubernetes.
Fuentes
- https://www.cncf.io/blog/2026/07/31/scaling-kubernetes-pods-with-keda-based-on-amazon-sqs-queue-depth/
