Introdução: o que é o EKS e por que usar
Rodar Kubernetes por conta própria exige manter etcd, API server, scheduler e controllers em alta disponibilidade, aplicar patches e fazer upgrades sem derrubar nada. O EKS tira esse peso das suas costas: o control plane é gerenciado, distribuído em várias Zonas de Disponibilidade e atualizado pela AWS.
O EKS roda Kubernetes upstream e é certificado como conforme, então manifests, Helm charts e ferramentas do ecossistema funcionam sem adaptação. A diferença está na integração com a AWS: IAM, VPC, ELB, EBS/EFS, CloudWatch, ECR e Secrets Manager.
Por que adotar o EKS:
- Alta disponibilidade do control plane, com SLA de 99,95% da AWS.
- Integração nativa com IAM, VPC, Load Balancers e observabilidade.
- Ecossistema Kubernetes: Helm, ArgoCD, Prometheus, Istio e operadores.
- Flexibilidade de compute: EC2, Fargate, Spot e Karpenter.
- Portabilidade: o mesmo manifest roda em outro Kubernetes, com menos lock-in.
O ponto de atenção é a complexidade. Para uma aplicação simples em containers, ECS pode ser suficiente. O EKS compensa quando há muitos serviços, necessidade de portabilidade, um ecossistema Kubernetes já adotado ou requisitos avançados de rede e escalabilidade.
Arquitetura do cluster: control plane e data plane
Um cluster EKS se divide em duas partes: o control plane, que a AWS gerencia, e o data plane, onde seus pods rodam.
Control plane (gerenciado pela AWS). Roda em uma VPC da própria AWS, separada da sua conta, e inclui:
- API server: ponto de entrada de todo kubectl e de todos os componentes. Pode ter endpoint público, privado ou ambos.
- etcd: banco chave-valor com o estado do cluster, replicado em três Zonas de Disponibilidade.
- Scheduler: decide em qual nó cada pod vai rodar.
- Controller manager: reconcilia o estado desejado com o estado real.
A AWS provisiona ao menos duas instâncias de API server e três de etcd em AZs diferentes e substitui automaticamente as que falharem. A comunicação com seus nós passa por ENIs (Elastic Network Interfaces) criadas nas suas subnets.
Data plane (sob sua responsabilidade). São os nós dentro da sua VPC. Em cada nó rodam:
- kubelet: agente que mantém os pods no estado desejado.
- kube-proxy: mantém as regras de rede que implementam os Services.
- containerd: o container runtime.
- VPC CNI: plugin que dá a cada pod um IP real da VPC.
Add-ons gerenciados. O EKS instala e atualiza componentes essenciais como add-ons: VPC CNI, CoreDNS, kube-proxy, EBS CSI Driver e o Pod Identity Agent.
O caminho de um deploy:
- O usuário ou o pipeline executa kubectl apply ou um deploy via Helm.
- A requisição chega ao API server, autenticada via IAM e autorizada via RBAC.
- O manifest é gravado no etcd.
- O scheduler escolhe um nó para o pod.
- O kubelet do nó puxa a imagem do ECR e inicia o container.
- O VPC CNI atribui um IP da VPC ao pod, e o kube-proxy atualiza as regras do Service.
Modelos de compute: managed node groups, Fargate e Karpenter
O EKS oferece formas diferentes de prover capacidade, e é comum combiná-las no mesmo cluster.
Managed node groups são a escolha padrão. A AWS cria as instâncias EC2 num Auto Scaling Group, usa AMIs otimizadas (Amazon Linux 2023 ou Bottlerocket) e faz upgrades com drenagem controlada dos nós. Indicado para cargas gerais, quando você quer controle sobre o tipo de instância. Em contrapartida, você dimensiona os grupos e escolhe as instâncias.
AWS Fargate roda cada pod em seu próprio ambiente isolado, sem nós para administrar. Você define quais pods usam Fargate por meio de Fargate profiles (namespace + labels). Indicado para cargas esporádicas ou com isolamento por pod. Limitações: não suporta DaemonSets nem GPU, e o custo por vCPU costuma ser maior.
Karpenter observa pods em estado Pending, escolhe a instância mais adequada ao pedido de CPU e memória e a cria em segundos. Também consolida nós subutilizados e remove os ociosos. Indicado para eficiência de custo, uso de Spot e diversidade de instâncias. Exige configurar NodePools e EC2NodeClasses.
Self-managed nodes deixam toda a operação com você: indicados só para casos especiais, como AMI customizada.
O EKS Auto Mode vai além e automatiza o gerenciamento de compute, rede e armazenamento para você.
Rede: VPC CNI, subnets, Services e Ingress
No EKS, cada pod recebe um IP real da VPC, sem overlay nem encapsulamento. Isso é feito pelo plugin Amazon VPC CNI e é o que torna a rede do EKS diferente da maioria dos clusters Kubernetes. O diagrama mostra um cluster em duas AZs (sa-east-1a e sa-east-1b), com um worker node por AZ.
Topologia da VPC
- Subnets públicas (10.0.0.0/24 e 10.0.1.0/24): abrigam o Application Load Balancer e os NAT Gateways, com saída pelo Internet Gateway.
- Subnets privadas (10.0.32.0/19 e 10.0.64.0/19): abrigam os worker nodes e os pods. Os /19 oferecem milhares de IPs, o que importa porque cada pod consome um.
- Route tables privadas: tráfego local para 10.0.0.0/16 e 0.0.0.0/0 pelo NAT Gateway da mesma AZ.
- ENIs do control plane: o EKS cria interfaces cross-account nas suas subnets para que o API server converse com o kubelet (porta 10250) e os nós com a API (443).
Como o VPC CNI funciona. Cada worker node tem uma ENI primária (eth0) e ENIs secundárias (eth1…) com IPs reservados para pods, o warm pool. Quando um pod é agendado, o plugin aws-node entrega um desses IPs, cria o par veth e adiciona uma rota /32 no namespace de rede do host. O número máximo de pods por nó depende do tipo da instância: ENIs × IPs por ENI. Quando isso limita, a prefix delegation atribui blocos /28 por ENI e aumenta bastante a densidade.
Os sete fluxos de comunicação do diagrama:
- Entrada: Internet → IGW → ALB nas subnets públicas → direto no IP do pod. Isso é possível porque o AWS Load Balancer Controller usa target-type: ip, sem passar por NodePort.
- Pod ↔ pod no mesmo nó: via veth e rotas /32 no host. O tráfego não sai do nó.
- Pod ↔ pod entre nós ou AZs: sai pela ENI e é roteado nativamente pela VPC, sem encapsulamento.
- Saída para a internet: pod → NAT Gateway → IGW, com SNAT para o Elastic IP.
- Serviços AWS: ECR, S3, STS e CloudWatch Logs via VPC Endpoints, com credenciais por IRSA ou Pod Identity.
- Control plane: o kubelet fala com a API pelas ENIs cross-account, e o kubectl de dev ou CI/CD usa o endpoint público ou privado na porta 443.
- Services e DNS: o pod acessa o ClusterIP (172.20.0.0/16), o kube-proxy faz DNAT para os IPs reais dos pods, e o CoreDNS resolve *.svc.cluster.local.
Services, Ingress e segurança de rede. Os Services são IPs virtuais: o ClusterIP não existe na VPC, só nas regras de iptables ou IPVS gravadas pelo kube-proxy. Para expor ao mundo, o AWS Load Balancer Controller transforma um Ingress em ALB (HTTP/HTTPS) e um Service do tipo LoadBalancer em NLB (TCP/UDP). A segurança de rede opera em três camadas:
- Security Groups do nó e do cluster, no nível da VPC.
- Security Groups for Pods (opcional), que aplicam SGs diretamente a pods específicos.
- Network Policies, via VPC CNI ou Calico, para regras entre pods dentro do cluster.
Segurança e identidade: IAM, IRSA, Pod Identity e RBAC
O EKS usa duas camadas de controle: o IAM decide quem é você na AWS, e o RBAC do Kubernetes decide o que você pode fazer dentro do cluster.
Acesso ao cluster. As pessoas e pipelines se autenticam com IAM e são mapeados a permissões do Kubernetes. O mecanismo moderno são as EKS Access Entries, que substituem o antigo ConfigMap aws-auth: você associa um principal IAM a uma access policy ou a grupos RBAC, tudo pela API da AWS e versionável em Terraform.
Acesso dos pods à AWS. Pods não devem usar as credenciais do nó, porque todos os pods do nó herdariam as mesmas permissões. Há dois mecanismos para dar a cada workload um papel IAM próprio:
- IRSA (IAM Roles for Service Accounts): usa o provedor OIDC do cluster e uma ServiceAccount anotada com o ARN da role. Boa escolha para clusters existentes e ampla compatibilidade.
- EKS Pod Identity: add-on com agente no nó, associação feita pela API do EKS, sem OIDC por cluster. Indicado para novos clusters, com gestão mais simples e roles reutilizáveis entre clusters.
Em ambos os casos vale o princípio do menor privilégio: uma role por aplicação, com apenas as ações que ela precisa.
Boas práticas de segurança:
- Endpoint privado do API server, ou público restrito por CIDR.
- Nós em subnets privadas, com acesso à AWS por VPC Endpoints.
- Secrets no AWS Secrets Manager, montados via Secrets Store CSI Driver, e criptografia de envelope com KMS.
- Pod Security Standards para impedir containers privilegiados.
- Network Policies para restringir comunicação entre namespaces.
- Imagens do ECR com scan habilitado.
- Audit logs do control plane enviados ao CloudWatch.
Integrando o EKS ao banco: exemplo com RDS
Bancos de dados raramente rodam dentro do cluster: o padrão é usar um serviço gerenciado como o Amazon RDS numa subnet de banco separada e deixar os pods se conectarem a ele pela rede da VPC.
- Security Groups: o SG do banco libera a porta (5432 no PostgreSQL) apenas para o SG dos nós ou, com Security Groups for Pods, apenas para o SG dos pods da aplicação.
- Endpoint estável: a aplicação usa o endpoint DNS do RDS, guardado num ConfigMap ou num Service do tipo ExternalName. Assim o nome interno fica independente do endpoint real.
- Credenciais: usuário e senha no Secrets Manager, lidos pelo pod com IRSA ou Pod Identity, sem senha em manifest.
Observabilidade, escalabilidade e custos
Observabilidade. Um cluster em produção precisa de logs, métricas e traces:
- Logs do control plane (api, audit, authenticator, controllerManager, scheduler): habilitados por cluster e enviados ao CloudWatch Logs.
- Container Insights: métricas de CPU, memória e rede por nó, pod e namespace.
- Prometheus e Grafana: o Amazon Managed Service for Prometheus e o Amazon Managed Grafana evitam operar essa stack.
- Traces: OpenTelemetry com AWS X-Ray ou outro backend compatível.
- Alarmes: pods em CrashLoopBackOff, nós NotReady e falhas de agendamento.
Escalabilidade. Há três níveis de escala, e eles trabalham juntos:
- HPA (Horizontal Pod Autoscaler): ajusta o número de réplicas por CPU, memória ou métricas customizadas.
- Karpenter ou Cluster Autoscaler: adiciona ou remove nós conforme pods pendentes ou capacidade ociosa.
- KEDA: escala por eventos externos, como o tamanho de uma fila SQS.
Defina sempre requests e limits de recursos: sem eles o scheduler decide às cegas, e o HPA por utilização não funciona.
Custos. O custo do EKS tem três componentes: a taxa fixa por hora do cluster, as instâncias EC2 ou o Fargate, e itens associados como NAT Gateway, load balancers, transferência entre AZs e volumes EBS. Para reduzir:
- Spot para cargas tolerantes a interrupção.
- Karpenter com consolidação de nós.
- Graviton para muitas cargas, com bom custo-benefício.
- VPC Endpoints para reduzir o tráfego pelo NAT Gateway.
- Right-sizing de requests, com VPA ou Goldilocks.
- Manter o cluster em versão suportada: versões antigas entram em suporte estendido, cobrado a mais.
Provisionando com Terraform e fazendo deploy com GitHub Actions
Em produção o cluster deve ser código: versionado, revisado e reproduzível.
Terraform. O caminho mais comum é o módulo terraform-aws-modules/eks/aws junto com o módulo de VPC. O exemplo é um esqueleto: confira versões e parâmetros na documentação dos módulos.
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
name = "eks-vpc"
cidr = "10.0.0.0/16"
azs = ["sa-east-1a", "sa-east-1b"]
public_subnets = ["10.0.0.0/24", "10.0.1.0/24"]
private_subnets = ["10.0.32.0/19", "10.0.64.0/19"]
enable_nat_gateway = true
}
module "eks" {
source = "terraform-aws-modules/eks/aws"
name = "meu-cluster"
vpc_id = module.vpc.vpc_id
subnet_ids = module.vpc.private_subnets
endpoint_public_access = true
eks_managed_node_groups = {
default = {
instance_types = ["m6i.large"]
min_size = 2
max_size = 6
desired_size = 2
}
}
}
Boas práticas: state remoto em S3 com lock, módulos com versão fixa e plano revisado em pull request antes do apply.
GitHub Actions. O pipeline típico faz build da imagem, publica no ECR e atualiza o Deployment. Use OIDC entre o GitHub e a AWS, sem chaves de longa duração guardadas como secret.
name: deploy
on:
push:
branches: [main]
permissions:
id-token: write
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::<conta>:role/github-deploy
aws-region: sa-east-1
- uses: aws-actions/amazon-ecr-login@v2
id: ecr
- name: Build e push
run: |
IMAGE=${{ steps.ecr.outputs.registry }}/api:${{ github.sha }}
docker build -t $IMAGE .
docker push $IMAGE
- name: Deploy
run: |
aws eks update-kubeconfig --name meu-cluster
kubectl set image deployment/api api=$IMAGE
kubectl rollout status deployment/api
A role do pipeline recebe acesso ao cluster por uma Access Entry. Em ambientes maiores, vale considerar GitOps com ArgoCD ou Flux, em que o cluster puxa o estado desejado do Git.
Boas práticas e conclusão
O EKS entrega um control plane confiável e deixa para você as decisões que definem a qualidade da operação: rede, identidade, compute e observabilidade. Checklist de produção:
- Cluster em pelo menos duas AZs, com nós em subnets privadas.
- Subnets com IPs suficientes para os pods (CIDR /19 ou maior, ou prefix delegation).
- Add-ons gerenciados (VPC CNI, CoreDNS, kube-proxy, EBS CSI) atualizados.
- Access Entries para pessoas e pipelines, e IRSA ou Pod Identity para pods, sempre com menor privilégio.
- Endpoint do API server restrito, secrets fora do etcd e criptografia com KMS.
- Requests e limits em todos os workloads, com HPA e Karpenter ou Cluster Autoscaler.
- PodDisruptionBudgets e topologySpreadConstraints para sobreviver a upgrades e falhas de AZ.
- Logs do control plane, Container Insights e alarmes configurados.
- Infraestrutura em Terraform e deploys por pipeline com OIDC ou GitOps.
- Upgrades de versão planejados, um minor por vez, testados antes em ambiente não produtivo.
O EKS não é o caminho mais simples para rodar containers, mas é um dos mais completos quando o objetivo é um ambiente padronizado, seguro e escalável. Entender a arquitetura, em especial a rede baseada em ENIs e IPs reais da VPC, é o que separa um cluster que apenas funciona de um que se opera com previsibilidade.

Top comments (0)