Este artigo foca na conteinerização de aplicações no desenvolvimento de software moderno com orquestração de contêineres de provedores de nuvem, que permite implantar e escalar nossas aplicações dinamicamente para qualquer demanda de carga, com repetibilidade, capacidade de manutenção, observabilidade e alta disponibilidade, tudo isso com bom custo-benefício e suporte a recuperação de desastres.
Em resumo
- Contêineres permitem empacotar aplicações de forma independente de plataforma como imagens leves, com alta performance para iniciar e replicar.
- Motores de orquestração de contêineres permitem gerenciar dinamicamente cargas de trabalho distribuídas grandes e imprevisíveis.
- AWS EKS é um dos orquestradores de contêineres mais populares e oferece integração nativa com diversos serviços da AWS.
- Use Helm charts para implantar aplicações complexas de machine learning ou data science em Kubernetes com um único comando.
Por que contêineres?
É quase impossível responder ao “por quê” sem antes explicar o “o quê”. Então vamos começar pelos problemas que os contêineres resolvem e pelo que é um contêiner, para então responder ao “por quê”.
No modelo antigo de engenharia de software, desenvolvedores escreviam código em suas máquinas locais, que era então implantado em um ambiente de testes e, depois, lançado em produção. O problema estava nas inconsistências entre ambientes e nas dependências e bibliotecas rodando em diferentes servidores.
Assim, uma aplicação que “funciona na minha máquina” (clássica frase de dev) pode depender de bibliotecas de runtime em versões muito diferentes das do ambiente de destino, o que pode levar a comportamentos inesperados após a implantação.
Os contêineres resolvem isso ao abstrair totalmente a camada da aplicação, empacotando código compilado, bibliotecas, dependências e runtimes em uma “imagem”.
Uma imagem de contêiner pode ser usada como um template que um engine de contêiner, como o Docker, implanta e executa rapidamente como uma instância de contêiner com comportamento previsível em qualquer ambiente.
Os próximos problemas que os contêineres resolvem são escalabilidade, manutenção e custo. Historicamente, ambientes de produção eram compostos por muitos recursos de hardware (caros) isolados e protegidos para uso exclusivo por aplicações de alto volume ou críticas ao negócio. Esses ambientes dispendiosos exigiam gestão, manutenção e patches constantes.
A quantidade de hardware alocada para tais aplicações precisava ser a máxima para suportar o pico de carga, mas as aplicações nem sempre têm padrões de uso consistentes e previsíveis. Isso faz com que muito hardware fique ocioso em horários de menor demanda.
A solução é a orquestração de contêineres.
Como uma imagem de contêiner é independente de plataforma, recursos de computação em contêiner podem ser escalados para cima e para baixo sob demanda em qualquer servidor disponível com capacidade para rodar um engine de contêiner, deixando a manutenção do sistema operacional subjacente desacoplada da aplicação.
Isso impacta diretamente o custo-benefício: ao gerenciar e orquestrar os contêineres para atender dinamicamente à demanda atual, maximizamos o uso do hardware.
Essa é uma visão “panorâmica”. Vamos aprofundar nas próximas seções, mas antes, vale falar de alguns usos práticos de contêineres.
Contêineres para data science e machine learning
Aplicações de data science e machine learning tendem a ser altamente intensivas em computação
com padrões de uso por vezes imprevisíveis e lidam com grandes volumes de dados.
Essas aplicações frequentemente se beneficiam de paralelização para dividir e conquistar problemas antes de persistir resultados em um data store. É uma grande simplificação, mas já dá para ver como esse tipo de aplicação combina perfeitamente com contêineres e orquestração de contêineres!
Com isso em mente, vamos ao “como”. No fim do artigo, retomaremos a conexão com aplicações de data science e machine learning ao falar de Helm e de como podemos executar aplicações complexas, implantadas como contêineres em um motor de orquestração, com esforço e configuração mínimos.
Existem vários engines de contêiner no mercado, mas, para este artigo, usaremos o mais popular, o Docker. Você pode se familiarizar com a plataforma no nosso tutorial Introduction to Docker.
Máquinas virtuais (VMs) vs contêineres
Máquinas virtuais abstraem o hardware físico, transformando um servidor em muitos via um hypervisor, permitindo que várias VMs compartilhem o mesmo host. Cada VM tem seu próprio sistema operacional (SO) convidado.
Contêineres são uma abstração na camada da aplicação. Um servidor com um engine de contêiner instalado pode executar vários contêineres ao mesmo tempo, todos compartilhando o SO subjacente. Você pode saber mais sobre contêineres no nosso tutorial de conteinerização.
A grande diferença é que contêineres usam o SO do host e não vêm empacotados com um próprio, ao contrário de VMs. Isso os torna muito mais leves e rápidos de replicar, executar e destruir, mantendo os benefícios de isolamento de segurança e tolerância a falhas entre contêineres (se um contêiner cair, não impacta os demais).
Também significa melhor uso de recursos: mais contêineres podem rodar em um único engine Docker do que VMs poderiam rodar em um hypervisor, considerando especificações de hardware comparáveis.
Imagem Docker vs contêiner
Uma Docker Image empacota configuração, código, dependências e o runtime. Imagens funcionam como um template a partir do qual instâncias de contêiner são replicadas e executadas no Docker. Um contêiner pode rodar em qualquer plataforma que suporte Docker.
Orquestração de contêineres
Agora que entendemos contêineres, precisamos de uma forma de gerenciá-los. Existem vários orquestradores, mas, neste artigo, vamos focar em Kubernetes rodando na nuvem AWS via o Elastic Kubernetes Service (EKS).
Algumas das tarefas principais gerenciadas pelo EKS são:
- Implantação
- Escalonamento
- Balanceamento de carga
- Monitoramento
- Descoberta de serviços
- Auto-recuperação
Serviços da AWS
Antes de explicar o EKS, precisamos entender alguns serviços da AWS que o sustentam.
CloudWatch
Serviço de monitoramento e observabilidade que coleta dados em forma de logs, métricas e eventos.
VPC
Uma Virtual Private Cloud é uma rede logicamente isolada, gerenciada e protegida com segurança por conta da AWS.
ELB
Um elastic load balancer é um componente de rede altamente disponível que pode distribuir tráfego entre múltiplos alvos.
IAM
O Identity and Access Management oferece controle de acesso de forma granular para contas AWS.
ECR
O Elastic Container Registry é um registro de imagens Docker totalmente gerenciado.
EC2
Elastic Cloud Compute (abreviado por causa dos 2 C’s) é um serviço central da AWS que sustenta vários outros. Ele permite alugar servidores virtuais nos quais os clientes executam suas aplicações.
Region
Uma localização física onde data centers são agrupados, por exemplo, EU-WEST-1 (Irlanda) e EU-WEST-2 (Londres).
AZ
Uma availability zone é um ou mais data centers distintos com energia, rede e conectividade redundantes. Uma região consiste em várias AZs.
Route53
Um serviço de DNS altamente disponível.
WAF
Web Application Firewall que ajuda a proteger aplicações contra exploits e bots comuns que podem afetar disponibilidade, comprometer segurança ou consumir recursos em excesso.
Fundamentos de Kubernetes
Kubernetes às vezes é referido como K8s. Isso porque há oito letras entre K e S em Kubernetes.
Cluster
O EKS provisiona um cluster K8s gerenciado. Este é o componente de nível mais alto e atua como um contêiner para todos os serviços, nós e pods.
O EKS tem integração nativa com CloudWatch, Elastic Container Repository (ECR), IAM, API Gateway, Elastic Load Balancer (ELB), CodePipeline, Secrets Manager e mais.
No exemplo mais básico, podemos armazenar imagens de contêiner no ECR e ter nossa aplicação gerenciada e executada pelo EKS, implantado em uma VPC distribuída por múltiplas zonas de disponibilidade, com todos os logs de sistema e aplicação publicados no CloudWatch.

Master/control plane
O nó master é o coração do K8s e ajuda a gerenciar, monitorar, agendar e planejar os nós. Ele tem vários subcomponentes.
ETCD
Um armazenamento chave-valor que persiste todos os dados críticos do cluster.
Kube scheduler
O scheduler implanta contêineres nos nós.
Kube controller manager
Garante o estado adequado dos componentes do cluster, assegurando que a carga de trabalho desejada corresponda à carga de trabalho real.
API
Todas as interações externas ao cluster passam pela API do K8s.

Nós (worker nodes)
Um worker node do EKS é uma instância EC2. Cada nó tem o docker runtime instalado para rodar contêineres, o agente Kubelet que lida com toda a comunicação com o master, e o K-proxy, que permite a comunicação entre nós.
Para que os nós integrem com o CloudWatch, a role do IAM do nó precisa incluir a política CloudWatchLogsFullAccess.

Pod
Um pod é a menor unidade implantável. Ele executa um único contêiner de aplicação, além de quaisquer sidecars necessários. Cada pod é efêmero e terá um endereço IP único.

Deployments e replica sets

Um replica set gerencia um conjunto de pods por label e garante que sempre exista um conjunto estável de pods em execução para uma carga de trabalho específica. Se um pod cair, cabe ao replica set restaurá-lo.
Deployments gerenciam replica sets. Se um replica set cair, o deployment deve restaurá-lo. Deployments podem ser configurados como rolling, ramped, re-create ou canary (detalhes dos tipos de deployment estão fora do escopo deste artigo).
Services
Para fins deste artigo, podemos considerar um service como um mapeamento direto para um Application Load Balancer (ALB) da AWS, que é um tipo de ELB. Há mais detalhes além disso, mas é importante entender alguns benefícios que o ALB traz:
- Associação a um nome DNS
- Health checks
- Alta disponibilidade entre múltiplas AZs
- WAF
- Access logs
A função principal de um service é distribuir tráfego entre nós/pods.
Escalonamento de contêineres
ASG e EC2
Um componente central do EC2 é o Auto Scaling Group (ASG). Esse componente da AWS mantém um conjunto de instâncias EC2 em uma carga desejada, distribuídas em múltiplas AZs dentro de uma região, geralmente atrás de um load balancer.
Métricas do CloudWatch fornecem os gatilhos para escalar para dentro ou para fora.
Esse tipo de escalonamento é chamado de horizontal, pois a frota de servidores de aplicação pode se expandir e contrair “horizontalmente” para atender à demanda de tráfego. Um exemplo de política de escalonamento seria manter todas as instâncias abaixo de 50% de uso de CPU. Nessa configuração, o ASG costuma manter um número igual de instâncias EC2 por AZ, mas há outras opções fora do escopo deste artigo.
HPA
É muito importante diferenciar o escalonamento no nível do EC2 e no nível do pod. O Horizontal Pod Autoscaler é responsável por escalar pods dentro de cada nó. O HPA usa métricas do K8s coletadas via o Metrics Server (que precisa ser instalado no cluster e não faz parte do deployment padrão do EKS) e escala pods com base nas métricas do nó. Um exemplo de política seria mirar 50% de uso de vCPU.
EKS Cluster autoscaler
O autoscaling de cluster requer a instalação do EKS cluster autoscaler (open source), responsável por escalar o serviço K8s em conjunto com um ASG da AWS, que por sua vez gerencia a escalada das instâncias físicas provisionadas para o cluster.
Quando um nó atinge capacidade máxima conforme a política do HPA, o cluster autoscaler cria outra instância EC2 e a adiciona ao ASG.
A visão completa

Políticas de escalonamento são altamente flexíveis, personalizáveis e configuráveis, mas normalmente têm um período de resfriamento antes de reduzir escala, para evitar ajustes desnecessários devido a picos e vales irregulares de tráfego.
Importante: se um pod exceder seu limite de vCPU, o Kubernetes vai limitar (throttle) a aplicação naquele pod; se exceder os limites de memória, o Kubernetes reiniciará o contêiner.
Otimização de custos
Exemplo de como restringir pods dentro de instâncias usando o tipo m5.large:
2 * vCPU = 2000m (millicore)
8 GiB de memória
Restrições de recursos por pod:
- Quantidade reservada de vCPU, ex.: 500m
- Limite de vCPU, ex.: 1000m
- Quantidade reservada de memória, ex.: 256Mi
- Limite de memória, ex.: 512Mi
Observabilidade
EKS Resource View
Mostra todos os recursos em execução no cluster.

CloudWatch Container Insights
- Monitora
- Alarmes
- Aciona funções Lambda
- Dashboards e métricas pré-criados
- Instalação com um clique

Helm
Helm é um gerenciador de pacotes para Kubernetes que automatiza o empacotamento, a configuração e a implantação de aplicações. Helm charts permitem criar, compartilhar, versionar e publicar aplicações complexas em Kubernetes.
Alguns exemplos interessantes de charts no domínio de data science e machine learning:
- Ml-workspace
- Mlflow
- Tensorflow
- Hive
- Spark
Essas aplicações K8s podem ser implantadas no seu cluster EKS via Helm com um único comando!
Conclusão
Neste guia completo, exploramos os fundamentos da orquestração de contêineres com o AWS Elastic Kubernetes Service (EKS). Desde os conceitos básicos de contêineres e seus usos reais em data science e machine learning, até um mergulho nas particularidades dos serviços da AWS e componentes do Kubernetes, cobrimos bastante terreno. O universo da orquestração de contêineres é complexo, mas extremamente recompensador, oferecendo escalabilidade, manutenção facilitada e ótimo custo-benefício.
Seja você desenvolvedor, cientista de dados ou profissional de TI, dominar a orquestração de contêineres certamente será uma habilidade valiosa no seu repertório. À medida que as empresas migram para soluções em nuvem e adotam arquiteturas de microsserviços, a demanda por profissionais com essa expertise só tende a crescer.
Pronto para colocar o conhecimento em prática? A DataCamp oferece diversos cursos para aprofundar seu entendimento de Kubernetes, Docker e computação em nuvem. Do nível iniciante ao avançado, você encontra aulas interativas, desafios reais e tutoriais conduzidos por especialistas para fortalecer suas habilidades.
- Introduction to Docker
- Machine Learning, Pipelines, Deployment and MLOps Tutorial
- AWS Cloud Concepts Course
Links úteis
- Kubectl cheat sheet com os comandos mais usados
- Tutorial de HPA que explica o recurso e orienta um app com escalonamento gerenciado
- Tutorial de cluster autoscaler para configurar e rodar um app simples com escalonamento de cluster
- Helm charts
- Calculadora de preços da AWS
Sou engenheiro de software de pilha completa e arquiteto de soluções, apaixonado por aprendizado e dados!

