Como depurar pods em CrashLoopBackOff no Kubernetes sem surtir
1. Entendendo o CrashLoopBackOff: o que está acontecendo de verdade?
O CrashLoopBackOff é um dos estados mais temidos no Kubernetes, mas entender seu mecanismo é o primeiro passo para resolver o problema sem pânico. Quando um pod entra nesse estado, significa que o container dentro dele está falhando repetidamente — e o Kubernetes está aplicando um backoff exponencial entre as tentativas de reinicialização.
O ciclo funciona assim: o kubelet tenta iniciar o container. Se ele falha (código de saída diferente de zero), o Kubernetes reinicia. Após a primeira falha, espera 10 segundos. Depois da segunda, 20 segundos, depois 40, 80, e assim até um máximo de 300 segundos (5 minutos). Esse mecanismo existe para evitar que recursos do cluster sejam consumidos por containers quebrados que reiniciam freneticamente.
É crucial diferenciar o CrashLoopBackOff de outros estados:
- Error: o container falhou, mas ainda não entrou no ciclo de backoff
- ImagePullBackOff: o problema está na imagem do container (não encontrada, sem permissão)
- CrashLoopBackOff: a imagem foi baixada, mas o container morre ao executar
2. Primeiros socorros: comandos essenciais para não entrar em pânico
Quando você vê um pod em CrashLoopBackOff, execute estes comandos na ordem:
# 1. Obtenha o relatório completo do pod
kubectl describe pod <nome-do-pod>
# 2. Capture os logs do container que falhou
kubectl logs <nome-do-pod>
# 3. Se o container reiniciou, veja os logs da execução anterior
kubectl logs <nome-do-pod> --previous
# 4. Veja todos os eventos recentes ordenados por tempo
kubectl get events --sort-by=.metadata.creationTimestamp
O kubectl describe pod é sua ferramenta mais poderosa. Ele mostra:
- Status: a razão exata da falha (ex: CrashLoopBackOff)
- Last State: o código de saída e a mensagem do container
- Events: a sequência cronológica de eventos que levaram ao crash
Exemplo prático de saída do describe:
Containers:
meu-app:
State: Waiting (CrashLoopBackOff)
Last State: Terminated
Reason: Error
Exit Code: 1
Message: main.go:45: connection refused to database
Ready: False
Restart Count: 5
3. Investigando a causa raiz: erros comuns de aplicação
A maioria dos CrashLoopBackOff é causada por erros de inicialização da aplicação. Os culpados mais frequentes:
Dependências ausentes ou variáveis de ambiente incorretas:
# Verifique as variáveis configuradas
kubectl exec <pod> -- env
# Teste a conectividade com serviços dependentes
kubectl exec <pod> -- nc -zv banco-de-dados 5432
kubectl exec <pod> -- wget -qO- http://redis:6379/ping
Health checks mal configurados:
Problemas com liveness e readiness probes são uma fonte frequente de crashes. Exemplo de probe problemático:
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
Se sua aplicação leva 30 segundos para iniciar, esse probe vai matar o container antes dele estar pronto. A solução é aumentar o initialDelaySeconds ou usar startupProbe.
Para testar se o probe está funcionando:
# Simule a requisição do probe manualmente
kubectl exec <pod> -- curl -f http://localhost:8080/healthz
4. Problemas de recursos: quando o pod não tem o que precisa
O Kubernetes pode matar seu container se ele exceder os limites de memória. Isso aparece como OOMKilled.
# Verifique se houve OOMKilled
kubectl describe pod <pod> | grep -A 10 "Last State"
# Monitore o uso de recursos em tempo real
kubectl top pod <pod>
kubectl top node <node-do-pod>
Exemplo de saída indicando OOM:
Last State: Terminated
Reason: OOMKilled
Exit Code: 137
Para resolver, ajuste os limites no deployment:
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
Outro problema comum é falta de disco no nó. Containers que geram muitos logs podem encher /var/lib/kubelet:
# Verifique o espaço em disco dos nós
kubectl describe node <node> | grep -A 5 "Conditions"
5. Cenários avançados: segredos, volumes e permissões
Erros de montagem de volume:
Se seu pod depende de ConfigMaps ou Secrets que não existem, ele falha silenciosamente.
# Verifique se o ConfigMap existe
kubectl get configmap meu-config
# Verifique a montagem no pod
kubectl describe pod <pod> | grep -A 5 "Volumes"
Erro típico no describe:
Events:
Warning FailedMount 5s kubelet MountVolume.SetUp failed for volume "config" : configmap "meu-config" not found
Problemas de segurança:
SecurityContexts restritivos podem impedir que seu container execute comandos essenciais:
# Verifique o securityContext atual
kubectl get pod <pod> -o yaml | grep -A 10 "securityContext"
# Teste permissões dentro do container
kubectl exec <pod> -- id
kubectl exec <pod> -- ls -la /var/run/
6. Ferramentas e truques para acelerar a depuração
kubectl debug (containers efêmeros):
Adicione um container de diagnóstico ao pod sem reiniciá-lo:
kubectl debug -it <pod> --image=busybox --target=<container>
Isso permite executar comandos no mesmo namespace de rede e volume do container problemático.
stern para logs em tempo real:
# Instale stern e veja logs de múltiplos pods
stern <nome-do-deployment> --tail 10
Inspeção profunda com YAML:
# Veja todos os campos gerenciados (incluindo status interno)
kubectl get pod <pod> -o yaml --show-managed-fields
7. Prevenção: como evitar o próximo CrashLoopBackOff
Adicione startup probes:
O startupProbe protege containers que demoram para iniciar:
startupProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 10
periodSeconds: 5
failureThreshold: 30 # 30 * 5 = 150 segundos para iniciar
Configure preStop hooks para desligamento gracioso:
lifecycle:
preStop:
exec:
command: ["/bin/sh", "-c", "sleep 5 && kill -SIGTERM 1"]
Monitore proativamente com Prometheus:
Configure alertas para restart count elevado:
# Alerta no Prometheus
- alert: PodCrashLoopBackOff
expr: rate(kube_pod_container_status_restarts_total[5m]) > 0.1
for: 5m
Lembre-se: o CrashLoopBackOff não é o fim do mundo. Com essas ferramentas e uma abordagem metódica, você pode diagnosticar e resolver a maioria dos casos em minutos. Mantenha a calma, siga a ordem lógica de investigação, e em breve seu pod estará rodando feliz novamente.
Referências
- Kubernetes Official Documentation: Debugging Pods — Guia oficial do Kubernetes para depuração de pods, incluindo CrashLoopBackOff
- Kubernetes Documentation: Pod Lifecycle — Documentação detalhada sobre o ciclo de vida dos pods e estados como CrashLoopBackOff
- Kubernetes: Configure Liveness, Readiness and Startup Probes — Tutorial oficial sobre configuração correta de health checks
- Stern - Multi pod and container log tailing — Ferramenta open source para visualizar logs de múltiplos pods em tempo real
- Prometheus Alerting Rules for Kubernetes — Documentação oficial do Prometheus para criar alertas de monitoramento de pods
- Kubernetes Debug: Ephemeral Containers — Como usar containers efêmeros para depuração sem interromper o pod