Debug de container: por que ele morre, reinicia e some

CrashLoopBackOff, OOMKilled, exit 137, container que some sem log. O método de diagnóstico para container que não sobe ou não para de reiniciar.

Equipe Solvefy 8 min de leitura

Container tem uma propriedade que complica o diagnóstico: quando ele morre, leva o ambiente junto. Não há máquina para entrar e investigar, o log pode ter sumido com o processo e o sistema já subiu outra instância — que vai falhar do mesmo jeito, apagando as evidências de novo.

A boa notícia é que os modos de falha são poucos e têm assinaturas distintas. Com um método, a maior parte dos casos se resolve em minutos em vez de horas.

Comece pelo código de saída

O código com que o processo terminou é a informação mais densa disponível, e é a primeira coisa a olhar.

CódigoSignificaCausa típica
0Terminou normalmenteO comando principal não era de longa duração
1Erro genérico da aplicaçãoExceção não tratada, configuração inválida
126Não é executávelPermissão faltando no arquivo de entrada
127Comando não encontradoBinário ausente na imagem, ou caminho errado
137Morto com SIGKILLQuase sempre falta de memória
139Falha de segmentaçãoBug nativo, ou incompatibilidade de arquitetura
143Terminado com SIGTERMEncerramento solicitado; normal em deploy

Dois merecem destaque.

`127` em container que "funcionava na minha máquina" costuma ser imagem base enxuta demais: o binário que você chama não existe naquela distribuição mínima, ou o script tem interpretador que não está na imagem. É também o sintoma de final de linha do Windows num script — o sistema procura um interpretador com um caractere invisível no nome e não encontra.

`137` é o mais comum de todos e tem duas origens diferentes que precisam ser distinguidas: o limite de memória do container foi atingido, ou o host inteiro ficou sem memória e o kernel escolheu uma vítima. A diferença aparece no evento: no primeiro caso o container é marcado como morto por falta de memória; no segundo, há pressão de memória no nó e outros containers também sofrem.

O container que sai com código 0 logo após subir

Sintoma clássico de quem está começando: o container sobe e termina imediatamente, sem erro.

A causa é quase sempre conceitual: container vive enquanto o processo principal vive. Se o comando de entrada é algo que executa e termina — um script de inicialização, um comando de configuração, um servidor em modo daemon que se desassocia do terminal —, o container termina junto.

A correção é garantir que o processo principal fique em primeiro plano. Servidores web, bancos e a maioria dos serviços têm uma opção para isso. Rodar em segundo plano dentro de container é sempre errado.

O ciclo de reinício, e como quebrá-lo

Quando o container morre, ele reinicia; ao reiniciar, morre de novo; e o orquestrador aumenta o intervalo entre as tentativas. O problema é que a janela para investigar fica cada vez menor, e o log da instância anterior pode não estar mais acessível.

A sequência que funciona:

  1. Leia o log da instância anterior, não da atual. Tanto o Docker quanto o Kubernetes permitem recuperar o log do container que morreu; é onde está a mensagem de erro real.
  2. Leia os eventos do objeto, não só o log da aplicação. É ali que aparecem falha ao baixar imagem, limite de memória atingido, volume que não montou e verificação de saúde reprovada — coisas que a aplicação nunca vai registrar, porque ela nem chegou a rodar.
  3. Se o log não diz nada, suba o container substituindo o comando de entrada por um que apenas espera. O container fica de pé, você entra nele e executa o comando original na mão, vendo a saída.

Esse terceiro passo é a técnica mais útil deste artigo. Ele transforma um container que morre em segundos num ambiente onde você pode investigar com calma — verificar se o arquivo de configuração está lá, se a variável de ambiente chegou, se o serviço externo responde, se o usuário tem permissão no volume.

As causas mais frequentes, por sintoma

Reinicia sempre no mesmo ponto, com erro de conexão

Dependência não disponível: banco, fila, serviço externo, DNS interno.

Verifique se o nome resolve de dentro do container, se a porta responde e se a credencial está correta. Em Kubernetes, verifique se o serviço tem endpoints — service sem endpoint é o caso em que o nome resolve e nada responde, e o erro parece de rede quando é de seletor errado.

Uma causa estrutural: se a aplicação desiste quando a dependência não está pronta, ela vai reiniciar até a dependência subir. Isso é aceitável se houver retentativa com espera crescente; sem isso, o ciclo pode durar bastante e poluir o diagnóstico.

Morre com 137 e reinicia

Falta de memória. Três passos, nessa ordem:

  • Verifique o pico real de uso, não o médio.
  • Compare com o limite configurado.
  • Se o pico está subindo continuamente ao longo de horas, é vazamento na aplicação, e aumentar o limite só adia.

Vale lembrar de ambientes com máquina virtual gerenciada dentro do container: a aplicação pode não enxergar o limite do container e dimensionar o próprio heap pela memória do host, estourando o limite na primeira carga. Runtimes modernos respeitam o limite do container, mas versões antigas não — e esse é um caso clássico de "funciona local, morre em produção".

Sobe, fica pronto e depois é reiniciado

Verificação de saúde reprovando. Muito comum, e quase sempre a verificação está errada, não a aplicação.

  • O tempo de espera inicial é curto demais para uma aplicação que demora a inicializar, e ela é morta antes de terminar de subir.
  • O endereço verificado exige autenticação e responde erro.
  • A verificação chama um endereço que consulta o banco, e uma lentidão momentânea do banco derruba a aplicação inteira.
  • O tempo limite é menor que a latência normal sob carga.

A regra: a verificação de vivacidade deve responder "o processo está funcional", de forma barata e sem dependências externas. A verificação de prontidão é que pode checar dependências, porque o efeito dela é tirar do balanceamento, não matar.

Não sobe, erro ao obter a imagem

Tag inexistente, registry privado sem credencial configurada, ou limite de requisições do registry público atingido.

O terceiro caso é subestimado: ambientes que baixam imagens públicas a cada deploy esbarram em limite de taxa e passam a falhar de forma intermitente e aparentemente aleatória. A correção é espelhar as imagens no seu próprio registry.

Erro de permissão em arquivo ou volume

Container rodando com usuário não-root — que é o correto — e volume montado com dono diferente. A aplicação não consegue escrever.

Resolve-se acertando o dono do volume ou o contexto de usuário do pod, nunca voltando a rodar como root.

Funciona no meu computador, não no servidor

Arquitetura diferente. Imagem construída em máquina ARM rodando em servidor x86, ou o inverso. O sintoma é erro de formato do executável ou falha de segmentação imediata.

Construa a imagem para a arquitetura de destino, ou publique imagem multiplataforma.

Deixe o diagnóstico mais fácil antes de precisar

Muito do sofrimento é evitável com decisões tomadas antes:

  1. Log no fluxo padrão de saída, nunca em arquivo dentro do container. Arquivo some com o container.
  2. Log estruturado, com nível e contexto, enviado para um coletor central. Se o log só existe no container, ele não existe.
  3. Mensagem de erro clara na falha de inicialização. "Configuração inválida: falta a variável X" economiza horas comparado a uma exceção genérica.
  4. Validar a configuração na inicialização e falhar com mensagem explícita, em vez de falhar obscuramente na primeira requisição.
  5. Verificações de saúde separadas — vivacidade barata, prontidão com dependências.
  6. Encerramento gracioso, tratando o sinal de término e registrando que o encerramento foi solicitado. Isso distingue "foi morto" de "morreu".
  7. Imagem com ferramentas mínimas de diagnóstico ou, em imagem sem shell, um container de depuração efêmero preparado.
  8. Limites de memória definidos e monitorados, com o pico visível em painel.

O método, resumido

  1. Código de saída.
  2. Log da instância anterior.
  3. Eventos do objeto, não só o log da aplicação.
  4. Se nada disso revelar: subir com comando de espera e investigar de dentro.
  5. Reproduzir em homologação com a mesma imagem e a mesma configuração.

Segue-se essa ordem porque ela é decrescente em velocidade de resposta. A maioria dos casos termina no passo 2.

Erros comuns

  • Olhar só o log da instância atual e perder a mensagem real.
  • Ignorar os eventos e diagnosticar às cegas.
  • Aumentar o limite de memória sem verificar se é vazamento.
  • Verificação de vivacidade que consulta o banco e derruba a aplicação por lentidão externa.
  • Tempo de espera inicial curto demais para aplicação que demora a subir.
  • Voltar a rodar como root para resolver permissão de volume.
  • Log em arquivo dentro do container.
  • Rodar processo em segundo plano dentro do container.
  • Depender de imagem pública baixada a cada deploy, esbarrando em limite de taxa.
  • Construir imagem em arquitetura diferente da de produção.
  • Aplicação que desiste na primeira falha de dependência, sem retentativa.

Onde a Solvefy/Cloud entra

Diagnóstico de container que não sobe é um dos chamados mais frequentes que atendemos — e a solução duradoura raramente é o conserto pontual. Arrumamos a base: log centralizado e estruturado, verificações de saúde desenhadas corretamente, limites de memória medidos e monitorados, encerramento gracioso, registry espelhado e imagens construídas para a arquitetura certa. Depois disso, o próximo incidente se resolve em minutos, pela sua equipe.

Seu container reinicia e ninguém sabe por quê? Diagnóstico gratuito, sem compromisso, em solvefy.cloud.

Solvefy/Cloud — Infraestrutura que cresce com você.

Faça agora o seu diagnóstico e orçamento

Inicie com um diagnóstico gratuito da sua infraestrutura e receba uma proposta personalizada — com escopo, cronograma e valores.