как работает регистрация контейнеров? - PullRequest
1 голос
/ 29 апреля 2020

Я видел во многих docker контейнерах, что обычной практикой является создание файла журнала и ведение журнала, подобного этому

/var/log/container.log
...

tail  -f /var/log/container.log

И каким-то образом вывод, похоже, выполняется во время выполнения контейнера журнал драйверов. Так что, если я запускаю

docker container logs container

Это покажет вывод файла container.log

Я знаю, что для любого контейнера рекомендуется войти в систему stdout и stderr, но я не могу понять, почему первый вариант работает (создайте файл и запустите tail на нем). Это потому, что вывод tail заносится в журнал драйверов и сливает его с содержимым stdout?

Очень ценю вашу помощь. Спасибо.

1 Ответ

2 голосов
/ 29 апреля 2020

Подход tail -f на самом деле не является наилучшей практикой.

Как вы заметили, правильный способ запуска процесса и создания журналов состоит в том, чтобы он записывал свои выходные данные непосредственно в stdout и stderr, и docker logs захватит их. Вы можете настроить уровень ведения журнала Docker для отправки их в другое место; если вы переходите к кластерной инфраструктуре, такой как Kubernetes, вы можете настроить ее уровень ведения журнала также для регистрации журналов, не изменяя код приложения.

#!/bin/sh
# I am the script that runs the main container process.
# Run a single process, as a foreground process; when that
# process ends, the container exits.
exec some_server --no-daemon --log-file /dev/stdout

Когда вы видите tail -f, оно обычно выглядит так:

#!/bin/sh
# Start something as a background process.
something --log-file /var/log/something.log &
# Hackily keep the container from exiting.
tail -f /var/log/something.log

Основным контейнерным процессом является tail процесс. Когда tail выходит, контейнер останавливается, а если вы docker stop контейнер, сигнал будет go до tail. О, кстати, как побочный эффект, запущен процесс something, но в случае его сбоя Docker не может это заметить. Тем не менее, поскольку процесс tail является основным процессом, а tail -f никогда не завершится, это позволяет контейнеру работать, и его журналы на основе файлов будут видны stdout контейнера.

Другой интересный подход Вот что делает изображение Docker Hub httpd: оно устанавливает свое ведение журнала так, чтобы оно указывало на файл, но содержимым этого файла по умолчанию является символическая ссылка на /dev/stdout.

RUN mkdir /var/log/something \
 && ln -s /dev/stdout /var/log/something/something.log
CMD ["something", "--log-file", "/var/log/something/something.log"]

Это Интересно, потому что по умолчанию поведение записывается в этот файл журнала, но на самом деле это специальное устройство /dev/stdout, поэтому оно будет go в стандартный вывод процесса (основного процесса контейнера). Если вы хотите записать это в файл, вы можете подключить свой собственный каталог через /var/log/something, что будет скрывать символическую ссылку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...