Olá a todos, o artigo de hoje, como você viu no título, trata da configuração do Elastic Beanstalk, especificamente do balanceador da AWS e do número de instâncias do TagretGroup, dependendo das condições de que precisamos.
Introdução ao Elastic Beanstalk
O Elastic Beanstalk é uma plataforma de serviços de alto nível que automatiza a implantação de aplicativos na nuvem. O EB configura automaticamente a infraestrutura e os recursos necessários, como instâncias EC2 (servidores virtuais), grupos de segurança, objetos S3 para armazenar arquivos de versão de aplicativos, bancos de dados RDS, balanceadores de carga Elastic Load Balancing e muito mais para garantir que o aplicativo seja lançado com o mínimo de tempo e esforço por parte do desenvolvedor.
Os principais componentes do Elastic Beanstalk são:
Aplicativo é a unidade básica. Primeiro, você cria um aplicativo que serve como um contêiner para suas versões e ambientes.
Um ambiente é uma versão do aplicativo que é implantada em uma infraestrutura específica do AWS e serve a uma função específica, como um ambiente de teste ou de produção.
Recursos com os quais estaremos lidando:
EC2 (Elastic Compute Cloud) são servidores virtuais que podem ser locados na nuvem da AWS para executar aplicativos.
Grupo de destino (Target Group) é um conceito usado na AWS para gerenciar o tráfego no nível do aplicativo. Os Target Groups permitem que você especifique exatamente para onde o tráfego que chega ao Load Balancer deve ser direcionado. Cada Target Group está associado a um recurso específico, como EC2 ou funções lambda.
Os Auto Scaling Groups permitem que o número de instâncias do EC2 seja dimensionado automaticamente em resposta a alterações na carga ou em outros fatores.
Após uma breve descrição do EB, vamos ao tópico do artigo.
- Introdução e desafios
O aplicativo estava sendo executado em uma única instância c5.xlarge e todas as verificações de status do AWS mostravam “Sucesso”, a máquina estava no estado “Em execução”, mas o aplicativo não estava respondendo. Depois de examinar os logs do servidor, percebemos que o problema era devido à reinicialização do IIS (esse é um procedimento padrão - geralmente acontece a cada 29 horas, mas você também pode definir o período individualmente).
Elastic Beanstalk
O Elastic Beanstalk não foi projetado para funcionar com uma única máquina, então, criamos esse estágio:
2x c5.large (c5.large é exatamente 2 vezes mais barato que c5.xlarge);
Se em 5 minutos a carga da CPU for >80%, adicionaremos outra instância.
Se a carga da CPU for <40% em 5 minutos, removeremos uma instância.
Resources:
AWSEBAutoScalingGroup:
Type: "AWS::AutoScaling::AutoScalingGroup"
Properties:
MinSize: 2
MaxSize: 3
AWSEBCloudwatchAlarmHigh:
Type: "AWS::CloudWatch::Alarm"
Properties:
EvaluationPeriods: 1
MetricName: CPUUtilization
Namespace: AWS/EC2
Period: 300
Statistic: Average
ComparisonOperator: GreaterThanOrEqualToThreshold
Threshold: 80
Unit: Percent
AlarmActions:
- Ref: "AWSEBAutoScalingScaleUpPolicy"
AWSEBCloudwatchAlarmLow:
Type: "AWS::CloudWatch::Alarm"
Properties:
EvaluationPeriods: 1
MetricName: CPUUtilization
Namespace: AWS/EC2
Period: 300
Statistic: Average
ComparisonOperator: LessThanOrEqualToThreshold
Threshold: 40
Unit: Percent
AlarmActions:
- Ref: "AWSEBAutoScalingScaleDownPolicy"
AWSEBAutoScalingScaleUpPolicy:
Type: "AWS::AutoScaling::ScalingPolicy"
Properties:
AdjustmentType: ChangeInCapacity
AutoScalingGroupName:
Ref: "AWSEBAutoScalingGroup"
Cooldown: 360
ScalingAdjustment: 1
O principal problema com essa solução é que ela não funcionará como pretendido - por padrão, o AWS presume que, se todas as verificações de status em uma instância forem aprovadas, não há problema em permitir o tráfego nela. O que é errado para o nosso estudo de caso - precisamos adicionar nosso próprio HealthCheck.
Vamos começar!
Configuração
Para a configuração, precisamos de um ID de ambiente e dessas guias na barra lateral do EC2, procure por Target Groups e posteriormente vamos em Auto Scaling Groups:
Vamos seguir a ordem:
- Target Groups Aqui precisamos definir a configuração do Target Group de acordo com nossos critérios de tempo de atividade. Em nosso caso, consideramos suficiente detectar uma máquina não saudável após 1 minuto: 3 solicitações a cada 15 segundos + timeouts (5 segundos) = 1 minuto.
Além disso, na guia Attributes (Atributos), há um parâmetro importante: Deregistration delay (Atraso no cancelamento do registro). Quando um registro deixa de responder no /hc, ele deve ser substituído no tempo especificado nesse parâmetro:
Resources:
AWSEBV2LoadBalancerTargetGroup:
Type: "AWS::ElasticLoadBalancingV2::TargetGroup"
Properties:
HealthCheckIntervalSeconds: 15
HealthCheckPath: /hc
HealthCheckProtocol: HTTP
HealthCheckTimeoutSeconds: 5
HealthyThresholdCount: 5
UnhealthyThresholdCount: 3
TargetGroupAttributes:
- Key: deregistration_delay.timeout_seconds
Value: '20'
- Auto Scaling Groups Habilitar HealthChecks e definir período de carência.
O parâmetro mais importante, sem o qual todas as configurações acima não serão aplicadas:
Para adicionar verificações de ELB, clique em “Ativar verificações de integridade do Elastic Load Balancing” e defina o período de carência da verificação de integridade.
O período de carência da verificação de integridade é um período de espera durante o qual o AWS não tomará nenhuma medida para remover ou substituir instâncias recém-criadas (ou em execução) em um Auto Scaling Group, mesmo que elas falhem na verificação de integridade.
Imagine que, acabamos de lançar um novo aplicativo e ele precisa de algum tempo para ser totalmente inicializado e começar a funcionar corretamente. Se o AWS começasse a verificar imediatamente se ele está funcionando como deveria e ainda visse que algo está errado (porque o aplicativo ainda precisa de tempo para concluir todos os processos de inicialização), o AWS o rotularia como não saudável e tentaria reiniciá-lo ou criar uma nova instância.
Selecionar o período de carência ideal não é a tarefa mais trivial. Simplesmente medimos quanto tempo leva, em média, para que um novo aplicativo comece a enviar 200 solicitações. Para o nosso exemplo, esse tempo é inferior a 8 minutos, portanto, definimos o valor de 500 segundos com uma reserva.
Atenção: Você deve levar em conta diferentes fatores que podem aumentar o tempo de carregamento do aplicativo: migrações de banco de dados ou atualizações importantes do aplicativo. Nesses casos, você precisará aumentar o período de carência manualmente.
Resources:
AWSEBAutoScalingGroup:
Type: "AWS::AutoScaling::AutoScalingGroup"
Properties:
HealthCheckType: ELB
HealthCheckGracePeriod: 500
Política de manutenção de instâncias
Também precisamos permitir que o ELB exceda o limite de N instâncias caso uma delas não esteja respondendo, mas ainda não tenha sido removida do EB. Ou seja, queremos permitir que uma instância seja adicionada preventivamente enquanto a que não está funcionando estiver sendo excluída. Como resultado, teremos 1 instância a mais do que o permitido no EB de uma só vez. Para fazer isso, selecione o parâmetro “Instance maintenance policy” (Política de manutenção de instância) no Auto Scaling Group e defina-o como Launch before terminating (Iniciar antes de encerrar):
Experimento (hora da verdade)
Vamos verificar como o balanceador se comportará se pararmos propositalmente nosso aplicativo em uma instância (por exemplo, com o comando Stop-Service)
Vamos alterar ligeiramente nossa configuração para o experimento - o número máximo de instâncias será 2, mantendo os mesmos parâmetros de CPU:
Vemos instâncias de trabalho:
Provisionei uma EC2 Windows Server para teste:
Em um minuto (de acordo com nossas configurações de TargetGroups), veremos a seguinte imagem:
A instância falhou logicamente no HealthCheck e agora todo o tráfego vai para a única instância restante.
E, ao mesmo tempo (como lembramos, em 20 segundos), uma nova instância é iniciada, mesmo antes de a anterior ser excluída! Como resultado, vemos 3 instâncias (é claro, sempre haverá apenas 2 instâncias funcionando):
Depois de excluir uma instância que não está funcionando, nosso sistema retorna a um estado estável de duas máquinas funcionando.
Isso também pode ser visto nos Eventos de Envio do EB:
Espero que você tenha aprendido mais sobre a configuração do Elastic Beanstalk no AWS.