
Quero manter um número constante de instâncias íntegras em execução. Mas às vezes o aplicativo apresenta bugs e sua taxa de utilização de recursos se torna tão baixa que pode ser determinada apenas pelas métricas do CloudWatch. Então, é claro, quero que essas instâncias sejam substituídas automaticamente. Mas não consigo descobrir como fazer isso. O mais próximo que consigo pensar é o escalonamento automático, mas de acordo com oPolítica de rescisão padrão, todas essas opções parecem não ter nada a ver com a métrica de uma instância específica.
Eu criei a AMI que está pronta para ser lançada. A única coisa que preciso é fazer com que ele encerre automaticamente a instância não íntegra e substitua-a por uma nova. Então, como posso fazer isso? Qualquer ajuda será apreciada.
Responder1
Verificações de integridade de instâncias personalizadas(parte inferior da página) é uma opção.
Você teria um trecho de código separado em execução na máquina (ou em qualquer máquina, na verdade) que monitora a integridade e executa a chamada da API que define a instância como não íntegra
Tenho outra ideia incompleta, mas não tenho certeza de como implementar esta. Eu fui o arquiteto de um sistema local onde o balanceador de carga foi chamado para um servidor web separado na instância; no nosso caso, era um pequeno servidor web Java personalizado, com cerca de 50 linhas de código. Ele retornou códigos de status HTTP, 200 (OK) se estiver tudo bem ou 500 (ERROR) se precisar ser encerrado. Suspeito que algo assim poderia ser integrado ao escalonamento automático, mas não faço isso há algum tempo e não tenho certeza de como você integraria isso ao escalonamento automático.
Aqui está o comando da primeira ideia acima
aws autoscaling set-instance-health --instance-id i-123abc45d --health-status Unhealthy
Responder2
Para quem se depara com esta dúvida:
Embora eu acredite que a AWS deveria ter incluído tal recurso no CloudWatch, infelizmente não consigo encontrar nenhuma informação que sugira que isso esteja disponível. Portanto, criei um script bash que consulta a API do CloudWatch para determinar as métricas de consumo de recursos e, em seguida, defina a integridade da instância de acordo, conforme sugerido porTim:
Preparação
- Se você ainda não fez isso,instale a interface de linha de comando da AWS. Também disponível via
yum
ouapt
. - Configurar AWS CLICorrendo
aws configure
, preencha sua chave de API e outras configurações.Importante: se você pretende executar o script abaixo como root como eu, você terá que executar este comando de configuração como root. Caso contrário, o script falhará.
/root/my-health-check.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
O resto
- Faça o script ser executado periodicamente
$ 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
- Desligue a instância e faça uma AMI. Uma vez feito isso, crie um novo grupo de escalonamento automático com a AMI. Agora ele deve encerrar-se e lançar um novo se a métrica não satisfizer a condição saudável. Voilá!
Referências:
[1]:Metadados da instância EC2