02 - Orquestração (Kubernetes, Docker Swarm)
video: https://youtu.be/... no frontmatter da nota.Orquestração (Kubernetes, Docker Swarm)
Orquestração de contêineres é a coordenação automatizada de implantação, escala, rede, saúde e ciclo de vida de centenas ou milhares de contêineres em um cluster de máquinas. Um orquestrador responde continuamente à pergunta de qual deve ser o estado do sistema e age para que a realidade converge para esse estado. Em produção, onde contêineres morrem, nós falham e picos de tráfego aparecem sem aviso, operar manualmente é inviável tanto pela carga operacional quanto pela taxa de erro humano. A relevância do tema é objetiva: Kubernetes tornou-se o padrão de fato do mercado, presente na estratégia de quase todos os provedores de nuvem, enquanto alternativas como Docker Swarm ocupam nichos de simplicidade. Entender o modelo de orquestração é pré-requisito para projetar deployments confiáveis, autoscaling coerente e observabilidade efetiva.
Por que orquestrar
Com três ou quatro contêineres, scripts e compose bastam; com dezenas de serviços e várias réplicas cada, a operação manual desmorona. O orquestrador automatiza decisões que antes exigiam plantão: onde colocar cada contêiner, o que fazer quando um nó morre, como distribuir tráfego entre réplicas, quando escalar e como atualizar versões sem indisponibilidade. Ele também uniformiza a exposição de serviços, oferecendo descoberta por nome e balanceamento embutidos.
O ganho mais profundo é o modelo declarativo. O time descreve o estado desejado em YAML versionado no Git, e o control plane trabalha continuamente para mantê-lo. Esse modelo separa intenção de mecanismo, habilita revisão de código em mudanças de infraestrutura, e torna o rollback tão simples quanto reaplicar um manifesto anterior. A reconciliação contínua também é autodireção: se uma réplica morre, o controlador a recria sem intervenção humana.
Control plane e nodes
A arquitetura do Kubernetes divide o cluster em um plano de controle e um conjunto de nós de trabalho. O control plane decide; os nodes executam.
| Componente | Plano | Papel |
|---|---|---|
| kube-apiserver | Control plane | Ponto de entrada da API; autentica, valida e persiste no etcd |
| etcd | Control plane | Armazenamento distribuído do estado desejado |
| Scheduler | Control plane | Escolhe o nó de cada Pod com base em recursos e afinidades |
| Controller Manager | Control plane | Roda os controladores que reconciliam o estado |
| kubelet | Node | Garante que os contêineres descritos rodem no nó |
| kube-proxy | Node | Programa as regras de rede para alcançar os Services |
Cada elemento do cluster é um objeto observado por controladores que implementam o padrão de reconciliação: observar o estado atual, comparar com o desejado e agir sobre a diferença, em laço contínuo. Essa arquitetura de controladores em cascata é o coração do Kubernetes e a razão de sua resiliência; componentes individuais podem falhar e se recuperar sem perder a convergência do sistema.
Modelo declarativo e reconciliação
O modelo declarativo é o diferencial conceitual mais importante da orquestração moderna. Em vez de descrever passos imperativos, como instalar, iniciar e configurar, o time declara o estado final desejado. O control plane mantém um laço de reconciliação por objeto: lê o estado atual, compara com o desejado e executa ações corretivas. Esse padrão tolera falhas parciais, pois uma reconciliação interrompida simplesmente retoma na próxima iteração.
A reconciliação em cascata cria camadas de controladores sobre controladores. O Deployment cria ReplicaSets; o ReplicaSet cria Pods; o EndpointSlice acompanha os Pods prontos para o Service; e o controller do Ingress programa o balanceador conforme as regras declaradas. Entender essa cadeia ajuda a diagnosticar: quando um Pod não existe, a causa geralmente está um nível acima, em um ReplicaSet bloqueado por limite de recursos ou imagem indisponível no registry.
Esse modelo também viabiliza GitOps. O repositório passa a ser a fonte da verdade, um controlador como ArgoCD compara continuamente o Git com o cluster e corrige deriva. O rollback deixa de ser um procedimento manual e passa a ser um revert de commit, com histórico auditável e revisão por pares em toda mudança de produção.
Deployments, Services e Ingress
O fluxo de objetos mais comum começa no Deployment. Um Deployment gerencia ReplicaSets, que mantêm o número de Pods desejado e executam rolling updates. O Pod é a menor unidade de agendamento e agrupa contêineres que compartilham rede e armazenamento. A estratégia de atualização controla quantos Pods novos sobem antes de derrubar os antigos, viabilizando deploys sem janela e rollbacks automáticos em caso de falha de probes.
O Service dá identidade de rede estável a um conjunto dinâmico de Pods, selecionados por rótulos. Tipos comuns variam entre ClusterIP, interno ao cluster; NodePort, que expõe a porta no nó; e LoadBalancer, que provisiona um balanceador na nuvem. O Ingress, apoiado por um controlador como ingress-nginx, roteia tráfego HTTP por host e por caminho para os Services, centralizando TLS e regras de roteamento.
# Deployment com rolling update controlado e probes de saúde
apiVersion: apps/v1
kind: Deployment
metadata:
name: pagamentos
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # sobe 1 Pod novo antes de remover um antigo
maxUnavailable: 0 # nunca derruba réplicas durante o rollout
selector:
matchLabels:
app: pagamentos
template:
metadata:
labels:
app: pagamentos
spec:
containers:
- name: pagamentos
image: registry.acme.io/pagamentos:1.7.0
ports:
- containerPort: 8080
resources:
requests: # reserva usada pelo scheduler e pelo HPA
cpu: "250m"
memory: "512Mi"
limits: # teto aplicado por cgroups
cpu: "500m"
memory: "512Mi"
readinessProbe: # só recebe tráfego quando responde
httpGet: { path: /healthz, port: 8080 }
initialDelaySeconds: 5
livenessProbe: # reinicia o contêiner em travamento
httpGet: { path: /livez, port: 8080 }
periodSeconds: 10
Abaixo, o Service seleciona os Pods pelo rótulo e o Ingress roteia o domínio público para o serviço.
# Service expõe o conjunto de Pods com identidade estável no cluster
apiVersion: v1
kind: Service
metadata:
name: pagamentos
spec:
type: ClusterIP
selector:
app: pagamentos # seleciona os Pods do Deployment acima
ports:
- port: 80 # porta do Service dentro do cluster
targetPort: 8080 # porta do contêiner
---
# Ingress roteia tráfego HTTP externo por host e caminho
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: pagamentos-ingress
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
ingressClassName: nginx
tls:
- hosts: ["pagamentos.acme.io"]
secretName: pagamentos-tls
rules:
- host: pagamentos.acme.io
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: pagamentos
port: { number: 80 }
Kubernetes como padrão de mercado
O Kubernetes venceu a disputa de orquestradores por combinação de modelo expressivo, ecossistema enorme e governança aberta. Todo grande provedor oferece serviço gerenciado: EKS na AWS, GKE no Google Cloud e AKS no Azure. Extensões como HPA para autoscaling, operators para bancos de dados, service mesh para mTLS e GitOps com ArgoCD formam um ecossistema que resolve boa parte das necessidades de plataforma. O custo disso é complexidade real: há curva de aprendizado, taxonomia extensa e a tentação de adicionar abstrações antes de precisar delas.
Em 2025, o Kubernetes 1.33 trouxe para beta, habilitado por padrão, o redimensionamento in-place de recursos de Pod via subresource resize. Isso permite ajustar CPU e memória de contêineres em execução sem recriar o Pod, com condições observáveis como PodResizePending e PodResizeInProgress. Para cargas com perfis variáveis, o recurso reduz disrupturas que antes exigiam reinício do processo a cada mudança de limites.
Docker Swarm e alternativas de simplicidade
O Docker Swarm (SwarmKit) é o orquestrador embutido no ecossistema Docker. Um docker swarm init transforma o host em manager, e docker service create publica um serviço replicado com balanceamento, roteamento por DNS e atualização rolante. Seu ponto forte é a curva de aprendizado mínima para quem já usa Docker, com o mesmo CLI e sem nova taxonomia. O ponto fraco é o ecossistema: pouca integração com operadores, mesh e ferramentas de plataforma, e adoção declinante no mercado.
Outras alternativas ocupam espaços específicos. Nomad da HashiCorp roda workloads heterogêneos com configuração enxuta; ECS da AWS oferece orquestração simplificada, profundamente integrada à nuvem; e serviços serverless como Fargate e Lambda eliminam a gestão de nós por completo. A escolha correta combina maturidade do time, integrações necessárias e custo total de operação.
Comparação entre orquestradores
| Critério | Kubernetes | Docker Swarm | AWS ECS | Nomad |
|---|---|---|---|---|
| Curva de aprendizado | Alta | Baixa | Média | Média |
| Modelo de definição | Manifestos YAML | Compose e CLI | Task definitions JSON | Jobs HCL |
| Ecossistema | Enorme, padrão do mercado | Reduzido | Integrado à AWS | Moderado |
| Escala comprovada | Milhares de nós | Clusters menores | Bilhões de tasks por semana na AWS | Grande, com nós mistos |
| Autoscaling nativo | HPA, VPA, Cluster Autoscaler | Básico | Service Auto Scaling | Integração externa |
| Serviço gerenciado | EKS, GKE, AKS | Não | ECS, EKS | HCP Nomad |
| Melhor perfil | Plataformas e escala | Laboratório e edge | Times focados em produto na AWS | Times com híbrido e legado |
Erros comuns e boas práticas
A maioria dos incidentes em clusters vem de configurações ausentes ou mal ajustadas, não de falhas da plataforma. Os pontos abaixo concentram os problemas recorrentes.
- Omitir
requestselimits, deixando o scheduler cego e permitindo contenção silenciosa de CPU e OOM kills imprevisíveis. - Faltarem probes de liveness e readiness, o que envia tráfego para Pods quebrados e impede rollouts seguros.
- Usar tags mutáveis de imagem sem
imagePullPolicyadequada, gerando Pods com versões diferentes no mesmo cluster. - Tratar o estado do cluster manualmente com
kubectl applyad hoc; GitOps com repositório como fonte da verdade evita deriva de configuração. - Expor o apiserver publicamente sem restrição e negligenciar RBAC, network policies e contextos de namespace.
- Acumular objetos vítimas de tentativa e erro; auditoria periódica de recursos órfãos reduz custo e confusão.
Boas práticas recomendadas: declare tudo em manifests versionados; defina limites coerentes com o perfil real de carga; utilize namespaces como fronteiras de equipe e de ambiente; mantenha a menor superfície possível de objetos customizados até haver necessidade comprovada; e trate o cluster como produto, com dono, métricas de saúde e processo de evolução controlado. O orquestrador amplifica tanto a disciplina quanto a bagunça do time; investir em convenções desde o início é mais barato que remediar depois.