AWS Certified CloudOps Engineer - Associate

Grupos de Auto Scaling de EC2

Cómo un Auto Scaling group sostiene una flota en el tamaño que pediste: los tres números de capacidad, los health checks que deciden qué se reemplaza, el balance zonal y las reglas que eligen qué instancia muere en un scale in.

Intermedio 26 minutos 5 Objetivos de aprendizaje
  1. Explicar cómo interactúan la capacidad mínima, deseada y máxima, y cuál de ellas cambia realmente una política de escalado
  2. Identificar las fuentes de health check que usa un Auto Scaling group y configurar el grace period para que las instancias de arranque lento sobrevivan
  3. Predecir cómo un Auto Scaling group distribuye y reequilibra instancias entre zonas de disponibilidad
  4. Seguir la política de terminación predeterminada hasta la instancia concreta que terminaría
  5. Enunciar qué previene la protección contra scale in y qué no previene

Una empresa de medios corre 12 instancias EC2 detrás de un Application Load Balancer. El pico de tráfico llega unas 3 horas las tardes de días hábiles. El resto de la semana, 3 instancias cubrirían la carga con margen de sobra, pero la flota se queda en 12 porque nadie quiere ser el que la achicó la semana antes de un lanzamiento. Después, un sábado, una instancia llena su disco, deja de responder, y se queda ahí muerta hasta el lunes a la mañana porque ningún health check estaba conectado a algo que pudiera actuar.

Son 2 fallas distintas, y un Auto Scaling group arregla las dos con el mismo mecanismo. Es un grupo de instancias EC2 que AWS mantiene en un tamaño que tú declaras, lanzando y terminando instancias para sostener ese tamaño, y reemplazando cualquier instancia que deje de verse saludable. Las políticas de escalado que hacen mover ese tamaño vienen en la lección siguiente. Esta cubre la maquinaria que está debajo, porque casi toda pregunta de escalado que sale mal en producción sale mal acá, no en la política.

Tres números, y una política mueve solo uno

Un Auto Scaling group se define con 3 valores de capacidad.

  • La capacidad mínima es un piso. El grupo nunca corre menos instancias que esto.
  • La capacidad máxima es un techo. El grupo nunca corre más.
  • La capacidad deseada es el número que el grupo está tratando de correr ahora mismo.

Supón que pones mínimo 2, deseada 6, máximo 12. El grupo lanza 6 instancias. Si más tarde una política de escalado calcula que hacen falta 15 instancias para sostener la CPU en el objetivo, el grupo llega a 12 y se detiene, porque 15 está arriba del techo. Si un cálculo de scale in dice que alcanza con 1 instancia, el grupo baja a 2 y se detiene.

La frase que conviene memorizar: una política de escalado cambia la capacidad deseada, y solo la capacidad deseada. El mínimo y el máximo son límites que recortan el resultado. Acá vive un malentendido común. Poner la capacidad máxima en 12 no significa que el grupo corra 12 instancias. Significa que el grupo nunca va a correr más de 12. Un grupo parado en su máximo porque la capacidad deseada llegó hasta ahí es una situación completamente distinta de un grupo en 6 con margen hasta 12, y al examen le gustan los enunciados donde el grupo ya tocó su techo y la política de escalado parece rota.

También hay valor en un grupo sin ninguna política de escalado. Con la capacidad deseada fija en 6, el grupo igual vigila esas 6 instancias y reemplaza las que fallan un health check. Mantener capacidad y escalar capacidad son funciones separadas, y la primera es la razón por la que vale la pena crear un grupo incluso para una flota cuyo tamaño nunca cambia.

El launch template es el plano

El grupo necesita saber qué lanzar. Eso sale de un launch template: AMI ID, tipo de instancia, key pair, security groups, IAM instance profile, block device mappings, user data y el resto de la superficie de lanzamiento de EC2.

Los launch templates tienen versiones. Creas la versión 3 con una AMI nueva, apuntas el grupo ahí, y toda instancia lanzada desde ese momento usa la versión 3 mientras las instancias existentes siguen corriendo con lo que sea que lanzaron. Ese historial de versiones es lo que hace funcionar a la política de terminación predeterminada y al instance refresh, y los 2 aparecen más adelante.

El viejo launch configuration todavía existe en material antiguo y en cuentas antiguas. No tiene versiones, no se puede editar (lo reemplazas), y AWS no lo extiende a las funciones nuevas de EC2. Trata "migrar el grupo de un launch configuration a un launch template" como la respuesta esperada cada vez que un escenario mencione Spot y On-Demand en un mismo grupo, varios tipos de instancia, o un instance refresh, porque ninguna de esas cosas funciona con un launch configuration.

Los health checks deciden qué se reemplaza

Una instancia en un Auto Scaling group arranca como Healthy y se queda así hasta que algo le diga lo contrario al grupo. El grupo escucha varias fuentes:

FuenteQué reportaActiva de forma predeterminada
Status checks de Amazon EC2Fallas de system y instance status check, y cualquier estado que no sea running
Elastic Load BalancingLa salud del target en el target group asociadoNo, la activas tú
VPC LatticeLa salud del target en un target group de LatticeNo, la activas tú
Amazon EBSUn volumen asociado está deterioradoNo, la activas tú
CustomLo que reporte tu propio código con set-instance-healthLa llama tu código

Esa tabla esconde la desconfiguración más común de todo el tema, así que conviene decirla en voz alta. De forma predeterminada un Auto Scaling group solo usa los status checks de EC2. Una instancia cuya aplicación devuelve HTTP 500 en cada pedido igual pasa los status checks de EC2, porque el hipervisor está bien y el sistema operativo está corriendo. El ALB sí lo nota, marca el target como unhealthy y deja de mandarle tráfico. El Auto Scaling group no la reemplaza, y terminas con un grupo que reporta 6 instancias saludables detrás de un target group que reporta 5 targets saludables, de forma indefinida. Activar el health check de Elastic Load Balancing en el grupo es lo que cierra esa brecha.

aws autoscaling update-auto-scaling-group \
  --auto-scaling-group-name web-asg \
  --health-check-type ELB \
  --health-check-grace-period 300

El health check grace period de ese comando es lo segundo que hay que acertar. Es el tiempo mínimo que se deja tranquila a una instancia recién puesta en servicio antes de que un veredicto unhealthy pueda terminarla. Los health checks de Elastic Load Balancing empiezan apenas la instancia queda registrada, así que una aplicación que necesita 4 minutos para calentar cachés fallaría sus primeros chequeos y la matarían por eso. El grace period compra ese tiempo.

Los valores predeterminados no son iguales en todas partes, y esta es una trampa real:

  • Consola: 300 segundos
  • AWS CLI o SDK: 0 segundos, que apaga el grace period por completo

Un grupo creado por una plantilla de CloudFormation o un script de CLI sin grace period explícito va a juzgar las instancias desde el primer segundo, y una flota de arranque lento puede caer en un bucle donde cada reemplazo muere antes de terminar de arrancar. Durante el grace period aplica una excepción: si la instancia sale del estado running de EC2, por ejemplo porque alguien la detuvo, el grupo la marca Unhealthy y la reemplaza de inmediato sin esperar.

No resuelvas el problema empujando el grace period a una hora. Un grace period alto es tiempo muerto en el que una instancia genuinamente rota se queda en servicio. El arreglo mejor, que cubre la lección del ciclo de vida, es un lifecycle hook de lanzamiento que mantiene la instancia fuera de servicio hasta que termina su bootstrap, lo que te deja poner el grace period bajo.

Dos comportamientos más para tener a mano: el reemplazo por health check no espera ningún cooldown, y una instancia que el grupo ya marcó unhealthy se saltea por completo la evaluación de la política de terminación. Las instancias unhealthy no se eligen, simplemente se quitan.

El balance zonal va antes que todo lo demás

Le das subredes al grupo, y cada subred vive en exactamente una zona de disponibilidad. Cuando el grupo lanza una instancia, elige la zona habilitada con menos instancias, y dentro de esa zona la subred con más direcciones IP libres. Cuando termina, mira primero la zona con más instancias.

Ese orden importa más de lo que parece. El balance zonal se evalúa antes que la política de terminación, siempre. Así que un grupo con 5 instancias en us-east-1a y 3 en us-east-1b va a terminar en us-east-1a incluso si la única instancia más vieja del grupo está en us-east-1b. Cuando un escenario dice "se terminó la instancia más nueva y no entendemos por qué", el desbalance zonal suele ser la respuesta.

Los grupos se desbalancean por razones ordinarias: una zona se quedó sin capacidad un rato y se recuperó, cambiaste las zonas habilitadas, pusiste instancias en standby, o el precio de Spot volvió a bajar de tu máximo en una zona que había quedado fuera de precio. Cuando eso pasa, el grupo corre una actividad de reequilibrio entre zonas de disponibilidad. Lanza primero la instancia nueva y termina la vieja después, así que el reequilibrio nunca hunde tu capacidad.

Lanzar antes de terminar crea un problema obvio cuando el grupo ya está en su capacidad máxima, y AWS lo resolvió con una excepción documentada: durante una actividad de reequilibrio el grupo puede superar temporalmente la capacidad máxima en 10 por ciento o una instancia, lo que sea mayor. El margen dura solo lo que dura el reequilibrio, casi siempre unos minutos. Si no toleras ni ese exceso, una instance maintenance policy te deja fijar el rango de porcentaje saludable en su lugar.

Qué instancia muere en un scale in

Una vez elegida la zona, la política de terminación predeterminada recorre las instancias desprotegidas en este orden:

  1. Configuraciones desactualizadas primero. Para un grupo sobre launch templates, eso significa instancias lanzadas desde un launch configuration, después instancias lanzadas desde un launch template distinto, después instancias en la versión más vieja del launch template actual.
  2. La más cercana a su próxima hora de facturación. Si quedan varios candidatos, el grupo elige el más cercano a su próxima hora de facturación, y desempata al azar. Este paso importa mucho menos que antes, porque la mayor parte del uso de EC2 se factura por segundo.

El objetivo de diseño es retirar las configuraciones viejas de forma natural a medida que el grupo hace scale in, y por eso un grupo que sube y baja durante el día converge de a poco a la versión actual del launch template sin que nadie haga nada.

Los grupos con instancias mixtas agregan un paso adelante. El grupo primero decide si debe irse una instancia Spot o una On-Demand, para que la flota tienda de nuevo a la proporción que configuraste, después revisa si terminar una instancia en particular mejora la alineación con tu estrategia de asignación, y recién ahí baja a configuraciones desactualizadas y hora de facturación.

Puedes sobrescribir la política cuando el valor predeterminado no sirve para tu caso:

PolíticaTerminaÚsala cuando
DefaultConfiguración desactualizada, después la más cercana a la próxima hora de facturaciónCasi siempre
OldestInstanceLa instancia que lleva más tiempo corriendoEstás moviendo la flota a un tipo de instancia nuevo
NewestInstanceLa instancia lanzada más recientementeEstás probando una configuración nueva y quieres revertirla primero
OldestLaunchTemplateTemplates no vigentes primero, después la versión más viejaEstás retirando una configuración anterior
OldestLaunchConfigurationEl launch configuration más viejoEstás migrando fuera de los launch configurations
ClosestToNextInstanceHourLa más cercana al límite de hora de facturaciónSolo con instancias facturadas por hora
AllocationStrategyLas instancias que alejan la flota de tu estrategia de asignaciónCambiaron los pools de Spot o las prioridades de On-Demand

Elijas lo que elijas, el balance zonal gana primero. Una política de terminación solo decide qué instancia se va dentro de la zona ya seleccionada.

Proteger una instancia contra scale in, y qué no te compra eso

Algunas instancias no deberían ser elegidas. Un host de contenedores a mitad de un trabajo, un agente de build 40 minutos adentro de una compilación, un nodo sosteniendo una sesión larga. La protección contra scale in marca una instancia como no elegible para la terminación por un evento de scale in. Puedes activarla en el grupo para que cada instancia nueva la herede, y después limpiarla por instancia cuando el trabajo termina, que es el patrón que usan los orquestadores de contenedores.

La mitad importante de esta función es lo que no hace. La protección contra scale in no previene:

  • El reemplazo después de un health check fallido
  • La interrupción de una instancia Spot
  • El fin de una reserva de Capacity Block
  • La terminación manual con terminate-instance-in-auto-scaling-group
  • La terminación manual desde la consola, la CLI o la API de EC2

Esa última sorprende. Para frenar a una persona que termina la instancia desde la consola de EC2 necesitas EC2 termination protection, un ajuste aparte sobre la instancia misma. Los 2 nombres suenan a la misma función y no lo son.

Hay un caso borde que aparece en incidentes reales: si todas las instancias del grupo están protegidas y se dispara un evento de scale in, el grupo baja la capacidad deseada pero no puede terminar nada. El historial de actividad registra Could not scale to desired capacity because all remaining instances are protected from scale in, y el grupo se queda corriendo en silencio por encima de su propia capacidad deseada hasta que alguien limpie la protección.

Apagar partes del grupo mientras trabajas

Cuando necesitas que el grupo deje de actuar un rato, suspende procesos individuales en vez de borrar políticas:

ProcesoSuspenderlo detiene
LaunchAgregar instancias por cualquier motivo, incluido llenar un warm pool
TerminateQuitar instancias por cualquier motivo
AddToLoadBalancerRegistrar instancias nuevas con el target group
AlarmNotificationQue las políticas de escalado dinámico reaccionen a sus alarmas de CloudWatch
AZRebalanceEl reequilibrio entre zonas de disponibilidad
HealthCheckMarcar instancias unhealthy desde señales de EC2 o ELB
ReplaceUnhealthyTerminar y reemplazar instancias ya marcadas unhealthy
InstanceRefreshLos reemplazos de instance refresh
ScheduledActionsEl escalado programado

Elegir el correcto es una pregunta de diagnóstico. Suspender Launch corta la rotación pero también bloquea un scale out programado que quizás todavía quieres; suspender ReplaceUnhealthy corta solo el bucle de reemplazo. Y si un grupo lleva más o menos 24 horas fallando al lanzar instancias, AWS aplica una suspensión administrativa por su cuenta. Cuando alguien reporta que un grupo "dejó de funcionar", revisa los procesos suspendidos antes de revisar la política.

Consejos para el examen

  • Un escenario donde el grupo se niega a crecer y la política se ve correcta es una pregunta de capacidad máxima. Lee los 3 números antes de leer la política.
  • "El load balancer muestra el target unhealthy pero la instancia nunca se reemplaza" siempre es el tipo de health check. El grupo usa solo status checks de EC2 de forma predeterminada.
  • "Las instancias se terminan y relanzan en bucle apenas arrancan" es el health check grace period, y la pista es un grupo creado por CLI o CloudFormation, donde el valor predeterminado es 0 en vez de los 300 de la consola.
  • No confundas los 2 temporizadores. El health check grace period es cuánto falta para que los health checks puedan matar una instancia nueva. El cooldown predeterminado, 300 segundos, es una pausa entre actividades de simple scaling y pertenece a la lección siguiente.
  • "Se terminó una instancia más nueva antes que una más vieja" significa que las zonas estaban desbalanceadas. El balance zonal supera a la política de terminación.
  • Cualquier cosa sobre Spot más On-Demand en un mismo grupo, varios tipos de instancia, o instance refresh descarta los launch configurations. La respuesta necesita un launch template.
  • La protección contra scale in bloquea solo el scale in. Si el enunciado dice health check, interrupción de Spot, o una persona haciendo clic en Terminate en la consola, la protección es la respuesta equivocada.

El modelo que conviene llevarse a la lección siguiente es angosto y carga peso: el grupo tiene una sola perilla que mueve, la capacidad deseada, y un conjunto de reglas para cómo se crean, se juzgan y se eligen para retirar las instancias alrededor de esa perilla. Todo lo que viene, target tracking, step scaling, escalado predictivo, es una forma distinta de decidir cuánto debería valer ese único número.