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