Назад | Перейти на главную страницу

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

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

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

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

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

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

Первый старт 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>.

Что ж, лучшее, что я узнал, это:

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

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

В моем случае -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). Я предполагаю, что здесь также будет отображаться большинство ошибок запуска контейнера.

Я не могу ответить на ваш вопрос о том, как сделать вывод докеров более полным, но могу сказать вам, что регулярное выражение на месте, заменяющее строку в файле .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), если вы используете эти переменные.

Иногда вы можете найти полезные сообщения об ошибках, подключившись к узлу, на котором запущен демон 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