Eu tive um problema com um contêiner, embora ele seja construído perfeitamente, ele não inicia corretamente. A causa é uma solução que adicionei ao Dockerfile (para ter um roteamento /etc/hosts auto-configurado)
RUN mkdir -p -- /lib-override /etc-override && cp /lib/libnss_files.so.2 /lib-override
ADD hosts.template /etc-override/hosts
RUN perl -pi -e 's:/etc/hosts:/etc-override/hosts:g' /lib-override/libnss_files.so.2
ENV LD_LIBRARY_PATH /lib-override
Obviamente, há algum erro lá, mas me pergunto como posso obter mais informações sobre o que o docker está fazendo durante a execução. por exemplo, isso funciona:
$ docker run image ls
usr bin ...
Mas isso não:
$ docker run image ls -l
$
Não há nada nos logs e também não posso chamar um shell interativo. Eu posso usar strace para ver o que está acontecendo, mas eu esperava que houvesse uma maneira melhor.
Existe alguma maneira de definir o docker para ser mais detalhado?
EDIT : Graças a Andrew D. Agora eu sei o que há de errado com o código acima (deixei para que sua resposta possa ser entendida). Agora, o problema ainda é como posso depurar algo assim ou obter algumas informações sobre por que ls -l falhou por que ls não falhou.
EDIT : O -D=true pode dar mais saída, embora não no meu caso ...
O comando Docker
events
pode ajudar e o comando Docker logs pode buscar logs mesmo depois que a imagem falhou ao iniciar.Primeiro comece
docker events
em segundo plano para ver o que está acontecendo.docker run ...
Em seguida, execute seu comando com falha . Então você deve ver algo como o seguinte na tela:Então você pode obter o ID hexadecimal de inicialização da mensagem anterior ou a saída do comando de execução. Então você pode usá-lo com o comando logs:
Agora você deve ver alguma saída da inicialização da imagem com falha.
Como @alexkb sugeriu em um comentário:
docker events&
pode ser problemático se seu contêiner estiver sendo reiniciado constantemente de algo como o serviço AWS ECS. Nesse cenário, pode ser mais fácil obter o ID hexadecimal do contêiner dos logs no/var/log/ecs/ecs-agent.log.<DATE>
. Em seguida, use o dockerlogs <hex id>
.Bem, o melhor que descobri até agora é:
Basta iniciar o cliente a partir de um novo shell. O equívoco foi pensar que o cliente realmente faz alguma coisa... bem, é apenas se comunicar com o daemon, então você não quer depurar o cliente, mas o próprio daemon (normalmente).
No meu caso, o
-a
sinalizador (anexar a STDOUT/STDERR) foi suficiente:Ele mostrou o erro de inicialização (no nosso caso, um caminho de log ausente usado por
supervisord
). Suponho que a maioria dos erros de inicialização do contêiner também apareça aqui.Não posso responder à sua pergunta sobre como tornar a saída do docker mais completa, mas posso dizer que regex no local substituindo uma string em um arquivo .so é um pouco insano: a string só tem tanto espaço alocado para ela e se você alterar os deslocamentos de arquivo de outras entradas, o arquivo elf será corrompido. Tente executar objdump ou readelf em seu arquivo .so depois de executar o comando perl ( antes da alteração de LD_LIBRARY_PATH ) fora de um contêiner - dólares para donuts, agora está corrompido.
A razão pela qual funciona neste hack tristemente necessário é porque "tmp" e "etc" têm o mesmo comprimento de string, portanto, nenhum deslocamento é alterado. Considere o diretório /dkr ou similar se preferir não usar /tmp.
Se você DEVE seguir essa abordagem e seus caminhos desejados não puderem ser alterados, reconstrua a biblioteca e altere o caminho padrão para /etc/hosts na fonte. Ou melhor, ao construir seu modificado
libnss_files.so
, renomeie-o para algo comolibnss_altfiles.so
e mudensswitch.conf
para usarhosts: altfiles
ao iniciar seu contêiner docker (a menos que o docker também tenha nsswitch.conf montado em bind, então você não poderá alterá-lo). Isso permitirá que você tenha o libnss_altfiles.so em paralelo com suas bibliotecas normais no sistema base. Se o docker vincular o nsswitch.conf, deixe uma cópia de seu libnss_files.so reconstruído em seu diretório /lib-override pronto para ser carregado por LD_LIBRARY_PATH.Como um aviso, os binários suid/sgid ignoram LD_LIBRARY_PATH e LD_PRELOAD, então algumas coisas vão quebrar (leia: volte a usar o /etc/hosts padrão) se você usar essas variáveis.
Às vezes, você pode encontrar mensagens de erro úteis entrando no nó executando o daemon do docker e fazendo:
Na 'edição da comunidade Docker' no Mac OS, você pode se conectar ao docker vm fazendo: