Pular para o conteúdo
NyverraNyverra
Artigos
⌘K
InícioArtigosSite institucional
🇧🇷

Nyverra

Canal editorial

Artigos sobre tecnologia, operações e parceiros — infraestrutura, monitoramento e ambientes críticos.

Explorar

  • Início
  • Artigos
  • Categorias
  • Tags
  • Autores
  • Sobre
  • Contato
  • RSS
  • Site institucional

© 2026 Nyverra. Todos os direitos reservados.

blog.nyverra.com

  1. Início
  2. Kubernetes
  3. Curso Kubernetes 23 — Deploy sem downtime: probes, rolling update e HPA
Kubernetes
#Kubernetes#Probes#K8S#Curso Kubernetes

Curso Kubernetes 23 — Deploy sem downtime: probes, rolling update e HPA

Wedson LopesWedson Lopes
30 de outubro de 20265 min de leitura

"Deploy sem downtime" não é uma flag. É o conjunto de decisões que impede o tráfego de chegar num pod que ainda não está pronto — e impede o cluster de matar um pod que está apenas lento.

Errar readiness é a causa número um de erro 502 em deploy.

Selo do curso: testado em Kubernetes 1.35 com aplicação Java e Nginx.

Os três probes

Probe Pergunta Se falhar
startup já iniciou? reinicia (enquanto isso, liveness não roda)
readiness pode receber tráfego? sai do Service (sem reiniciar)
liveness está vivo? reinicia o container
startupProbe:
  httpGet: { path: /actuator/health/liveness, port: 8080 }
  failureThreshold: 30
  periodSeconds: 5
readinessProbe:
  httpGet: { path: /actuator/health/readiness, port: 8080 }
  initialDelaySeconds: 5
  periodSeconds: 5
  failureThreshold: 3
livenessProbe:
  httpGet: { path: /actuator/health/liveness, port: 8080 }
  periodSeconds: 10
  failureThreshold: 3

Regras práticas:

  • Readiness deve checar dependências que impedem servir (banco, cache crítico). Não coloque dependência não crítica: se o Redis cai, o pod sai do ar sem necessidade.
  • Liveness deve checar só o processo. Liveness checando banco = restart em cascata quando o banco oscila.
  • Startup existe para aplicações lentas; sem ele, a liveness mata o app antes de subir.
  • initialDelaySeconds alto é sintoma de liveness mal configurada, não solução.

Rolling update

strategy:
  type: RollingUpdate
  rollingUpdate:
    maxSurge: 1
    maxUnavailable: 0
  • maxUnavailable: 0 garante que a capacidade não cai durante o rollout.
  • maxSurge: 1 cria um pod novo antes de derrubar um antigo.
  • minReadySeconds evita considerar pronto cedo demais:
minReadySeconds: 10
  • progressDeadlineSeconds evita rollout travado para sempre:
progressDeadlineSeconds: 600

Acompanhe:

kubectl -n portal rollout status deploy/portal-backend --timeout=5m
kubectl -n portal rollout history deploy/portal-backend
kubectl -n portal rollout undo deploy/portal-backend

terminationGracePeriodSeconds e o 502 clássico

Quando um pod é removido:

  1. Ele é marcado como Terminating e sai do Endpoints.
  2. O kubelet envia SIGTERM.
  3. O processo tem terminationGracePeriodSeconds para encerrar.

Se a aplicação para de aceitar conexão no SIGTERM imediatamente, conexões em voo caem. O padrão correto:

  • Receber SIGTERM.
  • Continuar servindo por alguns segundos (o Endpoints já propagou).
  • Fechar o servidor e as conexões de banco.
  • Sair com 0.
lifecycle:
  preStop:
    exec:
      command: ["sh", "-c", "sleep 5"]
terminationGracePeriodSeconds: 30

O sleep 5 não é elegância: é o tempo para o Service parar de mandar tráfego.

PDB no deploy

PDB protege durante drain, não durante rollout. Ainda assim, sem PDB um drain pode levar todas as réplicas de uma vez.

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: portal-backend
spec:
  minAvailable: 1
  selector:
    matchLabels:
      app: portal-backend

minAvailable: 50% também funciona e escala melhor.

HPA sem derrubar o serviço

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: portal-backend
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: portal-backend
  minReplicas: 2
  maxReplicas: 6
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70
  behavior:
    scaleDown:
      stabilizationWindowSeconds: 300
      policies:
        - type: Percent
          value: 50
          periodSeconds: 60

Lições:

  • minReplicas: 2 para não ficar sem capacidade em nó único.
  • scaleDown com janela de estabilização evita flapping.
  • Métrica de CPU só funciona com requests definidos. Sem requests, o HPA não calcula.
  • HPA não resolve gargalo de banco. Escalar app que segura conexão demais derruba o Postgres — aconteceu no nosso ambiente com 10 pods.

Deploy com quota apertada

Se o cluster não tem folga para maxSurge: 1, o pod novo fica Pending e o rollout trava. Duas saídas:

  • maxSurge: 0 + maxUnavailable: 1 (aceita queda momentânea de capacidade).
  • Garantir folga de recursos (capítulo 26).

Rollout travado com Pending é falta de capacidade, não bug do Kubernetes.

Laboratório

  1. Suba um Deployment com 3 réplicas, readiness e maxUnavailable: 0.
  2. Faça um loop de requisições e um deploy com imagem nova:
while true; do curl -s -o /dev/null -w "%{http_code}\n" http://portal.local/api/health; sleep 0.2; done
  1. Observe o rollout: nenhum 5xx deve aparecer.
  2. Remova a readinessProbe e repita: os erros aparecem.
  3. Teste kubectl drain com e sem PDB.
  4. Gere carga e veja o HPA escalar:
kubectl -n portal get hpa -w
  1. Force um pod em CrashLoopBackOff e observe liveness/startup.

Erros comuns

Sintoma Causa
502 durante deploy readiness ausente ou preStop faltando
Reinício em cascata liveness checando dependência externa
Rollout travado Pending falta de CPU/memória para o surge
HPA não escala sem requests ou metrics-server fora
HPA escala e derruba o banco conexões demais / pool mal dimensionado
Pod nunca Ready readiness com path/timeout errado
Drain bloqueado PDB com minAvailable igual ao total

Checklist

  • [ ] Startup, readiness e liveness com propósitos distintos.
  • [ ] Readiness só com dependências críticas.
  • [ ] maxUnavailable: 0 e maxSurge compatível com a capacidade.
  • [ ] minReadySeconds e progressDeadlineSeconds definidos.
  • [ ] preStop + terminationGracePeriodSeconds.
  • [ ] SIGTERM tratado na aplicação.
  • [ ] PDB por serviço crítico.
  • [ ] HPA com requests e behavior de scaleDown.
  • [ ] Teste de deploy com loop de requisições.

Glossário

  • readiness: pronto para tráfego.
  • liveness: processo saudável.
  • startup: inicialização longa.
  • maxSurge: pods extras durante o rollout.
  • maxUnavailable: pods que podem faltar.
  • PDB: orçamento de disrupturas.
  • HPA: autoscaling horizontal.

Próximo

Deploy sem downtime resolvido. Agora como a imagem chega até aqui: pipeline, imagem imutável, tag por digest e SBOM no próximo capítulo.

Próximo: Curso Kubernetes 24 — CI/CD: imagens imutáveis e SBOM

Compartilhar

Continuar a ler

Leia também

  • Kubernetes de Verdade — do zero ao cluster em produção
    Kubernetes

    Kubernetes de Verdade — do zero ao cluster em produção

    Uma trilha prática para entender, montar e operar um cluster Kubernetes — do primeiro pod ao failover do Postgres.

    30 de outubro de 20264 min de leitura
  • Curso Kubernetes 28 — DR e capstone: provar que o cluster volta
    Kubernetes

    Curso Kubernetes 28 — DR e capstone: provar que o cluster volta

    RPO, RTO e drills reais: cenários de desastre, runbook, restore medido e o capstone que fecha o curso com um cluster que se recupera.

    30 de outubro de 20265 min de leitura
  • Curso Kubernetes 27 — SLO/SLI, on-call e postmortem blameless
    Kubernetes

    Curso Kubernetes 27 — SLO/SLI, on-call e postmortem blameless

    O que prometer, como medir e o que fazer quando o erro estoura: SLI, SLO, error budget, alertas que acordam alguém e postmortem sem caça às bruxas.

    30 de outubro de 20264 min de leitura

Comentários

Ainda sem comentários

Seja o primeiro a compartilhar sua opinião sobre este artigo.

Deixe um comentário

Newsletter

Receba novos artigos

Inscreva-se para receber publicações do blog Nyverra no seu e-mail. Enviaremos um link de confirmação.

​