Как я могу отладить инициализацию контейнера docker?

У меня была проблема с контейнером, даже несмотря на то, что он отлично строится, он не запускается должным образом. Причиной является обходной путь, который я добавил в файл Dockerfile (для самонастраиваемой маршрутизации /etc/hosts)

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

Очевидно, что там какая-то ошибка, но мне интересно, как я могу получить больше информации о том, что делает docker во время работы. например, это работает:

$ docker run image lsusr bin ...

Но это не значит:

$ docker run image ls -l$

В журналах ничего нет, и я тоже не могу вызвать интерактивную оболочку. Я могу использовать strace, чтобы посмотреть, что происходит, но я надеялся, что есть лучший способ.

Есть ли какой-нибудь способ сделать docker более подробным?

РЕДАКТИРОВАТЬ: Спасибо Эндрю Д. Теперь я знаю, что не так с приведенным выше кодом (я оставил его, чтобы его ответ можно было понять). Теперь проблема по-прежнему заключается в том, как я могу отладить что-то подобное или узнать, почему ls -l потерпел неудачу, почему ls этого не произошло.

РЕДАКТИРОВАТЬ: Значение -D=true может дать больше выходных данных, хотя и не в моем случае...

Докер events команда может помочь и Журналы Docker команда может извлекать журналы даже после того, как образ не удалось запустить.

Первый старт docker events на заднем плане, чтобы видеть, что происходит.

docker events&

Затем запустите свой неудачный docker run ... команда. Затем вы должны увидеть на экране что-то вроде следующего:

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

Затем вы можете получить шестнадцатеричный идентификатор запуска из предыдущего сообщения или выходных данных команды run. Затем вы можете использовать его с помощью команды logs:

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

Теперь вы должны увидеть некоторые результаты неудачного запуска образа.

Как предложил @alexkb в комментарии: docker events& это может вызвать проблемы, если ваш контейнер постоянно перезапускается из чего-то вроде службы AWS ECS. В этом случае может быть проще получить шестнадцатеричный идентификатор контейнера из журналов в /var/log/ecs/ecs-agent.log.<DATE>. Затем используйте docker logs <hex id>.

Что ж, лучшее, что я выяснил на данный момент, это:

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

Просто запустите клиент из новой оболочки. Заблуждением было думать, что клиент на самом деле вообще что-то делает... ну, это просто общение с демоном, так что вы не хотите отлаживать клиент, но сам демон (обычно).

В моем случае, -a (прикрепить к STDOUT /STDERR) флаг было достаточно:

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

Он показал ошибку запуска (в нашем случае отсутствующий путь к журналу, используемый supervisord). Я предполагаю, что большинство ошибок при запуске контейнера также будут отображаться здесь.

Я не могу ответить на ваш вопрос о том, как сделать вывод docker более полным, но я могу сказать вам, что регулярное выражение на месте, заменяющее строку в файле .so, немного безумно: для строки выделено только столько места, и если вы измените смещения файлов других записей, то файл elf становится поврежденным. Попробуйте запустить objdump или readelf в вашем файле .so после выполнения команды perl (перед изменением LD_LIBRARY_PATH) за пределами контейнера - от долларов до пончиков, теперь он поврежден.

Причина, по которой это работает в этом печально необходимом взломе это потому, что "tmp" и "etc" имеют одинаковую длину строки, поэтому смещения не меняются. Рассмотрите каталог /dkr или аналогичный, если вы предпочитаете не использовать /tmp.

Если вы ДОЛЖНЫ использовать этот подход и ваши желаемые пути неизменны, перестройте библиотеку и измените путь по умолчанию для /etc/hosts в исходном коде. Или лучше, при создании вашего модифицированного libnss_files.so переименуйте его во что-то вроде libnss_altfiles.so и изменить nsswitch.conf использовать hosts: altfiles при запуске вашего контейнера docker (если в docker также не установлен привязанный файл nsswitch.conf, вы не можете его изменить). Это позволит вам иметь libnss_altfiles.so параллельно с вашими обычными библиотеками в базовой системе. Если docker выполняет привязку-монтирование nsswitch.conf, оставьте копию вашего перестроенного libnss_files.so в вашем каталоге /lib-override, готовом к загрузке с помощью LD_LIBRARY_PATH.

Предупреждаю, двоичные файлы suid /sgid игнорируют LD_LIBRARY_PATH и LD_PRELOAD, поэтому некоторые вещи могут сломаться (читай: вернитесь к использованию /etc/hosts по умолчанию), если вы используете эти переменные.

Иногда вы можете найти полезные сообщения об ошибках, подключившись к узлу, на котором запущен демон docker, а затем выполнив:

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

В "Docker Community edition" на Mac OS вы можете подключиться к виртуальной машине docker, выполнив:

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

Пожалуйста, приложите усилия, чтобы отметить один из ответов как “принятый”, спасибо!