Autoescalado en Amazon AWS empleando VPC

Mediante el siguiente artículo se pretende definir la configuración necesaria para poder desplegar una arquitectura en Amazon, la cual pueda autoescalar en función del consumo de CPU de las instancias que pertenezcan al grupo de autoescalado.

Requisitos previos 

Para poder configurar correctamente el autoescalado en Amazon es necesario realizar los siguientes pasos previos: 

  • Instalar la interfaz de líneas de comando de autoescalado. http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/UsingTheCommandLineTools.html
  • Instalar la interfaz de líneas de comando de CloudWatch 
  • Disponer de una AMI que esté configurada de tal forma que puede ser arrancada y puesta en producción. 
  • Disponer de un balanceador “ELB” que contemple las zonas de disponibilidad en las que se quiere desplegar las instancias de Amazon. “Es necesario tener anotado su nombre” 
  • Tener los identificadores de las subredes que se emplearán para realizar el autoescalado. 
Crear la configuración de arranque 

El primer paso necesario para poder empezar a autoescalar consiste en definir la configuración de arranque. Es muy importante definir la región en la que queremos que el autoescalado funcione ya que por defecto se emplean regiones americanas. 

Si se desea que el autoescalado se ejecute en una VPC en concreto será necesario indicar el grupo de seguridad que se quiere emplear. 

En este paso también se definirá la ami así como el tipo de instancia que se quiere emplear. El comando a ejecutar será el siguiente:

as-create-launch-config "nombre de la configuración de arranque" --region "región en la que nos encontramos" --image-id "id de la ami" --instance-type "tipo de instancia" --group "grupo de seguridad"

Aclaraciones: Como región si estamos en Europa puede definir eu-west-1 y si queremos instancias de tipo micro se definirá de la siguiente forma t1.micro


Crear el grupo de autoescalado 

En este paso se creará el grupo de autoescalado. Es muy importante que la región sea la correcta. Al igual que en el paso anterior, la región por defecto suele corresponder con regiones americanas y es necesario cambiarlo si estamos en otra zona.

Si se desea que el autoescalado se despliegue en una VPC, será necesario tener previamente identificadas aquellas subredes que pertenecen a dicha VPC.

Nota Importante: Es necesario emplear el identificador de la subred y no el identificador de la VPC 

A través del atributo min-size se definirá el número mínimo de instancias que el grupo de autoescalado podrá tener como mínimo. Es decir, si se especifica el valor 2, siempre tendremos dos instancias como mínimo. Por otra parte, max-size permite definir el número máximo de instancias que puede tener el grupo de autoescalado. 

Otro paso muy importante, consiste en definir el nombre del balanceador que queremos que emplee el grupo de autoescalado. Es muy importante que el balanceador contemple las zonas de disponibilidad que queremos que hagan uso las instancias. Si este apartado no se configura correctamente, es posible que se creen y apaguen instancias continuamente sin que se comprenda el motivo. En el ejemplo que se verá más adelante se ha definido la zona eu-west-1c la cual tiene que estar contemplada por el balanceador. Con el comando health-check-type se indicará que el balanceador se encargará de realizar el análisis de la disponibilidad de las instancias y que el mismo indicará cuando una instancia debe de ser sacada del grupo de autoescalado ya que no está funcionando correctamente. Es posible definir mas de un balanceado para aquellas configuraciones que se quieren balancear tanto peticiones externas como internas. 

Al ejecutar el comando en concreto, se emplearán otros atributos que permitirán parametrizar la configuración de autoescalado. Desired Capacity permitirá configurar el número de instancias que se quieren tener arrancadas desde el principio. De la misma forma, termination policie permite especificar cómo queremos que actúe Amazon AWS a la hora de terminar instancias. En este caso en concreto se desea que las instancias que se eliminen sean las más recientes y no las mas antiguas.  

Otro aspecto a tener en cuenta consiste en que hay que definir un periodo de tiempo de seguridad “gracia” durante el cual tras arrancar una instancia EC2 no se tendrán en cuenta las verificaciones de salud de la instancia. Este valor se especifica en segundos. Esto es así debido a que las instancias tardan un tiempo en arrancar y estar disponibles. Si se define un periodo de tiempo demasiado bajo, es posible que a las instancias no les dé tiempo suficiente a arrancar por lo cual el sistema de autoescalado las descarte ya que ha pasado el periodo de tiempo definido. Esto puede producir bucles en los cuales se aprecien instancias que se arrancan y se destruyen sin parar. 

Por lo tanto, la sentencia a emplear tendrá el siguiente formato:

as-create-auto-scaling-group "hombre" --launch-configuration "nombre de la configuración de arranque" --availability-zones "Zona de disponibilidad" --min-size "número mínimo de instancias del grupo" --max-size "número máximo de instancias en el grupo" --load-balancers “Balamceador o balanceadores a emplear” --health-check-type "Quién se encargará de comprobar el estado de las instancias" --grace-period "Tiempo del periodo de gracia" --region "región" --vpc-zone-identifier "subred en la que queremos que arranquen las instancias" --desired-capacity "número de instancias con las que arrancará el grupo" --termination-policies "instancias que se apagarán cuando sea necesario escalar hacia abajo"

Un ejemplo de configuración de grupo de autoescalado sería el siguiente: 

as-create-auto-scaling-group frontal --launch-configuration frontal --availability-zones eu-west-1c --min-size 1 --max-size 2 --load-balancers “Balanceador1,Balanceador2” --health-check-type ELB --grace-period 480 --region eu-west-1 --vpc-zone-identifier subnet-8888888 --desired-capacity 1 --termination-policies "NewestInstance" 

Para verificar que el grupo se ha creado correctamente se ejecutará el siguiente comando: 

as-describe-auto-scaling-groups "nombre del grupo"  -H --region "región"

Por el contrario, si se quieren modificar aspectos de la configuración de este grupo de autoescalado se ejecutará el siguiente comando teniendo en cuenta aquellos parámetros que se desean modificar: 

as-update-auto-scaling-group "nombre del grupo" --max-size 3 --min-size 1 --region "región"

En cualquier momento se podrán describir las actividades de escalado que se están ejecutando a través del siguiente comando: 

as-describe-scaling-activities --auto-scaling-group "nombre del grupo"  -H --region "región"

Si se desea especificar el periodo de tiempo durante el cual no se tendrán en cuenta cambios realizados por otras alarmas tras una actividad satisfactoria de autoescalado se empleará el atributo --honor-cooldown. Por defecto el valor es de 300. 

Generación de políticas de autoescalado 

Las políticas son necesarias para indicar a Amazon AWS cuando se desea aumentar el número de instancias o reducirlas. En este caso se van a definir dos políticas por las cuales se crecerá o decrecerá en una instancia y se esperará un periodo de tres minutos. 

A través del parámetro ChangeInCapacity se indicará que se puede aumentar o decrecer la capacidad existente. Si se quisiera que una vez que se cumpla la política se defina un número exacto de instancias se empleará ExactCapacity. PercentChangeinCapacity ampliará o reducirá en función del porcentaje especificado. El parámetro adjustement se empleará para indicar como se realizará el ajuste. Es decir, el número de instancias que se quieren sumar o eliminar. 

El formato de las sentencias será el siguiente:

as-put-scaling-policy --auto-scaling-group "Nombre del grupo de autoescalado" --name "nombre de la policita" --adjustment "En  cuantas instancias se hace el ajuste" --type "tipo de política" --cooldown "Tiempo sin actuar" --region "región" 

Como ejemplos, véanse las siguientes políticas que serán necesarias crear para crecer y decrecer instancias: 

as-put-scaling-policy --auto-scaling-group frontal --name scale-up --adjustment 1 --type ChangeInCapacity --cooldown 480 --region eu-west-1 

as-put-scaling-policy --auto-scaling-group frontal --name scale-dn "--adjustment=-1" --type ChangeInCapacity --cooldown 480 --region eu-west-1 

Nota: Cada vez que se inserten políticas de escalado el sistema devolverá el arn de dichas políticas. Es necesario anotar dicho arn ya que se empleará en el siguiente paso. 

Si al ejecutar las políticas no se han anotado los ARN correspondientes se puede ejecutar el siguiente comando que nos brindará información acerca de las políticas definidas en Amazon AWS. 

as-describe-policies --region "region"

Enlazar alarmas CloudWatch a políticas de autoescalado

Finalmente es necesario generar las alarmas de tipo CloudWatch que se asociarán a las políticas de autoescalado generadas en el apartado anterior. Las alarmas emplean determinados parámetros que hay que tener en cuenta. A través del parámetro –metric-name se especificará el tipo de métrica que se desea emplear. En este caso, se empleará el uso de CPU. 

El empleo del parámetro --statistic permite especificar el tipo de operación aritmética que se desea realizar con la métrica empleada, en este caso se define que se quiere la media, es decir la media del consumo de CPU. 

A través del empleo de la métrica --unit se definirá la unidad de medida de la métrica, en este caso porcentaje. 

Period se emplea para definir que el periodo de medición es cada minuto “60 segundos”. Evalutation-periods es un número que permite especificar los periodos consecutivos para los cuales el valor de la métrica se comparará con el Threshold para determinar si se ha producido una alarma. Threshold se emplea para definir el porcentaje de CPU a partir del cual queremos que la alarma salte. 

El atributo--comparison-operator permite indicar si queremos que la alarma salte cuando el valor de la métrica sea superior, inferior o igual al threshold. Es decir, si se especifica como operador GreaterThanThreshold se indicará que se desea que la alarma salte cuando sea superior al valor especificado en el threslhold. 

A través del atributo --alarm-action se especificará el ARN de la política que se desea que se active para que salte la alarma. Finalmente, al igual que en los casos anteriores se especificará la región. 

Los siguientes ejemplos permiten definir dos alarmas que se activarán empleando las políticas descritas previamente. 

mon-put-metric-alarm --alarm-name escalar-arriba --alarm-description "Escalar en caso de que se supere el 80% de CPU" --metric-name CPUUtilization --namespace AWS/EC2 --statistic Average --period 60 --threshold 60 --comparison-operator GreaterThanThreshold --dimensions "AutoScalingGroupName=frontal" --evaluation-periods 3 --unit Percent --alarm-actions arn:aws:autoscaling:eu-west-1:493698240:scalingPolicy:afe0b1cb7-482e-99c8-223e018add:autoScalingGroupName/frontal:policyName/scale-up --region eu-west-1 

mon-put-metric-alarm --alarm-name escalar-abajo --alarm-description "Escalar hacia abajo cuando el grupo tenga un consumo menor del 20%" --metric-name CPUUtilization --namespace AWS/EC2 --statistic Average --period 60 --threshold 15 --comparison-operator LessThanThreshold --dimensions "AutoScalingGroupName=frontal" --evaluation-periods 3 --unit Percent --alarm-actions arn:aws:autoscaling:eu-west-1:490563698240:scalingPolicy:43918-4477-b5b6-b759:autoScalingGroupName/frontal:policyName/scale-dn --region eu-west-1 

Nota: En este caso se ha empleado como dimensión “AutoScalingGroupName”. De esta forma se tendrá en consideración el consumo de CPU medio del grupo de autoescalado. No sirve de nada emplear el consumo de CPU de una instancia si se tienen varias en uso. Para ello, es mejor considerar la media del consumo de la CPU de todo el grupo de escalado. 

Para mostrar las alarmas definidas en una región en concreto se empleará el siguiente comando: 

mon-describe-alarms --headers --region "región"

Escalado programado 

Pese a que las acciones programas pueden ejecutarse a los segundos de cumplirse las condiciones, es posible que las tareas se atrasen unos minutos respecto al tiempo programado de inicio. 

Se pueden especificar tareas programadas hasta un mes en el futuro. Actualmente Amazon permite 125 tareas programadas al mes por grupo de autoescalado. Esto permite escalar 4 veces al día durante un mes de 31 días para cada grupo de AutoEscalado. 

Una tarea programada tiene que tener un valor único de tiempo. Si se intenta programar una tarea que coincida con otra que ya se ha programado se producirá un error. 

Los pasos para crear este tipo de tareas serán los siguientes: 
  • Crear la configuración de arranque 
  • Crear grupo de autoescalado 
  • Crear la programación para las acciones de escalado para unas fechas en concreto “Estas deben de ser futuras” 
as-put-scheduled-update-group-action EscalarArriba --auto-scaling-group frontal --start-time "2013-11-12T08:00:00Z" --desired-capacity 2 

as-put-scheduled-update-group-action EscalarAbajo --auto-scaling-group frontal-asg --start-time "2013-11-13T08:00:00Z" --desired-capacity 1 

Si la programación que se desea generar es para realizar tareas de escalado en ocasiones recurrentes, es necesario emplear un formato de tipo cron con el atributo recurrence. En este caso se escalará la capacidad en 2 a las 00:30 todos los días de la semana. 

as-put-scheduled-update-group-action EscalarArriba --auto-scaling-group frontal --recurrence “30 0 * * *” --desired-capacity 2 

Otros aspectos 

Si se desea eliminar todos los grupos de autoescalado generados se ejecutará el siguiente comando en el que será necesario definir el nombre del grupo de auto escalado que se desea eliminar: 

as-delete-auto-scaling-group "nombre del grupo" --force-delete --region "región"

Si tras la ejecución de algún comando se produce un error, se puede añadir la siguiente sintaxis la cual puede ser de ayuda durante el proceso de depuración de errores. 

--show-xml flag 

Hay que tener especial cuidado con las métricas de consulta de la salud de las instancias que emplea el balanceador. Es posible que se tengan que ajustar las mismas en función de las características de nuestra aplicación. 
  • Unhealthy Threshold se emplea para especificar cuantas veces consecutivas se realizarán verificaciones de salud antes de que el balanceador considere que una instancia está “Unhealthy” es decir que no se puede emplear. 
  • Healthy Threshold por el contrario se emplea para definir cuantas comprobaciones se tiente que realizar para que se considere que una instancia está sana “Healthy” 
De la misma forma también será adecuado modificar los valores de timeout y health check interval para adaptarlos a las casuísticas de cada uno. Mediante el campo response timeout se especificará el tiempo que el balanceador esperará para obtener una respuesta de salud. Por otra parte, Health Check Interval se especificará para indicar al balanceador cuando tiene que realizar un ping hacia la instancia para comprobar la salud de la misma. 

Finalmente, si se quiere suspender el proceso de autoescalado se ejecutará el siguiente comando: 

as-suspend-processes "grupo de autoescalado" --region "región"

La suspensión del autoescalado puede ser de utilidad a la hora de trazar problemas que se pueden producir durante dicho proceso. Si se quiere volver a reanudar el proceso se ejecutará el siguiente comando: 

as-resume-processes "grupo de autoescalado" --region "región"