¿Cómo puedo depurar la inicialización de un contenedor acoplable?

93

Tuve un problema con un contenedor, aunque se construye perfectamente, no se inicia correctamente. La causa es una solución alternativa que agregué al Dockerfile (por tener un enrutamiento autoconfigurado / etc / hosts)

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 hay algún error allí, pero me pregunto cómo puedo obtener más información sobre lo que está haciendo Docker mientras se ejecuta. por ejemplo, esto funciona:

$ docker run image ls
usr bin ...

Pero esto no:

$ docker run image ls -l
$

No hay nada en los registros y tampoco puedo llamar a un shell interactivo. Puedo usar strace para ver qué sucede, pero esperaba que hubiera una mejor manera.

¿Hay alguna manera de configurar Docker para que sea más detallado?

EDITAR : Gracias a Andrew D. Ahora sé lo que está mal con el código anterior (lo dejé para que se pueda entender su respuesta). Ahora la cuestión es todavía cómo podría yo depurar algo como esto o conseguir algunos interiores en qué ls -l fracasaron por qué ls no lo hicieron.

EDITAR : El -D = verdadero podría dar más salida, aunque no en mi caso ...

estani
fuente
Haga el esfuerzo de marcar una de las respuestas como "aceptada", ¡gracias!
Brian Topping

Respuestas:

95

El eventscomando Docker puede ayudar y el comando Docker logs puede recuperar registros incluso después de que la imagen no se inicie.

Primero comience docker eventsen segundo plano para ver qué está pasando.

docker events&

Luego ejecute su docker run ...comando fallido . Entonces debería ver algo como lo siguiente en la pantalla:

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

Luego puede obtener la identificación hexadecimal de inicio del mensaje anterior o la salida del comando de ejecución. Luego puede usarlo con el comando de registros:

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

Ahora debería ver algunos resultados del inicio fallido de la imagen.

Como @alexkb sugirió en un comentario: docker events&puede ser problemático si su contenedor se reinicia constantemente desde algo como el servicio AWS ECS. En este escenario, puede ser más fácil sacar la identificación hexadecimal del contenedor de los registros /var/log/ecs/ecs-agent.log.<DATE>. Luego usa docker logs <hex id>.

Peter Lamberg
fuente
¡Muy útil! Nuevo en Docker y estaba tratando de ejecutar Portainer. Lo resolvió con estos pasos de depuración. Encontré a alguien en Medium.com con el mismo problema: medium.com/@jameson_37151/…
Jameson
Me sale "contenedor no encontrado"?
erizo demente
Extraño. Solo para asegurarme, @dementedhedgehog, ¿intentaste copiar la identificación hexadecimal del mensaje de registro que termina en " (from xxx/xxx:latest) die"?
Peter Lamberg
1
Muchas gracias por esta respuesta, es un salvavidas. Lo único que puede agregar es que docker events&puede ser problemático si su contenedor se reinicia constantemente desde algo como el servicio AWS ECS. Entonces, en este escenario, puede ser más fácil sacar la identificación hexadecimal del contenedor de los registros /var/log/ecs/ecs-agent.log.<DATE>. Luego, use docker logs <hex id>como se sugiere en esta respuesta para ver por qué las cosas no se inician.
alexkb
1
@alexkb ¡Gracias! Agregué su sugerencia al final de la respuesta para que otros puedan encontrarla más fácilmente.
Peter Lamberg
18

Bueno, lo mejor que he descubierto hasta ahora es:

#stop the current demon and start it in debug modus
sudo service docker stop
dockerd -D # --debug

Simplemente inicie el cliente desde un nuevo shell. La idea errónea fue pensar que el cliente realmente hace algo ... bueno, solo se está comunicando con el demonio, por lo que no desea depurar al cliente sino al propio demonio (normalmente).

estani
fuente
13

En mi caso, el -aindicador (adjuntar a STDOUT / STDERR) fue suficiente:

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

Mostró el error de inicio (en nuestro caso, una ruta de registro faltante utilizada por supervisord). Supongo que la mayoría de los errores de inicio del contenedor también aparecerían aquí.

Claytond
fuente
3

No puedo responder a su pregunta sobre cómo hacer que la salida de Docker sea más completa, pero puedo decirle que la expresión regular en el lugar que reemplaza una cadena en un archivo .so es un poco loco: la cadena solo tiene mucho espacio asignado, y Si cambia las compensaciones de archivo de otras entradas, el archivo elf se corrompe. Intente ejecutar objdump o readelf en su archivo .so después de ejecutar el comando perl ( antes del cambio LD_LIBRARY_PATH ) fuera de un contenedor: dólares a rosquillas ahora está dañado.

La razón por la que funciona en este truco tristemente necesario es porque "tmp" y "etc" tienen la misma longitud de cadena, por lo que no cambian las compensaciones. Considere el directorio / dkr o similar si prefiere no usar / tmp.

Si DEBE adoptar este enfoque y sus rutas deseadas no se pueden cambiar, reconstruya la biblioteca y cambie la ruta predeterminada para / etc / hosts en la fuente. O mejor, cuando construya su libnss_files.sonombre modificado , libnss_altfiles.socámbielo a algo así y cámbielo nsswitch.confpara usarlo hosts: altfilescuando inicie su contenedor acoplable (a menos que el acoplador también haya montado nsswitch.conf, entonces no puede cambiarlo). Esto le permitirá tener libnss_altfiles.so en paralelo con sus bibliotecas normales en el sistema base. Si la ventana acoplable nsswitch.conf de bind-mount, deje una copia de sus libnss_files.so reconstruidos en su directorio / lib-override listo para ser cargado por LD_LIBRARY_PATH.

Como aviso, los binarios suid / sgid ignoran LD_LIBRARY_PATH y LD_PRELOAD, por lo que algunas cosas se romperán (lea: vuelva a usar el / etc / hosts predeterminado) si usa esas variables.

Andrew Domaszek
fuente
Muchas gracias por la gran comprensión ... Fui demasiado rápido y ahora veo lo que está sucediendo. Todavía no sé por qué obtener la estadística necesita resolver un host (ls -l) mientras que la simple lista de archivos (ls) no ...
estani
0

A veces, puede encontrar mensajes de error útiles ingresando al nodo que ejecuta el demonio docker y luego haciendo:

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

En 'Docker Community edition' en Mac OS, puede conectarse al docker vm haciendo lo siguiente:

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