Home > Blog > Desenvolvimento Web
Desenvolvimento Web
JavaScript
Programação

Probes Kubernetes em Node.js

Atualizado em: 22 de agosto de 2026

Rack de servidores processando fluxos de dados no Node.js

As probes Kubernetes em Node.js permitem que o cluster descubra quando um container iniciou, está pronto para receber tráfego ou entrou em um estado que exige reinício. Elas são divididas em startup, readiness e liveness probes, cada uma com uma responsabilidade diferente.

Uma probe mal configurada pode reiniciar uma aplicação saudável durante uma pausa de garbage collection, enviar tráfego antes da conexão com o banco ou manter um pod quebrado no balanceamento. A aplicação precisa expor endpoints simples, rápidos e com semântica clara, enquanto o manifesto deve usar prazos compatíveis com o comportamento real.

Neste guia, você aprenderá a criar endpoints, configurar HTTP, TCP e exec probes, definir thresholds, evitar dependências excessivas, integrar com graceful shutdown, observar falhas e testar deploys.

O que são probes?

Probes são verificações executadas pelo kubelet no container. A documentação oficial de liveness, readiness e startup probes descreve os tipos e parâmetros. A documentação prática de configuração de probes apresenta exemplos de manifestos.

Para a lógica de endpoints, consulte Health Checks no Node.js. Para encerramento durante remoção do pod, veja Graceful Shutdown no Node.js.

Liveness probe

Liveness responde à pergunta: o processo está em um estado do qual não consegue se recuperar sozinho? Quando falha além do limite, o kubelet reinicia o container.

Ela não deve falhar apenas porque o banco está temporariamente indisponível. Reiniciar todos os pods durante uma falha do banco pode piorar o incidente.

Readiness probe

Readiness responde: este pod pode receber tráfego agora? Quando falha, o pod é removido dos endpoints do Service, mas o container continua executando.

Ela pode considerar inicialização, shutdown, dependências críticas e capacidade de atender requisições.

Startup probe

Startup protege aplicações que demoram para iniciar. Enquanto ela não passa, liveness e readiness não interferem. Depois do sucesso, a startup probe deixa de ser executada.

Endpoints separados

app.get('/health/live', (req, res) => {
  res.status(200).json({ status: 'ok' });
});

app.get('/health/ready', async (req, res) => {
  const ready = applicationState.isReady();

  res.status(ready ? 200 : 503).json({
    status: ready ? 'ready' : 'not_ready'
  });
});

Separar endpoints evita misturar semânticas.

Liveness simples

Um endpoint de liveness deve verificar o mínimo necessário: o event loop ainda consegue processar a requisição e o processo não marcou um estado fatal.

let fatalState = false;

app.get('/health/live', (req, res) => {
  if (fatalState) {
    return res.status(500).end();
  }

  res.status(200).end();
});

Não consulte banco na liveness

Se o PostgreSQL cai, reiniciar o Node.js não recupera o banco. A liveness deve detectar deadlock lógico, corrupção interna ou estado fatal, não toda dependência externa.

Readiness com estado local

const state = {
  started: false,
  shuttingDown: false,
  databaseReady: false
};

function isReady() {
  return state.started
    && !state.shuttingDown
    && state.databaseReady;
}

Atualize o estado por verificações com timeout e eventos da aplicação.

Verificação direta do banco

async function checkDatabase() {
  const controller = new AbortController();
  const timer = setTimeout(() => controller.abort(), 500);

  try {
    await database.query('SELECT 1', {
      signal: controller.signal
    });
    return true;
  } finally {
    clearTimeout(timer);
  }
}

Nem todos os drivers aceitam AbortSignal. Use timeout compatível com a biblioteca.

Cuidado com carga das probes

Cem pods com probe a cada segundo geram cem consultas por segundo. Use cache curto ou estado de conexão quando uma consulta constante não for necessária.

HTTP probe

livenessProbe:
  httpGet:
    path: /health/live
    port: 3000
  periodSeconds: 10
  timeoutSeconds: 2
  failureThreshold: 3

O kubelet considera códigos entre 200 e 399 como sucesso.

Readiness no manifesto

readinessProbe:
  httpGet:
    path: /health/ready
    port: 3000
  initialDelaySeconds: 2
  periodSeconds: 5
  timeoutSeconds: 1
  successThreshold: 1
  failureThreshold: 2

Startup probe

startupProbe:
  httpGet:
    path: /health/live
    port: 3000
  periodSeconds: 5
  failureThreshold: 30

O exemplo permite até cerca de 150 segundos para inicialização.

initialDelaySeconds

Atraso fixo pode esconder variação de startup. Startup probe é mais expressiva: libera assim que a aplicação está pronta e tolera inicializações lentas dentro do limite.

periodSeconds

Define a frequência. Valores pequenos detectam rápido, mas aumentam carga e sensibilidade a oscilações.

timeoutSeconds

O endpoint precisa responder muito abaixo desse limite. Um timeout de um segundo com handler que consulta várias dependências remotas gera falsos negativos.

failureThreshold

Quantidade de falhas consecutivas antes da ação. Liveness deve tolerar pausas curtas; readiness pode reagir mais rápido para retirar tráfego.

successThreshold

Readiness pode exigir sucessos consecutivos para evitar que o pod entre e saia do balanceamento durante instabilidade. Para liveness e startup, há restrições específicas; consulte a versão do Kubernetes.

TCP probe

readinessProbe:
  tcpSocket:
    port: 3000
  periodSeconds: 5

TCP verifica se a porta aceita conexão, mas não garante que a aplicação consegue responder corretamente.

Exec probe

livenessProbe:
  exec:
    command:
      - node
      - scripts/check-health.js

Cada execução cria processo e consome recursos. Prefira HTTP quando já existe servidor.

gRPC probe

Kubernetes moderno pode verificar serviços gRPC nativamente quando configurado. Para serviços gRPC, implemente o protocolo de health checking compatível.

Consulte gRPC com Node.js.

Porta nomeada

ports:
  - name: http
    containerPort: 3000

readinessProbe:
  httpGet:
    path: /health/ready
    port: http

Nomes reduzem duplicação de números no manifesto.

Host e headers

Probes HTTP podem configurar headers, mas não devem depender de autenticação externa. Restrinja o endpoint pela rede do cluster e não exponha detalhes sensíveis.

Resposta mínima

Retorne um corpo pequeno:

{ "status": "ready" }

Não inclua versão de dependências, URLs internas, credenciais ou stack traces.

Readiness durante startup

O servidor pode começar a escutar antes de terminar migrations, aquecimento de cache ou carregamento de configuração. Mantenha readiness falsa até concluir etapas obrigatórias.

await loadConfiguration();
await connectDatabase();
await warmCriticalCache();
state.started = true;

Migrations

Não execute migrations concorrentes em todos os pods sem lock. Prefira job separado ou etapa controlada de deploy.

Readiness durante shutdown

process.on('SIGTERM', async () => {
  state.shuttingDown = true;
  await delay(5000);
  server.close();
});

Marcar not ready permite que endpoints sejam atualizados antes de fechar conexões.

terminationGracePeriodSeconds

terminationGracePeriodSeconds: 30

O prazo precisa ser maior que drenagem do balanceador e fechamento da aplicação.

preStop

lifecycle:
  preStop:
    exec:
      command: ["sh", "-c", "sleep 5"]

Um pequeno atraso pode ajudar propagação, mas não substitui readiness e SIGTERM corretos. O tempo do hook faz parte do período de terminação.

RollingUpdate

Readiness impede que pods novos recebam tráfego antes de estarem prontos. Configure maxUnavailable e maxSurge conforme capacidade.

PodDisruptionBudget

PDB limita interrupções voluntárias, mas não impede reinícios por liveness. Uma probe ruim pode derrubar muitos pods independentemente do orçamento.

Event loop bloqueado

Se uma função bloqueia o event loop, a probe HTTP não responde e liveness pode reiniciar. Isso pode ser útil para travamento permanente, mas um pico curto não deve causar loop.

Veja Event Loop no Node.js.

Monitorando atraso

Use monitorEventLoopDelay() e métricas para identificar saturação antes de depender de restart. Reiniciar não corrige trabalho síncrono constante.

Garbage collection

Pausas de GC podem atrasar uma probe. Configure thresholds que tolerem pausas observadas no p99 e investigue memória.

Dependência externa instável

Readiness que muda a cada falha curta pode causar flapping. Use janela, sucessos consecutivos e cache de estado.

Circuit breaker

Uma dependência opcional com circuit breaker aberto não precisa tornar todo o pod indisponível. Diferencie recursos críticos e degradáveis.

Consulte Circuit Breaker no Node.js.

Aplicação degradada

Uma API pode continuar pronta para rotas básicas mesmo sem serviço de recomendações. Readiness não deve exigir tudo se há fallback válido.

Dockerfile

O HEALTHCHECK do Docker não é usado automaticamente como probe do Kubernetes. Defina probes no manifesto.

Veja Docker Multi-stage para Node.js.

Service mesh

Sidecars podem alterar startup e shutdown. O proxy precisa estar pronto e drenar conexões. Teste a sequência específica do mesh.

Ingress

Readiness controla endpoints do Service; o Ingress envia tráfego apenas aos endpoints prontos. Pode haver atraso de propagação, por isso o shutdown deve tolerar requisições residuais.

Observabilidade

Monitore:

  • falhas por tipo de probe;
  • reinícios do container;
  • tempo até readiness;
  • duração dos handlers;
  • motivo de not ready;
  • event loop delay;
  • OOMKilled;
  • tempo de terminação.

Logs

Não registre cada probe bem-sucedida em produção. Isso gera ruído. Registre mudanças de estado e falhas com rate limit.

Métricas com OpenTelemetry

Use métricas e traces para investigar dependências lentas. Consulte OpenTelemetry no Node.js.

Testando endpoints

Teste estados:

  • antes da inicialização;
  • pronto;
  • banco indisponível;
  • dependência opcional indisponível;
  • shutdown;
  • estado fatal;
  • handler com timeout.

Testando manifesto

Em ambiente de homologação:

  1. atrase startup artificialmente;
  2. bloqueie banco;
  3. envie SIGTERM;
  4. cause falha fatal;
  5. observe eventos do pod;
  6. confirme remoção do Service;
  7. meça requisições interrompidas.

kubectl describe

kubectl describe pod my-api-abc123

Eventos mostram falha, timeout e reinício.

kubectl logs –previous

kubectl logs my-api-abc123 --previous

Útil para analisar o container antes do último reinício.

Erros comuns

  • Banco na liveness: todos os pods reiniciam durante falha externa.
  • Mesma probe para tudo: semânticas se misturam.
  • Timeout curto demais: pausas normais viram falha.
  • Endpoint pesado: a probe cria carga.
  • Sem startup probe: aplicação lenta reinicia em loop.
  • Readiness ativa no shutdown: requisições chegam durante fechamento.
  • Corpo com detalhes: informações internas são expostas.

Boas práticas

  • Separe live, ready e startup.
  • Mantenha liveness mínima.
  • Use readiness para dependências críticas.
  • Defina timeouts curtos e realistas.
  • Evite consultas a cada segundo.
  • Marque not ready no shutdown.
  • Alinhe termination grace.
  • Não registre sucessos repetitivos.
  • Teste falhas em homologação.
  • Monitore reinícios e flapping.

Conclusão

As probes Kubernetes em Node.js ajudam o cluster a distinguir inicialização, capacidade de receber tráfego e falha irreversível. Startup protege o boot, readiness controla o balanceamento e liveness decide reinícios.

O desenho correto evita usar dependências externas na liveness, mantém endpoints rápidos e integra readiness ao shutdown. Com thresholds baseados em métricas e testes de falha, probes melhoram disponibilidade sem transformar oscilações temporárias em loops de reinício.

Os 10 Melhores Cursos de Programação de 2026

Descubra os melhores cursos de programação. Aprenda a escolher o curso ideal para iniciar ou avançar na carreira de desenvolvedor

POSTS RELACIONADOS

Ver todos

Seta para a direita