ECS y EKS: Orquestación de Contenedores en AWS

Durante la migración de su plataforma de pagos a la nube, Nexiabank enfrentaba un dilema crítico: necesitaban mantener la capacidad de procesar 2,000 transacciones por segundo con alta disponibilidad, mientras cumplían estrictas regulaciones financieras. Inicialmente, desplegaron su aplicación en ECS con modo EC2, lo que les dio control granular sobre la infraestructura. Sin embargo, la gestión de parches y el escalado manual de los nodos EC2 consumían recursos valiosos. Al migrar a Fargate, eliminaron la sobrecarga operativa mientras mantenían el rendimiento. Para sus componentes más críticos, implementaron EKS con nodos gestionados, aprovechando las capacidades avanzadas de Kubernetes para la recuperación automática y el despliegue progresivo. Esta arquitectura híbrida redujo sus costos operativos en un 35% y mejoró su tiempo de recuperación ante fallos de 15 minutos a menos de 30 segundos.

image.png

Distinción entre ECS y EKS

Amazon ofrece dos servicios principales para la orquestación de contenedores, cada uno con sus propias características y casos de uso:

Amazon Elastic Container Service (ECS)

ECS es un servicio de orquestación de contenedores propietario de AWS:

  • Desarrollado y optimizado específicamente para el ecosistema AWS
  • Integración nativa con servicios de AWS (CloudWatch, IAM, VPC, etc.)
  • Menor complejidad operativa
  • Curva de aprendizaje más suave

Amazon Elastic Kubernetes Service (EKS)

EKS es un servicio de Kubernetes gestionado:

  • Implementa el estándar de código abierto Kubernetes
  • Mayor portabilidad entre diferentes entornos (on-premise, multi-cloud)
  • Ecosistema más amplio de herramientas y extensiones
  • Mayor flexibilidad para configuraciones avanzadas

Comparación de Nomenclatura

La terminología difiere significativamente entre ambos servicios:

# Ejemplo de definición en EKS (Kubernetes) apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.14.2 ports: - containerPort: 80
// Ejemplo equivalente en ECS (Task Definition) { "family": "nginx-service", "containerDefinitions": [ { "name": "nginx", "image": "nginx:1.14.2", "essential": true, "portMappings": [ { "containerPort": 80, "hostPort": 80 } ] } ] }

Modos de Lanzamiento: EC2 vs. AWS Fargate

Tanto ECS como EKS ofrecen diferentes opciones para ejecutar contenedores:

Modo EC2

En este modo, los contenedores se ejecutan en instancias EC2 que tú gestionas:

  • Mayor control sobre la infraestructura subyacente
  • Capacidad para optimizar costos (especialmente con Spot Instances)
  • Responsabilidad de gestionar las instancias EC2 (parches, escalado, etc.)
  • Posibilidad de usar tipos de instancias específicos para cargas de trabajo especializadas

En ECS:

  • Debes crear y gestionar un Auto Scaling Group de instancias EC2
  • Las instancias ejecutan el agente de ECS
  • Puedes usar AMIs optimizadas para ECS

En EKS:

  • Puedes usar grupos de nodos gestionados o auto-gestionados
  • Las instancias ejecutan componentes de Kubernetes (kubelet, kube-proxy)
  • AWS ofrece AMIs optimizadas para EKS

image.png

AWS Fargate (Serverless Containers)

Fargate es un motor de computación serverless para contenedores:

  • Sin gestión de servidores - AWS maneja toda la infraestructura
  • Modelo de pago por recursos consumidos (vCPU, memoria)
  • Escalado automático a nivel de tarea/pod
  • Aislamiento mejorado entre aplicaciones

En ECS con Fargate:

  • Defines los requisitos de CPU y memoria en la Task Definition
  • ECS programa las tareas directamente en la infraestructura Fargate

En EKS con Fargate:

  • Defines perfiles de Fargate que determinan qué pods se ejecutan en Fargate
  • Kubernetes programa los pods en la infraestructura Fargate

image.png

¿Cuándo usar cada modo?

El balanceo de carga es crucial para aplicaciones en contenedores:

Integración de ALB con ECS

ECS se integra nativamente con Application Load Balancer:

  1. Dynamic Port Mapping: Permite ejecutar múltiples instancias del mismo contenedor en un host
  2. Path-based routing: Dirige el tráfico a diferentes servicios basados en la ruta URL
  3. Health checks: Monitorea la salud de los contenedores y redirige el tráfico
  4. Sticky sessions: Mantiene la afinidad de sesión cuando es necesario
// Fragmento de definición de servicio ECS con ALB { "serviceName": "web-service", "taskDefinition": "web-task:1", "loadBalancers": [ { "targetGroupArn": "arn:aws:elasticloadbalancing:region:account-id:targetgroup/web-target-group/1234567890123456", "containerName": "web", "containerPort": 80 } ], "desiredCount": 3, "launchType": "FARGATE" }

Integración de ALB con EKS

Para EKS, AWS proporciona el AWS Load Balancer Controller:

  1. Crea automáticamente ALBs basados en anotaciones en los recursos de Kubernetes
  2. Gestiona los target groups y las reglas de enrutamiento
  3. Soporta Ingress para enrutamiento basado en host/path
# Ejemplo de Ingress para EKS con ALB apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: web-ingress annotations: kubernetes.io/ingress.class: alb alb.ingress.kubernetes.io/scheme: internet-facing spec: rules: - http: paths: - path: /api pathType: Prefix backend: service: name: api-service port: number: 80 - path: / pathType: Prefix backend: service: name: frontend-service port: number: 80

Implementación de Auto Scaling

El escalado automático es esencial para manejar cargas variables:

Auto Scaling en ECS

ECS ofrece varias opciones de escalado:

  1. Service Auto Scaling: Ajusta automáticamente el número de tareas
    • Target Tracking: Mantiene una métrica objetivo (CPU, memoria)
    • Step Scaling: Escala basado en alarmas de CloudWatch
    • Scheduled Scaling: Escala según un cronograma predefinido
# Configurar Target Tracking Scaling para un servicio ECS aws application-autoscaling register-scalable-target \\ --service-namespace ecs \\ --scalable-dimension ecs:service:DesiredCount \\ --resource-id service/my-cluster/my-service \\ --min-capacity 1 \\ --max-capacity 10 aws application-autoscaling put-scaling-policy \\ --policy-name cpu70-target-tracking-scaling-policy \\ --service-namespace ecs \\ --scalable-dimension ecs:service:DesiredCount \\ --resource-id service/my-cluster/my-service \\ --policy-type TargetTrackingScaling \\ --target-tracking-scaling-policy-configuration '{ "TargetValue": 70.0, "PredefinedMetricSpecification": { "PredefinedMetricType": "ECSServiceAverageCPUUtilization" } }'
  1. Capacity Providers (para modo EC2): Gestiona automáticamente la capacidad de las instancias EC2 subyacentes

Auto Scaling en EKS

EKS ofrece dos niveles de escalado:

  1. Horizontal Pod Autoscaler (HPA): Escala el número de pods
    • Basado en métricas como CPU, memoria o métricas personalizadas
    • Integración con Prometheus para métricas avanzadas
# Ejemplo de HPA en Kubernetes apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: web-app-hpa spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: web-app minReplicas: 2 maxReplicas: 10 metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 70
  1. Cluster Autoscaler: Escala el número de nodos en el cluster
    • Añade nodos cuando hay pods que no pueden ser programados
    • Elimina nodos cuando están infrautilizados

Configuración de Networking y Seguridad

La configuración adecuada de red y seguridad es crucial para aplicaciones en contenedores:

Networking en ECS

ECS ofrece dos modos principales de networking:

  1. awsvpc: Modo recomendado y obligatorio para Fargate
    • Cada tarea recibe su propia interfaz de red elástica (ENI)
    • Direcciones IP privadas dentro de la VPC
    • Grupos de seguridad a nivel de tarea
    • Aislamiento de red mejorado
  2. bridge: Modo tradicional para ECS en EC2
    • Contenedores comparten la interfaz de red del host
    • Mapeo de puertos para exponer servicios
    • Grupos de seguridad a nivel de instancia
// Task Definition con modo awsvpc { "family": "web-app", "networkMode": "awsvpc", "containerDefinitions": [ { "name": "web", "image": "nginx:latest", "portMappings": [ { "containerPort": 80 } ] } ], "requiresCompatibilities": ["FARGATE"], "cpu": "256", "memory": "512" }

Networking en EKS

EKS utiliza el modelo de red de Kubernetes con algunas particularidades de AWS:

  1. Amazon VPC CNI: Plugin de red predeterminado
    • Asigna direcciones IP de la VPC directamente a los pods
    • Permite usar grupos de seguridad a nivel de pod
    • Integración con servicios de AWS
  2. Alternativas CNI: Calico, Cilium, Weave Net
    • Políticas de red avanzadas
    • Encriptación de tráfico entre pods
    • Observabilidad mejorada

Seguridad en ECS y EKS

Grupos de Seguridad

  • ECS con awsvpc: Grupos de seguridad a nivel de tarea
  • ECS con bridge: Grupos de seguridad a nivel de instancia
  • EKS con VPC CNI: Grupos de seguridad a nivel de pod (con configuración adicional)
# Crear un grupo de seguridad para tareas ECS aws ec2 create-security-group \\ --group-name ecs-tasks-sg \\ --description "Security group for ECS tasks" \\ --vpc-id vpc-12345678 # Permitir tráfico HTTP aws ec2 authorize-security-group-ingress \\ --group-id sg-12345678 \\ --protocol tcp \\ --port 80 \\ --cidr 0.0.0.0/0

IAM Roles

Tanto ECS como EKS utilizan roles de IAM para conceder permisos:

  1. Roles de ejecución: Permiten al servicio de contenedores realizar acciones en tu nombre
    • Extraer imágenes de ECR
    • Escribir logs en CloudWatch
    • Acceder a secretos
  2. Roles de tarea/pod: Permiten a las aplicaciones dentro de los contenedores acceder a servicios de AWS
    • Acceso a S3, DynamoDB, SQS, etc.
    • Implementación del principio de mínimo privilegio

En ECS:

// Task Definition con roles IAM { "family": "app", "executionRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole", "taskRoleArn": "arn:aws:iam::123456789012:role/app-task-role", "networkMode": "awsvpc", "containerDefinitions": [...] }

En EKS: EKS utiliza el proyecto de código abierto IAM Roles for Service Accounts (IRSA) para proporcionar identidades IAM a los pods:

# Service Account con IAM Role apiVersion: v1 kind: ServiceAccount metadata: name: app-service-account annotations: eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/app-pod-role

Casos de Uso y Patrones de Implementación

Microservicios con ECS Fargate

Ideal para:

  • Equipos que ya están profundamente integrados en el ecosistema AWS
  • Aplicaciones que requieren mínima gestión de infraestructura
  • Cargas de trabajo predecibles o con picos ocasionales

Patrón de implementación:

  1. Task Definitions con modo awsvpc
  2. Servicios ECS con Auto Scaling basado en Target Tracking
  3. ALB para enrutamiento basado en path
  4. Service Discovery para comunicación entre servicios

Aplicaciones Híbridas con EKS

Ideal para:

  • Organizaciones con presencia multi-cloud o on-premise
  • Aplicaciones que requieren características avanzadas de Kubernetes
  • Cargas de trabajo con requisitos específicos de programación o afinidad

Patrón de implementación:

  1. Nodos gestionados para cargas de trabajo predecibles
  2. Fargate para microservicios sin estado
  3. HPA para escalado basado en métricas personalizadas
  4. AWS Load Balancer Controller para gestión de Ingress
  5. ExternalDNS para integración con Route 53

Mejores Prácticas

Optimización de Costos

  1. Dimensionamiento adecuado: Asigna CPU y memoria según las necesidades reales
  2. Spot Instances: Utiliza instancias spot para cargas de trabajo tolerantes a interrupciones
  3. Savings Plans: Considera Compute Savings Plans para cargas predecibles
  4. Fargate Spot: Aprovecha Fargate Spot para tareas en segundo plano

Seguridad

  1. Principio de mínimo privilegio: Asigna solo los permisos necesarios
  2. Escaneo de imágenes: Utiliza ECR Image Scanning o herramientas de terceros
  3. Secretos: Gestiona secretos con AWS Secrets Manager o Parameter Store
  4. Actualizaciones: Mantén las imágenes y componentes actualizados

Observabilidad

  1. Logs centralizados: Configura CloudWatch Logs o soluciones como ELK/Grafana
  2. Métricas detalladas: Implementa métricas personalizadas para aplicaciones
  3. Trazabilidad: Utiliza AWS X-Ray o soluciones como Jaeger/Zipkin
  4. Alertas: Configura alarmas para métricas críticas

Resumen

ECS y EKS representan dos enfoques diferentes para la orquestación de contenedores en AWS, cada uno con sus propias fortalezas y casos de uso. ECS ofrece una experiencia más integrada y simplificada dentro del ecosistema AWS, mientras que EKS proporciona la flexibilidad y portabilidad del estándar Kubernetes.

La elección entre EC2 y Fargate como modo de lanzamiento depende de tus requisitos específicos de control, optimización de costos y sobrecarga operativa. La integración con servicios como ALB facilita la exposición de aplicaciones en contenedores, mientras que las capacidades de auto scaling permiten manejar eficientemente cargas variables.

La configuración adecuada de networking y seguridad es fundamental para garantizar que tus aplicaciones en contenedores sean seguras, escalables y cumplan con los requisitos de conformidad. Al seguir las mejores prácticas y patrones de implementación, puedes aprovechar al máximo estos servicios para construir arquitecturas modernas y resilientes en AWS.

La clave para el éxito con ECS y EKS está en entender las diferencias fundamentales entre estos servicios y seleccionar el que mejor se alinee con tus objetivos técnicos y organizacionales, considerando factores como la experiencia del equipo, los requisitos de portabilidad y la integración con otros servicios de AWS.