Dominando kubectl logs e describe para Depuração Eficiente de Pods

Este guia fornece técnicas especializadas para dominar os comandos essenciais de depuração do Kubernetes: `kubectl logs` e `kubectl describe`. Aprenda os flags críticos, como `-f`, `--tail`, `-c` e `--previous`, necessários para solução de problemas eficiente. Detalhamos como interpretar a seção crucial de 'Eventos' no `describe` para diagnosticar problemas de agendamento e configuração, e como usar `logs` para extrair erros de tempo de execução de pods com falha ou com múltiplos contêineres, acelerando seu fluxo de trabalho de depuração.

Dominando kubectl logs e describe para Depuração Eficiente de Pods

Quando um pod do Kubernetes falha, kubectl describe e kubectl logs geralmente indicam onde procurar em seguida. describe explica o que o Kubernetes tentou fazer. logs mostra o que o contêiner escreveu antes, durante ou após a falha.

Esses comandos fornecem visões diferentes, porém complementares, do estado e histórico de um Pod do Kubernetes. kubectl describe fornece os metadados, status, variáveis de ambiente e, crucialmente, um histórico de eventos do sistema. kubectl logs fornece os fluxos de saída padrão (stdout) e erro padrão (stderr) gerados pela própria aplicação conteinerizada.

O truque é usá-los na ordem correta. Se o pod nunca foi agendado, os logs não ajudarão. Se o pod inicia e sai, os eventos podem apenas informar que ele falhou; os logs da aplicação geralmente explicam o porquê.


O Fluxo de Trabalho de Depuração de Pod em Três Etapas

Antes de mergulhar nos comandos, é útil entender o fluxo de trabalho típico de depuração:

  1. Verificar Status: Use kubectl get pods para identificar o estado de falha (Pending, CrashLoopBackOff, ImagePullBackOff, etc.).
  2. Obter Contexto e Eventos: Use kubectl describe pod para entender por que a transição de estado ocorreu (por exemplo, falha do agendador, falha da sonda de atividade, falha na montagem do volume).
  3. Inspecionar Saída da Aplicação: Use kubectl logs para examinar o comportamento em tempo de execução da aplicação (por exemplo, erros de configuração, falhas de conexão com banco de dados, rastreamentos de pilha).

1. kubectl describe: A Ferramenta de Triagem do Sistema

kubectl describe é o primeiro comando que você deve executar quando um Pod está se comportando mal. Ele não mostra a saída da aplicação, mas fornece os metadados críticos e o histórico que o próprio Kubernetes registrou sobre o Pod.

Uso Básico

O uso fundamental requer apenas o nome do Pod:

kubectl describe pod my-failing-app-xyz789

Use namespaces explicitamente quando você não estiver no namespace padrão:

kubectl describe pod my-failing-app-xyz789 -n payments

Se você conhece apenas o deployment ou o rótulo, encontre o pod primeiro:

kubectl get pods -n payments -l app=checkout -o wide

Seções Principais na Saída

Ao revisar a saída de describe, concentre-se nestas seções críticas:

A. Status e Estado

Observe o campo Status no topo e, em seguida, revise os estados individuais dos contêineres dentro do Pod. Isso informa se o contêiner está Running, Waiting ou Terminated, e fornece o motivo para esse estado.

Campo Status/Motivo Comum Significado
Status Pending O Pod está aguardando para ser agendado ou tem recursos ausentes.
Reason ContainerCreating O runtime do contêiner está baixando a imagem ou executando a configuração.
State Waiting / Reason: CrashLoopBackOff O contêiner iniciou e saiu repetidamente.
State Terminated / Exit Code O contêiner terminou a execução. Códigos de saída diferentes de zero geralmente indicam erros.

B. Configuração do Contêiner

Esta seção verifica se suas variáveis de ambiente, solicitações/limites de recursos, montagens de volume e sondas de atividade/inicialização estão definidos corretamente, correspondendo ao manifesto que você aplicou.

C. A Seção Events (Crucial)

A seção Events, localizada na parte inferior da saída, é indiscutivelmente a parte mais valiosa. Ela fornece um registro cronológico do que o plano de controle do Kubernetes fez para e pelo Pod, incluindo avisos e erros.

Erros Comuns Revelados por Events:

  • Problemas de Agendamento: Warning FailedScheduling: Indica que o agendador não conseguiu encontrar um nó adequado (por exemplo, devido a restrições de recursos, taints do nó ou regras de afinidade).
  • Falhas ao Baixar Imagem: Warning Failed: ImagePullBackOff: Indica que o nome da imagem está errado, a tag não existe ou o Kubernetes não tem credenciais para baixar de um registro privado.
  • Erros de Volume: Warning FailedAttachVolume: Indica problemas ao conectar armazenamento externo.

Dica: Se a seção Events estiver limpa e o contêiner tiver iniciado, o problema geralmente está relacionado à aplicação: uma variável de ambiente ruim, migração falha, segredo ausente, dependência inacessível ou um processo que sai imediatamente.

2. kubectl logs: Inspecionando a Saída da Aplicação

Se describe mostrar que o Pod foi agendado com sucesso e os contêineres tentaram ser executados, o próximo passo é verificar os fluxos de saída padrão usando kubectl logs.

Recuperação Básica de Logs e Streaming em Tempo Real

Para visualizar os logs atuais do contêiner principal em um Pod:

# Recuperar todos os logs até o momento atual
kubectl logs my-failing-app-xyz789

# Transmitir logs em tempo real (útil para monitorar a inicialização)
kubectl logs -f my-failing-app-xyz789

Lidando com Pods de Múltiplos Contêineres

Para pods que utilizam o padrão Sidecar ou outros designs de múltiplos contêineres, você deve especificar de qual contêiner deseja visualizar os logs usando o flag -c ou --container.

# Visualizar logs do contêiner 'sidecar-proxy' dentro do Pod
kubectl logs my-multi-container-pod -c sidecar-proxy

# Transmitir logs do contêiner da aplicação principal
kubectl logs -f my-multi-container-pod -c main-app

Depurando Contêineres Reiniciando (--previous)

Um dos cenários de depuração mais comuns é o estado CrashLoopBackOff. Quando um contêiner reinicia, kubectl logs mostra apenas a saída da tentativa atual (com falha), que geralmente contém apenas a mensagem de inicialização antes da falha.

Para visualizar os logs da instância anterior e terminada—que contém o erro real que causou a saída—use o flag --previous (-p):

# Visualizar logs da instância de contêiner anterior que falhou
kubectl logs my-crashloop-pod --previous

# Combinar com especificação de contêiner, se necessário
kubectl logs my-crashloop-pod -c worker --previous

Limitando a Saída

Para logs de alto volume, recuperar todo o histórico pode ser lento ou sobrecarregante. Use --tail para limitar a saída às últimas N linhas.

# Mostrar apenas as últimas 50 linhas dos logs do contêiner
kubectl logs my-high-traffic-app --tail=50

Você também pode adicionar carimbos de data/hora e uma janela de tempo:

kubectl logs my-high-traffic-app --tail=100 --timestamps
kubectl logs my-high-traffic-app --since=10m

Para um deployment, versões recentes do kubectl podem buscar logs através do nome da carga de trabalho:

kubectl logs deploy/checkout-api -n payments --tail=100

Quando isso for muito amplo, use um seletor de rótulo:

kubectl logs -n payments -l app=checkout --all-containers=true --tail=50

3. Combinando Técnicas para Diagnóstico Avançado

A depuração eficaz geralmente envolve alternar rapidamente entre describe e comandos específicos de logs.

Estudo de Caso: Diagnosticando Falha na Sonda de Atividade

Imagine um Pod preso em Running que ocasionalmente reinicia, causando interrupção.

Passo 1: Verifique describe para a visão do sistema.

kubectl describe pod web-server-dpl-abc

A saída mostra na seção Events:

Type     Reason      Age   From               Message
----     ------      ----  ----               -------
Warning  Unhealthy   2s    kubelet, node-a01  Liveness probe failed: HTTP GET http://10.42.0.5:8080/health failed: 503 Service Unavailable

Conclusão do Passo 1: O contêiner está em execução, mas a sonda de atividade está falhando com um erro 503, fazendo com que o Kubernetes reinicie o contêiner.

Passo 2: Verifique logs para o contexto da aplicação.

Agora, investigue por que a aplicação está retornando um status 503, que é uma falha no nível da aplicação.

kubectl logs web-server-dpl-abc --tail=200

A saída do log revela:

2023-10-26 14:01:15 ERROR Database connection failure: Timeout connecting to DB instance 192.168.1.10

Conclusão Final: O Pod está reiniciando devido a uma falha na sonda de atividade, e a sonda está falhando porque a aplicação não consegue se conectar ao banco de dados. O problema é de rede externa ou configuração do banco de dados, não do contêiner em si.

Estudo de Caso: Pod Pendente Sem Logs

Um pod em Pending geralmente não tem logs de contêiner úteis porque nenhum contêiner foi iniciado ainda.

kubectl get pod report-worker-6f9c7b9b7d-f2q8m -n analytics

Saída:

NAME                                  READY   STATUS    RESTARTS   AGE
report-worker-6f9c7b9b7d-f2q8m        0/1     Pending   0          4m

Vá direto para describe:

kubectl describe pod report-worker-6f9c7b9b7d-f2q8m -n analytics

Os eventos podem mostrar:

Warning  FailedScheduling  default-scheduler  0/6 nodes are available: 6 Insufficient memory.

Isso não é um bug da aplicação. O pod está solicitando mais memória do que o agendador pode alocar. O próximo passo é inspecionar as solicitações do deployment, a capacidade do cluster, os taints dos nós e o comportamento do autoscaler:

kubectl get deploy report-worker -n analytics -o yaml
kubectl top nodes

Estudo de Caso: ImagePullBackOff

Para ImagePullBackOff, os logs geralmente estão vazios porque a imagem do contêiner nunca foi iniciada. describe fornece o erro útil:

kubectl describe pod api-7dfb9c8b7f-bd2p9 -n staging

Mensagens de evento comuns incluem uma tag de imagem que não existe, uma falha de autenticação contra um registro privado ou um problema de DNS/rede para alcançar o registro. A correção pode ser tão simples quanto corrigir a tag:

kubectl set image deploy/api api=registry.example.com/api:2026-05-24 -n staging

Ou pode exigir a verificação do segredo de pull da imagem:

kubectl get secret regcred -n staging
kubectl describe serviceaccount default -n staging

Estudo de Caso: Pod com Múltiplos Contêineres e Aplicação Silenciosa

Sidecars podem esconder o sinal se você olhar para o contêiner errado. Primeiro, liste os nomes dos contêineres:

kubectl get pod checkout-84f7c9d7bf-px5mx -n payments \
  -o jsonpath='{.spec.containers[*].name}{"\n"}'

Em seguida, inspecione cada um deliberadamente:

kubectl logs checkout-84f7c9d7bf-px5mx -n payments -c checkout --tail=100
kubectl logs checkout-84f7c9d7bf-px5mx -n payments -c envoy --tail=100

Se os logs da aplicação estiverem silenciosos, mas os logs do proxy mostrarem falhas de conexão upstream, o pod pode estar saudável do ponto de vista do Kubernetes enquanto o tráfego ainda falha através da malha de serviço ou configuração do proxy.

Melhores Práticas e Avisos

Prática Comando Justificativa
Sempre verifique logs anteriores kubectl logs --previous Necessário para diagnosticar CrashLoopBackOff. O erro crítico está quase sempre na execução anterior.
Especifique contêineres kubectl logs -c <nome> Evita ambiguidade em Pods com múltiplos contêineres e impede a busca de logs de sidecars não intencionais.
Use rótulos para operações em massa kubectl logs -l app=frontend -f Permite transmitir logs de vários Pods correspondentes a um seletor simultaneamente (útil para atualizações contínuas).
Aviso: Rotação de Logs N/A Os nós do Kubernetes realizam rotação de logs. Logs mais antigos que a política de retenção configurada do nó (geralmente alguns dias ou baseada em tamanho) serão podados e indisponíveis via kubectl logs. Use uma solução de logging centralizada externa (por exemplo, Fluentd, Loki, Elastic Stack) para retenção de longo prazo.

Coisas que Esses Comandos Não Podem Dizer

kubectl logs mostra apenas stdout e stderr do contêiner conforme retidos pelo nó. Se a aplicação escreve em um arquivo dentro do contêiner, kubectl logs pode não mostrar nada. Isso é um problema de design de logging, não um problema do kubectl.

kubectl describe mostra o estado do objeto Kubernetes e eventos recentes, mas os eventos não são logs de auditoria permanentes. Eventos antigos expiram. Para investigações de longa duração, copie a saída relevante para as notas do incidente.

Nenhum dos comandos substitui métricas. Um pod pode estar em execução e registrando logs normalmente enquanto a limitação de CPU, pressão de memória ou latência downstream causa problemas visíveis ao usuário. Após describe e logs, os próximos comandos geralmente são:

kubectl top pod -n payments
kubectl top node
kubectl get events -n payments --sort-by=.lastTimestamp

Use describe primeiro quando o Kubernetes não conseguiu criar ou manter o pod em execução. Use logs primeiro quando o pod está em execução, mas a aplicação está se comportando mal. Alterne entre eles até conseguir separar os sintomas da plataforma dos sintomas da aplicação.

Um Fluxo de Depuração que Você Pode Reutilizar

Quando você estiver sob pressão, use o mesmo fluxo todas as vezes:

kubectl get pod <pod> -n <namespace> -o wide
kubectl describe pod <pod> -n <namespace>
kubectl logs <pod> -n <namespace> --all-containers=true --tail=100
kubectl logs <pod> -n <namespace> --all-containers=true --previous --tail=100
kubectl get events -n <namespace> --sort-by=.lastTimestamp

A ordem importa. get pod -o wide informa o nó, IP do pod, contagem de reinicializações e idade. describe informa detalhes de agendamento, imagem, volume, sonda e estado do contêiner. Os logs atuais mostram o que o contêiner em execução está fazendo agora. Os logs anteriores capturam a falha que já aconteceu. Os eventos mostram se o mesmo problema está ocorrendo em todo o namespace.

Para deployments, adicione uma verificação de rollout:

kubectl rollout status deploy/<nome> -n <namespace>
kubectl describe deploy/<nome> -n <namespace>
kubectl get rs -n <namespace> -l app=<rótulo>

Às vezes, o pod que você está depurando é de um ReplicaSet antigo durante um rollout. Se você corrigir o deployment, mas continuar lendo logs de um pod antigo que está sendo encerrado, pode perder meia hora perseguindo o problema errado.

Interpretando Reinicializações Corretamente

A coluna RESTARTS é uma pista, não um diagnóstico. Uma contagem de reinicializações de 1 após um dreno de nó pode ser inofensiva. Uma contagem de reinicializações que aumenta a cada minuto é uma falha ativa. Use describe para verificar o último estado:

Last State:     Terminated
  Reason:       Error
  Exit Code:    1
  Started:      Sun, 24 May 2026 10:14:02 +0800
  Finished:     Sun, 24 May 2026 10:14:07 +0800

Um código de saída 1 geralmente significa que o processo terminou com um erro geral da aplicação. 137 geralmente significa que o processo foi morto, comumente porque excedeu os limites de memória, embora você deva confirmar com o campo Reason e o contexto do nó/runtime do contêiner. 143 geralmente aparece quando um processo recebe SIGTERM durante a terminação normal. Não trate todo código de saída diferente de zero como o mesmo tipo de falha.

Quando houver suspeita de memória, procure por:

Reason:       OOMKilled
Exit Code:    137

Em seguida, compare o limite do contêiner com o uso real:

kubectl describe pod <pod> -n <namespace> | rg -A5 'Limits|Requests'
kubectl top pod <pod> -n <namespace>

Se o metrics-server não estiver instalado, kubectl top não funcionará. Nesse caso, use o sistema de métricas da sua plataforma ou ferramentas no nível do nó.