
Quiero mantener una cantidad constante de instancias en buen estado en ejecución. Pero a veces la aplicación tendrá errores y su tasa de utilización de recursos será tan baja que podría determinarse únicamente mediante las métricas de CloudWatch. Luego, por supuesto, quiero que esas instancias se reemplacen automáticamente. Pero no puedo encontrar cómo hacer esto. Lo más parecido que se me ocurre es el escalado automático, pero según elPolítica de terminación predeterminada, todas esas opciones parecen no tener nada que ver con la métrica de una instancia en particular.
He creado una AMI que está lista para su lanzamiento. Lo único que necesito es hacer que finalice automáticamente la instancia en mal estado y reemplazarla por una nueva. Entonces, ¿cómo puedo hacer esto? Cualquier ayuda se agradece.
Respuesta1
Comprobaciones de estado de instancias personalizadas(parte inferior de la página) es una opción.
Tendría un fragmento de código separado ejecutándose en la máquina (o en cualquier máquina realmente) que monitorea el estado y ejecuta la llamada a la API que establece la instancia en mal estado.
Tengo otra idea a medio formar, pero no estoy muy seguro de cómo implementarla. Fui el arquitecto de un sistema local donde teníamos el balanceador de carga llamado en un servidor web separado en la instancia; en nuestro caso era un pequeño servidor web Java personalizado, alrededor de 50 líneas de código. Devolvió códigos de estado HTTP, 200 (OK) si todo va bien o 500 (ERROR) si es necesario finalizarlo. Sospecho que algo así podría integrarse con el escalado automático, pero hace tiempo que no hago esto y no estoy seguro de cómo se integraría con el escalado automático.
Aquí está el comando de la primera idea anterior.
aws autoscaling set-instance-health --instance-id i-123abc45d --health-status Unhealthy
Respuesta2
Para cualquiera que se encuentre con esta pregunta:
Aunque creo que AWS debería haber incluido dicha característica en CloudWatch, lamentablemente no puedo encontrar ninguna información que sugiera que esté disponible. Así que creé un script bash que consulta la API de CloudWatch para determinar las métricas de consumo de recursos y luego configuré el estado de la instancia en consecuencia, como lo sugiereTimo:
Preparación
- Si no lo has hecho,instalar la interfaz de línea de comandos de AWS. También disponible a través de
yum
oapt
. - Configurar la CLI de AWSejecutando
aws configure
, complete su clave API y otras configuraciones.Importante: si tiene la intención de ejecutar el siguiente script como root como lo hago yo, deberá ejecutar este comando de configuración como root. De lo contrario, el script fallará.
/root/mi-chequeo-de-salud.sh
#!/bin/bash
# retrieve metrics starting from 20 minutes ago (3 data points)
# Note: Sometimes CloudWatch failed to gather data for a specific period,
# then the number of data points returned could be less than what we expect.
# Also, when the instance just started, there will be no data point.
start_time=$(date -d "-20 minutes" -u +"%Y-%m-%dT%H:%M:%SZ")
# retrieve metrics up to now
end_time=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
# get current instance ID [1]
instance_id=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
# get current region [2]
# This is only needed if you have multiple regions to manage, otherwise just
# specify a region via `aws configure`.
region=$(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone | sed 's/\(.*\)[a-z]/\1/')
# save data retrieved for processing [3]
# Here I used an example of retrieving "NetworkIn" of "AWS/EC2" namespace,
# with metric resolution set to 300 (5 minutes).
# For a list of available metrics, run `aws cloudwatch list-metrics`
datapoints=$(aws cloudwatch get-metric-statistics --namespace AWS/EC2 --metric-name NetworkIn --dimensions Name=InstanceId,Value=$instance_id --statistics Average --start-time $start_time --end-time $end_time --period 300 --region $region --output text | awk '{ print $2 }')
# custom handler
# In this example, the health check will fail if all data points fall below
# my threshold. The health check will not fail if there is no data.
healthy=0
hasdata=0
THRESHOLD=300000
for i in $datapoints; do
# In this case, the metric(NetworkIn) is not integer.
if (( $(echo "$i $THRESHOLD" | awk '{print ($1 > $2)}') )); then
healthy=1
fi
hasdata=1
done
if [ $hasdata -eq 1 ]; then
if [ $healthy -eq 0 ]; then
aws autoscaling set-instance-health --instance-id $instance_id --health-status Unhealthy --region $region
fi
fi
El resto
- Haga que el script se ejecute periódicamente
$ chmod +x /root/my-health-check.sh
# run the script at 0, 5, 10, 15 ... 55 of every hour
$ echo "*/5 * * * * root /root/my-health-check.sh 2>&1 | /usr/bin/logger -t ec2_health_check" >> /etc/crontab
- Apague la instancia y cree una AMI. Una vez hecho esto, cree un nuevo grupo de escalado automático con la AMI. Ahora debería finalizarse y lanzar uno nuevo si la métrica no satisface la condición de buen estado. ¡Voilá!
Referencias:
[1]:Metadatos de la instancia EC2