Como posso depurar uma inicialização do contêiner do docker?

Eu tive um problema com um contêiner, mesmo que ele construa perfeitamente, ele não inicia corretamente. A causa é uma solução alternativa que adicionei ao Dockerfile (por ter um roteamento /etc/hosts auto-configurado)

RUN mkdir -p -- /lib-override /etc-override && cp /lib/libnss_files.so.2 /lib-overrideADD hosts.template /etc-override/hostsRUN perl -pi -e 's:/etc/hosts:/etc-override/hosts:g' /lib-override/libnss_files.so.2ENV 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 lsusr 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. Posso usar o strace para ver o que está acontecendo, mas esperava que houvesse uma maneira melhor.

Existe alguma maneira de definir docker para ser mais detalhado?

EDITAR: Graças a Andrew D. Agora 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 entender por que ls-l falhou por que ls não.

EDITAR: The-D = true pode dar mais saída, embora não no meu caso...

Encaixe events o comando pode ajudar e Docker logs o comando pode buscar logs mesmo depois que a imagem falhou ao iniciar.

Primeiro começo docker events no fundo para ver o que está acontecendo.

docker events&

Em seguida, execute sua falha docker run ... comando. Então você deve ver algo como o seguinte na tela:

2015-12-22T15:13:05.503402713+02:00 xxxxxxxacd8ca86df9eac5fd5466884c0b42a06293ccff0b5101b5987f5da07d: (from xxx/xxx:latest) die

Em seguida, você pode obter o ID Hex de inicialização da mensagem anterior ou a saída do comando Executar. Então você pode usá-lo com o comando logs:

docker logs <copy the instance id from docker events messages on screen>

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 o contêiner estiver sendo constantemente reiniciado 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 /var/log/ecs/ecs-agent.log.<DATE>. Em seguida, use o docker logs <hex id>.

Bem, o melhor que eu descobri até agora é:

#stop the current demon and start it in debug modussudo service docker stopdockerd -D # --debug

Basta iniciar o cliente a partir de um novo shell. O equívoco era pensar que o cliente realmente faz qualquer 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 (anexar ao stdout/stderr) bandeira foi suficiente:

user@machine:~$ docker start -a server_nameError: The directory named as part of the path /log/log_path/app.log does not exist.For help, use /usr/bin/supervisord -h

Ele mostrou o erro de inicialização (no nosso caso, um caminho de log ausente usado por supervisord). Presumo 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 o regex no local substituindo uma string em um arquivo .so é um pouco insano: a string só tem muito espaço alocado a ela e, se você alterar as compensações de arquivos de outras entradas, o arquivo elf será corrompido. Tente executar objdump ou readelf em seu arquivo .so após executar o comando perl (antes da alteração 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, nenhuma compensação é alterada. Considere o diretório / dkr ou similar se preferir não usar /tmp.

Se você precisar adotar essa abordagem e seus caminhos desejados forem imutáveis, reconstrua a biblioteca e altere o caminho padrão para /etc/hosts na origem. Ou melhor, ao construir seu modificado libnss_files.so renomeie-o para algo como libnss_altfiles.so e mudança nsswitch.conf usar hosts: altfiles ao iniciar o contêiner do docker (a menos que o docker tenha o nsswitch montado no bind.conf também, então você não pode alterá-lo). Isso permitirá que você tenha o libnss_altfiles.so em paralelo com suas bibliotecas normais no sistema base. Se o docker ligar-montar nsswitch.conf, deixe uma cópia do seu reconstruído libnss_files.so em seu diretório / lib-override pronto para ser carregado por LD_LIBRARY_PATH.

Como um heads up, os binários suid/sgid ignoram LD_LIBRARY_PATH e LD_PRELOAD, então algumas coisas vão quebrar (leia: volte a usar o padrão /etc/hosts) se você usar essas variáveis.

Às vezes, você pode encontrar mensagens de erro úteis inserindo sshing no nó que executa o daemon docker e fazendo:

$ tail -f /var/log/containers/* /var/log/docker.log 2>&1

Em 'Docker Community edition' no Mac OS, você pode se conectar à VM do docker fazendo:

$  screen ~/Library/Containers/com.docker.docker/Data/vms/0/tty

Por favor, faça o esforço para marcar uma das respostas como “aceito”, obrigado!