Healthchecks em containers
1. Introdução aos Healthchecks: Por que sua aplicação precisa deles?
Healthchecks são mecanismos que permitem verificar se um container está realmente funcionando como esperado, e não apenas se o processo principal está em execução. Em ambientes de produção, um processo pode estar rodando mas a aplicação pode estar travada, sem responder a requisições, ou em estado degradado.
A diferença fundamental é entre:
- Healthcheck de processo: verifica apenas se o PID do processo principal existe (o que Docker faz por padrão)
- Healthcheck de aplicação: verifica se a aplicação responde corretamente a requisições, se consegue conectar ao banco, se a fila está acessível, etc.
Cenários onde a ausência de healthchecks causa falhas:
- Aplicação web que trava mas o processo Node.js continua rodando
- Banco que aceita conexões mas não processa queries corretamente
- Worker que consumiu toda a memória mas o processo ainda está ativo
Sem healthchecks, orquestradores como Docker Swarm e Kubernetes não conseguem tomar decisões inteligentes sobre quando reiniciar ou remover tráfego de um container.
2. Healthchecks no Docker: Comandos e Configurações
O Docker oferece a diretiva HEALTHCHECK no Dockerfile para definir verificações periódicas. A sintaxe básica:
HEALTHCHECK --interval=30s --timeout=3s --retries=3 CMD curl -f http://localhost/ || exit 1
Opções disponíveis:
- --interval: tempo entre verificações (padrão 30s)
- --timeout: tempo máximo para o comando responder (padrão 30s)
- --retries: tentativas consecutivas antes de marcar como unhealthy (padrão 3)
- --start-period: tempo de inicialização antes de começar os checks (Docker 17.05+)
Existem duas formas de declarar o comando:
- CMD-SHELL: executa via shell (interpreta variáveis de ambiente, pipes)
- CMD: execução direta sem shell
Exemplo prático em um Dockerfile de aplicação Node.js:
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
HEALTHCHECK --interval=15s --timeout=5s --start-period=10s --retries=2 \
CMD wget --no-verbose --tries=1 --spider http://localhost:3000/healthz || exit 1
CMD ["node", "server.js"]
Para inspecionar o status:
docker inspect --format='{{.State.Health.Status}}' container_name
docker ps --filter "health=unhealthy"
3. Implementando Healthchecks com Docker Compose
No Docker Compose, os healthchecks são configurados por serviço. Além disso, podemos usar depends_on com condition: service_healthy para controlar a ordem de inicialização.
Exemplo completo com PostgreSQL e API Node.js:
version: '3.8'
services:
db:
image: postgres:15
environment:
POSTGRES_USER: app
POSTGRES_PASSWORD: secret
POSTGRES_DB: myapp
healthcheck:
test: ["CMD-SHELL", "pg_isready -U app -d myapp"]
interval: 10s
timeout: 5s
retries: 5
start_period: 30s
api:
build: .
ports:
- "3000:3000"
depends_on:
db:
condition: service_healthy
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3000/healthz"]
interval: 15s
timeout: 5s
retries: 3
start_period: 10s
Dessa forma, o serviço api só será iniciado após o PostgreSQL passar no healthcheck, evitando erros de conexão no startup.
4. Healthchecks no Kubernetes: Probes Essenciais
Kubernetes oferece três tipos de probes para healthchecks:
- livenessProbe: indica se o container está vivo. Se falhar, o kubelet reinicia o container
- readinessProbe: indica se o container está pronto para receber tráfego. Se falhar, o Service remove o pod dos endpoints
- startupProbe: indica se a aplicação iniciou. Protege containers lentos de serem reiniciados por livenessProbe
Exemplo de configuração com httpGet:
apiVersion: v1
kind: Pod
metadata:
name: web-app
spec:
containers:
- name: app
image: myapp:1.0
ports:
- containerPort: 8080
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 15
periodSeconds: 20
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
Para aplicações que não expõem HTTP, podemos usar tcpSocket ou exec:
tcpSocket:
port: 3306
exec:
command:
- cat
- /tmp/healthy
5. Estratégias Avançadas de Healthchecks em Kubernetes
Parâmetros importantes para ajuste fino:
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 30 # tempo antes do primeiro check
periodSeconds: 10 # intervalo entre checks
timeoutSeconds: 5 # timeout para cada check
failureThreshold: 3 # falhas consecutivas para considerar unhealthy
successThreshold: 1 # sucessos consecutivos para considerar healthy
Endpoint HTTP customizado:
Crie endpoints específicos no seu servidor:
# Express.js
app.get('/healthz', (req, res) => {
// Verifica conexão com banco, cache, etc.
if (dbConnected && cacheConnected) {
res.status(200).send('OK');
} else {
res.status(503).send('Service Unavailable');
}
});
app.get('/ready', (req, res) => {
// Verifica se está pronto para receber tráfego
if (warmupComplete) {
res.status(200).send('Ready');
} else {
res.status(503).send('Not Ready');
}
});
Boas práticas para evitar cascatas:
- Use startupProbe para aplicações com inicialização lenta (> 30s)
- Evite healthchecks que dependem de serviços externos no livenessProbe (use apenas no readinessProbe)
- Ajuste failureThreshold para evitar reinicializações por picos momentâneos
- Implemente circuit breaker no código para evitar thundering herd
6. Monitorando e Depurando Healthchecks
Para depurar probes no Kubernetes:
kubectl describe pod pod-name
kubectl get events --field-selector involvedObject.name=pod-name
kubectl logs pod-name --previous
Eventos comuns:
- Liveness probe failed: container será reiniciado
- Readiness probe failed: tráfego será removido
- Back-off restarting failed container: muitas reinicializações
Para métricas com Prometheus, exporte o status dos healthchecks:
# Exemplo de métrica customizada
# HELP app_health_status Current health status of the application
# TYPE app_health_status gauge
app_health_status{service="api"} 1
Ferramentas de monitoramento:
- Prometheus + Grafana: dashboards com métricas de restart, probe failures
- Kube-state-metrics: expõe métricas de estado dos pods
- Custom metrics: exponha healthchecks como métricas Prometheus
7. Casos de Uso e Exemplos Práticos
Aplicação web Nginx:
apiVersion: v1
kind: Pod
metadata:
name: nginx-health
spec:
containers:
- name: nginx
image: nginx:1.25
livenessProbe:
httpGet:
path: /health
port: 80
initialDelaySeconds: 10
periodSeconds: 15
readinessProbe:
httpGet:
path: /index.html
port: 80
initialDelaySeconds: 5
periodSeconds: 5
Worker assíncrono com Redis:
livenessProbe:
exec:
command:
- redis-cli
- ping
initialDelaySeconds: 20
periodSeconds: 10
readinessProbe:
exec:
command:
- sh
- -c
- "redis-cli ping && [ $(redis-cli dbsize) -gt 0 ]"
initialDelaySeconds: 10
periodSeconds: 15
Stack completa com Kubernetes:
apiVersion: apps/v1
kind: Deployment
metadata:
name: full-stack
spec:
replicas: 3
selector:
matchLabels:
app: full-stack
template:
metadata:
labels:
app: full-stack
spec:
containers:
- name: api
image: api:1.0
ports:
- containerPort: 3000
livenessProbe:
httpGet:
path: /healthz
port: 3000
initialDelaySeconds: 15
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 3000
initialDelaySeconds: 5
periodSeconds: 5
startupProbe:
httpGet:
path: /startup
port: 3000
initialDelaySeconds: 0
periodSeconds: 5
failureThreshold: 30
8. Conclusão e Próximos Passos
Healthchecks são fundamentais para construir sistemas resilientes em containers. Eles permitem que orquestradores tomem decisões automáticas sobre reinicialização, roteamento de tráfego e escalabilidade, garantindo alta disponibilidade mesmo em cenários de falha parcial.
Pontos principais a reter:
- Sempre implemente healthchecks granulares (liveness + readiness + startup)
- Use endpoints HTTP customizados para verificar dependências internas
- Ajuste thresholds e delays conforme as características da sua aplicação
- Monitore os resultados dos healthchecks para identificar padrões de falha
Próximos passos sugeridos:
- Implemente healthchecks em todos os seus deployments
- Adicione métricas de healthcheck ao Prometheus
- Automatize testes de resiliência com ferramentas como Chaos Monkey
- Estude padrões de circuit breaker e retry com backoff
Referências
- Docker Documentation: HEALTHCHECK — Documentação oficial da diretiva HEALTHCHECK no Dockerfile com todas as opções
- Kubernetes Documentation: Configure Liveness, Readiness and Startup Probes — Guia oficial do Kubernetes sobre configuração de probes
- Docker Compose Specification: Healthcheck — Documentação oficial do healthcheck no docker-compose.yml
- Google Cloud Blog: Kubernetes best practices - Health probes — Artigo técnico da Google com melhores práticas para health probes
- Microsoft Azure: Health probes in Azure Kubernetes Service — Guia da Microsoft sobre health probes em AKS com exemplos práticos
- Kubernetes Documentation: Pod Lifecycle — Documentação oficial sobre o ciclo de vida dos pods e como probes interagem
- Prometheus Documentation: Monitoring Kubernetes — Guia de monitoramento Kubernetes com Prometheus para métricas de healthcheck