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

93

У меня была проблема с контейнером, хотя он прекрасно собирается, но не запускается должным образом. Причина - это обходной путь, который я добавил в Dockerfile (для того, чтобы иметь самонастраиваемую маршрутизацию / 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

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

$ docker run image ls
usr bin ...

Но это не так:

$ docker run image ls -l
$

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

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

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

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

estani
источник
Пожалуйста, приложите усилия, чтобы пометить один из ответов как «принятый», спасибо!
Брайан Топпинг

Ответы:

95

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

Сначала запустите docker eventsв фоновом режиме, чтобы увидеть, что происходит.

docker events&

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

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

Затем вы можете получить шестнадцатеричный идентификатор запуска из предыдущего сообщения или выходных данных команды запуска. Затем вы можете использовать его с командой 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>. Тогда используйте докер logs <hex id>.

Питер Ламберг
источник
Очень полезно! Новичок в докере и пытался заставить работать portainer. Решил это с помощью этих шагов отладки. Нашел кого-то на Medium.com с той же проблемой: medium.com/@jameson_37151/…
Джеймсон
Я получаю "контейнер не найден" !?
сумасшедший ежик
Странный. Просто чтобы убедиться, @dementedhedgehog вы пытались скопировать hex-идентификатор из сообщения журнала, заканчивающегося на " (from xxx/xxx:latest) die"?
Питер Ламберг
1
Спасибо большое за этот ответ, это спасатель жизни. Единственное, что нужно добавить, это docker events&может быть хлопотно, если ваш контейнер постоянно перезапускается из-за чего-то вроде сервиса AWS ECS. Таким образом, в этом случае может быть проще получить шестнадцатеричный идентификатор контейнера из журналов /var/log/ecs/ecs-agent.log.<DATE>. Затем используйте docker logs <hex id>как предложено в этом ответе, чтобы увидеть, почему вещи не загружаются.
alexkb
1
@alexkb Спасибо! Я добавил ваше предложение в конец ответа, чтобы другим было легче его найти.
Питер Ламберг
18

Ну, лучшее, что я обнаружил, это:

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

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

estani
источник
13

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

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

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

claytond
источник
3

Я не могу ответить на ваш вопрос о том, как сделать вывод в 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при запуске контейнера докера (если докер также не имеет привязанного монтируемого nsswitch.conf, вы не можете его изменить). Это позволит вам иметь libnss_altfiles.so параллельно с вашими обычными библиотеками в базовой системе. Если docker выполняет bind-mount nsswitch.conf, оставьте копию перестроенного libnss_files.so в каталоге / lib-override, готового для загрузки LD_LIBRARY_PATH.

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

Андрей Домашек
источник
Большое спасибо за отличное понимание ... Я был слишком быстр и теперь вижу, что происходит. Я до сих пор не знаю, почему получение статистики требует разрешения хоста (ls -l), а простой листинг файлов (ls) не ...
estani
0

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

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

В «Docker Community Edition» в Mac OS вы можете подключиться к Docker vm, выполнив:

$  screen ~/Library/Containers/com.docker.docker/Data/vms/0/tty
user674669
источник