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: 3O 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: 2Startup probe
startupProbe:
httpGet:
path: /health/live
port: 3000
periodSeconds: 5
failureThreshold: 30O 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: 5TCP 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.jsCada 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: httpNomes 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: 30O 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:
- atrase startup artificialmente;
- bloqueie banco;
- envie SIGTERM;
- cause falha fatal;
- observe eventos do pod;
- confirme remoção do Service;
- meça requisições interrompidas.
kubectl describe
kubectl describe pod my-api-abc123Eventos 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.



