Utilizando AWS Fargate Spot para economizar até 70% em aplicações ECS
Um forma simples de configurar instâncias Fargate Spot para containers ECS, sendo pelo console ou CloudFormation
Escrevi este artigo após identificar uma necessidade na empresa em que trabalho, acredito que possa ser útil para quem utiliza o Elastic Container Service (ECS) no dia a dia e deseja diminuir custos, principalmente em ambiente de desenvolvimento e homologação, assim como foi o meu caso!
Antes de tudo, o ECS é um orquestrador de containers que permite provisionar aplicações de uma forma simples e rápida, possibilitando escalabilidade e um rápido deploy. Com ele é possível utilizar instâncias EC2, onde a infraestrutura fica por nossa conta, ou por meio do AWS Fargate onde não há necessidade por parte do cliente de gerenciar máquinas (Essa segunda opção é a que vamos utilizar).
Em 2019 foi lançado o Fargate Spot que segue o mesmo conceito das instâncias Spot para Amazon EC2, ele busca oferecer uma forma de econômica para os usuários da cloud fornecendo capacidade não utilizada pela AWS. Então quando solicitadas tarefas Spot será desta capacidade ociosa que elas sairão. Clientes que adquirem instâncias dedicadas tem preferência para tais recursos, por conta disso essa capacidade pode ser retirada a qualquer momento para que estes clientes, que optaram pela opção mais cara, possam utilizar. Você receberá uma notificação dois minutos antes da AWS precisar destes recursos de volta. Contudo, o principal motivo para utilizar Instâncias Spot é cortar custos, o preço (por hora de CPU e GB) de uma Task Spot é variável, com um desconto de 50% a 70% sobre o preço de uma tarefa sob demanda. Então, não se preocupe, definindo a estratégia certa seu sistema não ficará indisponível. Contudo, antes de utilizar em ambiente produtivo pense bem na estratégia que irá implantar, para assim evitar problemas de indisponibilidade ocasionais (📝#dica do Jean ).
Como sempre busco em meus artigos, para exemplificar de forma prática vamos subir uma aplicação Spring Boot com a infra sendo provisionada por um CloudFormation.
Então, com os conceitos básicos explicados, vamos começar criando os recursos necessários em nosso Console AWS, e caso queira pular para o template CloudFormation acesse aqui.
Existem dois tipos de configuração, uma sendo no Cluster, a qual será replicada para todos os serviços dentro dele e a feita para um serviço específico. Caso seu Cluster possua mais de um Service e você apenas queira implementar essa estratégia em um único, neste cenário não é necessário configurar o Cluster, apenas o Service.
Criando um Cluster
E é aqui que faremos a configuração para aceitar a estratégia de Fargate Spot. Na aba do serviço Elastic Container Service selecione a opção “Networking only”
Após provisionar o Cluster podemos verificar que por padrão nosso Capacity Providers já está configurado para aceitar ambos: **FARGATE ** e FARGATE_SPOT.
Para definir quais estratégias queremos utilizar devemos clicar no botão de “Update” no canto superior direito.
Nesta tela de configuração selecionamos a estratégia que nosso cluster irá utilizar, nesse caso selecionei ambos os provedores de capacidade. Defini o peso (weight) de 1 para FARGATE e 5 para FARGATE_SPOT. Com esses valores definidos para cada seis tarefas, cinco são iniciadas no FARGATE_SPOT e uma no FARGATE. Claro que você deverá escolher a estratégia que melhor se encaixa com sua necessidade, o que dependerá também de qual ambiente está realizando essas modificações. Por exemplo, o ambiente de desenvolvimento tem menos necessidade de instâncias apenas FARGATE e quanto mais Spots menor a conta no final do mês.
CloudFormation: Cluster
Para realizar configuração do Fargate Spot por meio do Cloudformation devemos adicionar ao nosso Cluster os atributos de CapacityProvider, neles definimos o peso que cada estratégia deve ter como fizemos pelo Console AWS.
EcsCluster:
Type: 'AWS::ECS::Cluster'
Properties:
ClusterName: !Sub '${EcsClusterName}'
CapacityProviders:
- FARGATE
- FARGATE_SPOT
DefaultCapacityProviderStrategy:
- CapacityProvider: FARGATE
Weight: 1
- CapacityProvider: FARGATE_SPOT
Weight: 1
Criando uma Task Definition
No lado esquerdo clique em “Task Definitions”, vamos criar uma nova task do tipo “FARGATE”, no caso é a primeira opção:
Faça as configurações básicas de Role, network e sistema operacional e configuração do container que será utilizado. Para simular criei uma imagem no Amazon Elastic Container Registry (ECR) com a aplicação SpringBoot dentro dela, pode utiliza-la ou fazer com uma imagem própria.
Nesta etapa não precisamos configurar nada relacionado a instância Fargate Spot, apenas nos certificarmos que a opção selecionada foi “Fargate”.
CloudFormation: Task Definition
No Cloudformation um ponto de atenção é adicionar o atributo “RequiresCompatibilities” sendo igual a FARGATE.
TaskDefinition:
Type: 'AWS::ECS::TaskDefinition'
Properties:
ContainerDefinitions:
- Name: !Sub '${ContainerName}'
Image: !Ref ImageDocker
PortMappings:
- ContainerPort: !Ref ListenerContainerPort
HostPort: !Ref ListenerContainerPort
Cpu: !Ref ContainerCpu
Memory: !Ref ContainerMemory
MemoryReservation: !Ref ContainerMemoryReservation
Essential: true
Family: !Sub 'family-${FeatureName}-${MicroServiceName}'
NetworkMode: awsvpc
Memory: !Ref ContainerMemoryReservation
Cpu: !Ref ContainerCpu
ExecutionRoleArn: !GetAtt TaskExecutionRole.Arn
TaskRoleArn: !Ref TaskExecutionRole
RequiresCompatibilities:
- FARGATE
Criando um Service
Agora vamos criar um serviço para gerenciar melhor as Tasks que ficarão rodando. Vá até seu Cluster entre na aba de “Services” e clique em “Create”. Podemos fazer a mesma configuração de estratégia que fizemos para o Cluster ao nível de Service.
CloudFormation: Service
A configuração aqui também é bem semelhante, iremos passar o “CapacityProvider” criando uma estratégia personalizada para este serviço.
Service:
Type: "AWS::ECS::Service"
Properties:
ServiceName: !Sub service-${FeatureName}-${MicroServiceName}
Cluster: !Ref EcsClusterName
DeploymentConfiguration:
MinimumHealthyPercent: 100
MaximumPercent: 200
DesiredCount: 2
HealthCheckGracePeriodSeconds: 40
CapacityProviderStrategy:
- CapacityProvider: FARGATE_SPOT
Weight: 5
- CapacityProvider: FARGATE
Weight: 1
PlatformVersion: '1.4.0'
LoadBalancers:
- ContainerName: !Sub ${ContainerName}
ContainerPort: !Ref ListenerContainerPort
TargetGroupArn: !Ref TargetGroup
SchedulingStrategy: REPLICA
TaskDefinition: !Ref TaskDefinition
NetworkConfiguration:
AwsvpcConfiguration:
AssignPublicIp: ENABLED
SecurityGroups:
- !Ref SecurityGroup
Subnets: !Ref PrivateSubnets
Rodando as aplicações
Com tudo configurado vamos ativar nosso service para provisionar novas instâncias e observar o comportamento delas.
Acessando as tasks para ter uma visão mais detalhada podemos verificar quais delas foram provisionadas como FARGATE_SPOT. A primeira está como FARGATE e a partir da segunda task já temos o desconto de 50% à 70% por tarefa rodando.
Os exemplos descritos neste artigo estão melhor detalhados no seguinte repositório (qualquer dúvida abra uma Issue ou comente):
Repositório GitHub
https://github.com/jjeanjacques10/springboot-ecs-fargate
Conclusão
Seguindo esse passo a passo podemos provisionar tarefas em nossos ECS’s com desconto na Cloud AWS, nos testes que realizei consegui ver a diferença de custos em média de 72%. Claro que em alguns casos essa abordagem não é a melhor, principalmente porquê estes recursos podem ser solicitados pela AWS quando necessário. Então analise o que faz mais sentido para o seu cenário atual e suas necessidades.
Agora é buscar aplicar estes conceitos em suas aplicações, sugiro como novamente que façam testes em ambiente não produtivo, que na minha opinião é o ideal, não queremos ter instâncias não dedicadas sendo utilizadas diretamente pelo cliente final.
Gostaria de agradecer a Kamila Peres por ter me apresentado esse conceito e me incentivado a ir mais a fundo nos estudos.
Caso tenha alguma crítica, sugestão ou dúvida fique a vontade para me enviar uma mensagem:
Linkedin: https://www.linkedin.com/in/jjean-jacques10/
Até a próxima!
Referências
-
AWS Fargate Spot Now Generally Available | AWS News Blog (amazon.com) https://aws.amazon.com/blogs/aws/aws-fargate-spot-now-generally-available/
-
AWS Fargate Spot vs. Fargate price comparison https://tomgregory.com/aws-fargate-spot-vs-fargate-price-comparison/
-
Fully Managed Container Solution — Amazon Elastic Container Service (Amazon ECS) — Amazon Web Serviceshttps://aws.amazon.com/ecs/
-
Provision Infrastructure As Code — AWS CloudFormation — Amazon Web Services https://aws.amazon.com/cloudformation/
-
The trouble with Fargate Spot — The Scale Factory https://www.scalefactory.com/blog/2020/07/27/the-trouble-with-fargate-spot/