Operar el workload
Operar el workload — red, escalado y fallas
De entender a operar
La Semana 2 terminó con el ambiente entendido: se lee el template, se actualiza el stack, y se reconocen el clúster, la task definition, y el servicio. Esta semana se opera. Tres preguntas guían la sesión: ¿cómo llega el tráfico al contenedor?, ¿cómo crece el sistema cuando hay más carga?, y ¿qué ocurre cuando una tarea no arranca?
El camino del tráfico
Cuando se abre la URL de la aplicación, la petición atraviesa una cadena de recursos antes de llegar al contenedor. Conocer esa cadena es lo que permite diagnosticar dónde se corta cuando algo falla.
El camino de una petición
Internet
→ Application Load Balancer (puerto 80)
→ Listener
→ Target Group
→ Tarea de Fargate (contenedor, puerto 8080)
flowchart LR U["Internet"] --> L["ALB<br/>(puerto 80)"] L --> LI["Listener"] LI --> TG["Target Group<br/>(health checks)"] TG --> T1["Tarea Fargate<br/>(puerto 8080)"] TG --> T2["Tarea Fargate<br/>(puerto 8080)"]
- El ALB recibe el tráfico HTTP en el puerto 80, en subredes públicas.
- El listener define en qué puerto escucha el ALB y a qué target group reenvía.
- El target group agrupa los destinos —las tareas— y verifica su salud.
- La tarea corre en una subred, con un grupo de seguridad que permite el tráfico del ALB hacia el puerto del contenedor.
Los grupos de seguridad son la pieza que conecta —o bloquea— cada salto: uno permite tráfico de internet hacia el ALB en el puerto 80; otro permite tráfico del ALB hacia la tarea en el puerto 8080. Si una petición no llega, casi siempre es un grupo de seguridad o un health check fallando.
Health checks
El target group verifica periódicamente que cada tarea responda en una ruta de salud
(por ejemplo, GET /). Una tarea que responde es healthy y recibe tráfico; una que
no responde es unhealthy y el ALB deja de enviarle peticiones. Si todas las tareas
están unhealthy, el ALB devuelve 503 aunque los contenedores estén corriendo.
Escalar el servicio
En la Semana 2 cambió DesiredCount a mano. En producción la carga varía, y ajustarla
manualmente no escala. El auto scaling del servicio ajusta el número de tareas según
una métrica.
La forma más común es target tracking: se fija un objetivo —por ejemplo, "mantener el uso de CPU promedio en 50%"— y ECS agrega o quita tareas para sostenerlo. Si la CPU sube por encima del objetivo, lanza más tareas; si baja, las reduce, sin bajar del mínimo definido.
Cuando una tarea no arranca
Un servicio que no logra mantener sus tareas sanas es el problema operativo más común. ECS no oculta el motivo: lo deja escrito en la tarea detenida.
Cuando una tarea termina inesperadamente, aparece en la lista de tareas detenidas
(stopped), con un campo stoppedReason que dice por qué. Las causas habituales:
stoppedReason (resumen) | Causa |
|---|---|
CannotPullContainerError | El URI de la imagen es incorrecto, o el rol no tiene permiso sobre ECR. |
Essential container ... exited | El contenedor arrancó y se cerró solo —error de la aplicación; revise los logs. |
Task failed ELB health checks | La tarea corre pero no pasa el health check; el ALB la da de baja. |
La regla de diagnóstico: una tarea detenida siempre tiene un stoppedReason, y cuando
ese motivo apunta a la aplicación, la respuesta está en los logs —el grupo de
CloudWatch Logs identificado en la Semana 2.
Práctica guiada: configurar auto scaling
Definir la política
- Abrir ECS → Clusters → su clúster → su servicio.
- En la pestaña Configuration and tasks, buscar Service auto scaling y pulsar Update.
- Activar Service auto scaling, y fijar el número mínimo de tareas en
1y el máximo en4. - Agregar una política de tipo Target tracking, métrica
ECSServiceAverageCPUUtilization, con un valor objetivo de
50. - Guardar los cambios.
Verificar los destinos sanos
- Abrir EC2 → Target Groups y seleccionar el target group de la aplicación.
- En la pestaña Targets, confirmar que las tareas aparecen como healthy. Esos son los destinos a los que el ALB reparte el tráfico.
Ejercicio 12 — Configurar el escalado y verificar la salud
Configurar auto scaling para el servicio con seguimiento de CPU (objetivo 50%, mínimo 1, máximo 4 tareas). Luego, en el target group del ALB, confirmar que las tareas están registradas como sanas.
- Abrir ECS → Clusters → su clúster → su servicio.
- En Configuration and tasks → Service auto scaling, pulsar Update.
- Activar el auto scaling; fijar mínimo 1, máximo 4.
- Agregar una política Target tracking sobre ECSServiceAverageCPUUtilization con objetivo 50. Guardar.
- Abrir EC2 → Target Groups, seleccionar el target group de la aplicación, y abrir la pestaña Targets.
- Confirmar que las tareas aparecen con estado healthy —son los destinos activos detrás del balanceador.
CI/CD y el rol de un pipeline
Lo que ya hace a mano
A lo largo del taller se construyó, sin nombrarlo, un flujo de entrega completo. Cada vez que cambia el código, hoy se ejecuta a mano una secuencia: subir el commit a CodeCommit, lanzar el build en CodeBuild, esperar la imagen en ECR, y actualizar el servicio de ECS para que tome la nueva imagen.
Funciona, pero depende de que alguien recuerde los pasos, los ejecute en orden, y no se saltee ninguno. CI/CD automatiza exactamente esa secuencia.
Qué es CI/CD
- Integración continua (CI): cada cambio se integra y se construye automáticamente. En este taller, eso es el build de CodeBuild disparándose con cada commit.
- Entrega continua (CD): cada cambio que pasa el build avanza automáticamente hacia el despliegue, con las verificaciones y aprobaciones que el equipo defina.
La idea central no es la velocidad por sí misma, sino la reproducibilidad: el camino
del código a producción es siempre el mismo, descrito una vez y ejecutado igual cada vez.
El mismo principio que vio en git (push en lugar de subir archivos) y en CloudFormation
(lanzar un template en lugar de clicar recursos), ahora aplicado al flujo entero.
El pipeline
Un pipeline es la descripción de ese flujo automatizado. AWS CodePipeline modela el camino como una secuencia de etapas (stages), y cada etapa contiene una o más acciones.
Anatomía de un pipeline
Source Build Deploy
(CodeCommit) → (CodeBuild) → (ECS)
- Stage — una fase del flujo (Source, Build, Deploy).
- Action — un paso dentro de una etapa.
- Artifact — lo que una etapa produce y pasa a la siguiente.
- Transition — el paso de una etapa a la siguiente.
- Una etapa agrupa un paso del flujo: obtener el código, construir, desplegar.
- Una acción es una tarea concreta dentro de una etapa (por ejemplo, "ejecutar este proyecto de CodeBuild").
- Un artefacto es lo que una etapa entrega a la siguiente: la etapa Source entrega el código, la etapa Build entrega la imagen.
- Una transición conecta una etapa con la siguiente; puede ser automática o estar detenida a la espera de una aprobación.
Leer un pipeline existente
Antes de crear uno, conviene saber leerlo —en un equipo real, lo habitual es heredar pipelines, no empezarlos de cero. La vista de CodePipeline muestra las etapas de izquierda a derecha, cada una con el estado de su última ejecución: en curso, exitosa, o fallida. Al leer un pipeline ajeno, las preguntas útiles son: ¿qué dispara la primera etapa?, ¿qué produce cada etapa?, ¿dónde hay aprobaciones manuales?, y ¿en qué etapa falla cuando falla?
En la próxima sesión se construye un pipeline que automatiza el flujo que hoy se hace a mano: Source desde CodeCommit, Build con el proyecto de CodeBuild, y Deploy hacia ECS, con una aprobación manual antes de desplegar.
Preguntas puente
Estas preguntas cierran la sesión presencial y abren la remota. En la sesión de hoy se operó el workload —red, escalado, fallas— y se vio qué es un pipeline. Conviene reflexionarlas antes de la sesión remota, donde se construye el pipeline, se conecta a las notificaciones, y se abre la observabilidad.
Pregunta 1
Para automatizar el flujo que hoy se hace a mano, ¿qué etapas necesitaría un pipeline de la aplicación, y en qué orden?
Tres etapas, en este orden:
- Source — obtener el código desde CodeCommit. Es lo que dispara el pipeline: un commit nuevo en la rama vigilada.
- Build — ejecutar el proyecto de CodeBuild, que construye la imagen Docker y la
publica en ECR (el
buildspec.ymlcorrespondiente). - Deploy — actualizar el servicio de ECS para que tome la nueva imagen.
El orden no es arbitrario: cada etapa consume el artefacto de la anterior. No se puede construir sin el código, ni desplegar sin la imagen. Es la misma secuencia que ejecuta hoy manualmente, ahora descrita una vez.
Pregunta 2
¿Dónde, en ese flujo, agrega valor una aprobación manual? ¿Y dónde solo lo haría más lento sin aportar nada?
Una aprobación manual agrega valor antes de la etapa de Deploy: es el punto donde alguien confirma que la imagen recién construida puede salir a producción. Da una pausa deliberada entre "se construyó" y "se desplegó", útil cuando el despliegue es delicado o requiere coordinación.
Ponerla antes del Build solo molestaría: construir es barato, reproducible, y no afecta a nadie —no hay nada que aprobar todavía. La regla práctica: las aprobaciones manuales van delante de las acciones irreversibles o visibles para el usuario, no delante de los pasos internos y repetibles.
Pregunta 3
Cuando el build termina —en éxito o en error— ¿quién debería enterarse, y por qué medio?
Debe enterarse el equipo, por el canal donde ya conversa —en esta organización, Microsoft Teams— sin tener que mirar la consola. Un build exitoso confirma que el cambio avanzó; uno fallido necesita atención rápida, y cuanto antes se detecte, antes se corrige.
El mecanismo que lo hace posible es el que adelantamos en la Semana 1: el evento del build lo capturan las reglas de notificación, lo publican en SNS, y AWS Chatbot lo entrega a Teams. En el laboratorio lo veremos como un toast en la guía del instructor, que es un espejo de ese mismo flujo. Lo construimos en la próxima sesión.