Kubernetes em produção é diferente

Rodar Kubernetes em desenvolvimento e rodar em produção são experiências completamente diferentes. Em dev, você se preocupa com funcionalidade. Em produção, com resiliência, segurança, observabilidade e custo.

Este guia cobre as práticas essenciais para operar Kubernetes em produção com confiança.

Namespaces e organização do cluster

Antes de qualquer workload, planeje a organização do cluster. Namespaces são o mecanismo principal para separar ambientes e times.

Uma estrutura comum em produção: um namespace por ambiente (staging, production), ou um namespace por time/produto. Cada namespace pode ter seus próprios resource quotas, network policies e service accounts.

Evite colocar tudo no namespace default. Sem separação, qualquer falha de configuração pode afetar workloads não relacionados. Resource quotas por namespace garantem que um time não consuma todos os recursos do cluster.

Para ambientes multi-tenant, combine namespaces com RBAC granular: cada time vê e gerencia apenas seus próprios recursos.

Resource Requests e Limits

Cada container deve declarar seus resource requests e limits. Requests garantem que o scheduler aloque o pod em um node com recursos suficientes. Limits previnem que um container consuma recursos excessivos.

A regra geral: requests devem refletir o consumo médio e limits devem acomodar picos razoáveis. Definir limits muito apertados causa OOMKills desnecessários. Não definir limits permite que um único container derrube outros.

Uma prática recomendada é usar Vertical Pod Autoscaler (VPA) em modo de recomendação para analisar o consumo real antes de definir valores. Muitas equipes "chutam" valores e acabam desperdiçando recursos ou sofrendo com instabilidade.

Para CPU, considere não definir limits (apenas requests) em ambientes com burst previsível. Kubernetes faz throttling de CPU, o que pode causar latência inesperada. Para memória, limits são essenciais — sem eles, um memory leak pode derrubar o node inteiro.

Health Checks que funcionam

Liveness Probes

Verificam se a aplicação está viva. Se falhar, Kubernetes reinicia o container. Use para detectar deadlocks ou estados irrecuperáveis.

Cuidado com liveness probes que verificam dependências externas (banco de dados, APIs). Se o banco cair, todos os pods serão reiniciados em cascata — piorando a situação. Liveness deve verificar apenas o estado interno da aplicação.

Readiness Probes

Verificam se a aplicação está pronta para receber tráfego. Se falhar, o pod é removido do Service. Use para aguardar warmup, conexões com banco ou carregamento de caches.

Readiness probes podem (e devem) verificar dependências externas. Se o banco está inacessível, o pod não deve receber tráfego. A diferença crucial: readiness remove do balanceamento, liveness reinicia. Confundir os dois é um erro comum e perigoso.

Startup Probes

Para aplicações com inicialização lenta (JVM, carregamento de modelos ML, migração de schema), use startup probes para evitar que liveness probes matem o container antes dele estar pronto.

Configure failureThreshold * periodSeconds para cobrir o pior caso de inicialização. Um startup probe com failureThreshold: 30 e periodSeconds: 10 dá 5 minutos para a aplicação subir.

Estratégias de deploy

Rolling Update

A estratégia padrão. Pods novos são criados gradualmente enquanto pods antigos são removidos. Configure maxSurge e maxUnavailable para controlar a velocidade e garantia de disponibilidade.

Para serviços críticos, use maxUnavailable: 0 e maxSurge: 1. Isso garante que a capacidade nunca cai abaixo do desejado durante o deploy. Combine com minReadySeconds para evitar que pods sejam considerados prontos antes de estabilizar.

Blue-Green

Mantenha dois ambientes idênticos. Tráfego é roteado para o "blue" enquanto o "green" recebe a nova versão. Após validação, troque o roteamento. Permite rollback instantâneo.

No Kubernetes, implemente blue-green com dois Deployments e um Service que alterna o selector entre eles. Ou use um Ingress Controller com traffic splitting nativo.

Canary

Direcione uma pequena porcentagem do tráfego para a nova versão. Monitore métricas e expanda gradualmente se tudo estiver saudável. Ideal para mudanças de alto risco.

Ferramentas como Argo Rollouts e Flagger automatizam canary releases com análise automática de métricas. Se a taxa de erro da nova versão ultrapassar um threshold, o rollback acontece automaticamente.

Pod Disruption Budgets

PodDisruptionBudgets (PDBs) garantem que operações de manutenção (drain de nodes, upgrades de cluster) não derrubem seu serviço. Defina o número mínimo de pods que devem estar disponíveis durante disrupções voluntárias.

Para serviços críticos com 3 réplicas, um PDB com minAvailable: 2 garante que pelo menos 2 pods estejam sempre rodando, mesmo durante upgrades de node.

Sem PDBs, um kubectl drain pode remover todos os pods de um serviço simultaneamente. Em produção, isso é inaceitável.

Auto-scaling inteligente

Horizontal Pod Autoscaler (HPA)

Escala o número de pods baseado em métricas como CPU, memória ou métricas customizadas. Configure thresholds conservadores para reagir antes do impacto no usuário.

Não confie apenas em CPU. Métricas de negócio (requests por segundo, tamanho da fila, latência p99) são indicadores melhores de quando escalar. Use o KEDA (Kubernetes Event-Driven Autoscaling) para escalar baseado em métricas externas como mensagens em filas SQS, Kafka lag ou custom Prometheus queries.

Configure stabilizationWindowSeconds para evitar thrashing (escalar e desescalar repetidamente). Um window de 5 minutos para scale-down evita que picos momentâneos causem instabilidade.

Vertical Pod Autoscaler (VPA)

Ajusta automaticamente requests e limits de CPU e memória baseado no uso histórico. Ideal para workloads com consumo variável e difícil de prever manualmente.

Use VPA em modo Off (apenas recomendação) junto com HPA para obter insights sobre o dimensionamento ideal sem alterar pods automaticamente.

Cluster Autoscaler

Escala o número de nodes no cluster quando pods não conseguem ser agendados por falta de recursos. Configure limites máximos para controlar custos.

Combine com node pools de diferentes tamanhos (spot/preemptible para workloads tolerantes a interrupção, on-demand para workloads críticos) para otimizar custo sem sacrificar disponibilidade.

Gestão de configuração e secrets

ConfigMaps para configuração

Use ConfigMaps para configurações que variam entre ambientes (URLs de serviços, feature flags, parâmetros de tunning). Monte como volumes ou injete como variáveis de ambiente.

Evite ConfigMaps gigantes. Prefira um ConfigMap por domínio de configuração. Quando um ConfigMap muda, os pods que o referenciam como volume recebem a atualização automaticamente (com delay). Pods que usam env vars precisam ser reiniciados.

Secrets com External Secrets Operator

Nunca armazene secrets diretamente em manifests Kubernetes. Use External Secrets Operator para sincronizar secrets de vaults externos (AWS Secrets Manager, Azure Key Vault, HashiCorp Vault) para Kubernetes Secrets automaticamente.

Combine com rotação automática de secrets e audit trails para conformidade com políticas de segurança.

Segurança essencial

  • RBAC: Princípio do menor privilégio para todos os service accounts. Crie roles específicos por namespace em vez de usar cluster-admin
  • Network Policies: Restrinja comunicação entre namespaces e pods. Comece com deny-all e abra apenas o necessário
  • Pod Security Standards: Evite containers rodando como root. Use securityContext com runAsNonRoot: true, readOnlyRootFilesystem: true e drop de capabilities desnecessárias
  • Secrets Management: Use External Secrets Operator, nunca plain text em manifests. Habilite encryption at rest para etcd
  • Image Scanning: Escaneie imagens por vulnerabilidades antes de deploy. Use admission controllers como Kyverno ou OPA Gatekeeper para bloquear imagens sem scan ou com vulnerabilidades críticas
  • Supply Chain Security: Assine imagens com cosign/sigstore e valide assinaturas no admission controller

Observabilidade

Sem observabilidade, você está voando cego. Os três pilares:

Logs

Centralize com Fluentd/Fluent Bit para Elasticsearch ou Loki. Padronize logs em formato JSON estruturado para facilitar busca e análise. Inclua campos como trace_id, service_name e environment em todas as mensagens.

Defina políticas de retenção por criticidade: logs de erro por 90 dias, logs de debug por 7 dias. Sem retenção, custos de armazenamento explodem.

Métricas

Prometheus + Grafana para dashboards e alertas. Use os quatro golden signals (latência, tráfego, erros, saturação) como base para alertas. ServiceMonitors do Prometheus Operator facilitam a descoberta automática de endpoints.

Crie dashboards por serviço com métricas RED (Rate, Errors, Duration) e dashboards de cluster com métricas USE (Utilization, Saturation, Errors) para nodes.

Traces

OpenTelemetry para rastrear requests entre serviços. Em arquiteturas distribuídas, traces são essenciais para entender onde o tempo é gasto e onde os erros se originam. Jaeger ou Tempo como backend para visualização.

Configure sampling inteligente: 100% para requests com erro, 10-20% para requests normais. Isso reduz o volume de dados sem perder visibilidade nos problemas.

Gestão de custos

Kubernetes pode ser caro sem otimização. Práticas para controlar custos:

  • Right-sizing: use VPA para identificar pods over-provisioned e ajuste requests/limits
  • Spot/Preemptible nodes: use para workloads tolerantes a interrupção (batch jobs, CI/CD runners)
  • Resource quotas: limite consumo por namespace para evitar surpresas
  • Idle resources: identifique e remova deployments, PVCs e load balancers órfãos
  • Kubecost ou OpenCost: ferramentas open source para visibilidade detalhada de custos por namespace, deployment e label

Comece com o básico, evolua com confiança

Não tente implementar tudo de uma vez. Comece com health checks, resource limits e rolling updates. Depois adicione auto-scaling, network policies e observabilidade avançada. Cada camada adiciona resiliência e confiança na operação.

O caminho para Kubernetes em produção maduro é incremental: estabilidade primeiro, otimização depois, automação por último. Pular etapas cria fragilidade que aparece nos piores momentos.