docker run, docker exec и журналы

If I do :

docker run --name nginx -d nginx:alpine /bin/sh -c 'echo "Hello stdout" > /dev/stdout'

Я вижу "Hello stdout", когда делаю:

docker logs nginx

Но когда контейнер запущен (docker run --name nginx -d nginx:alpine), я делаю:

docker exec nginx /bin/sh -c 'echo "Hello stdout" > /dev/stdout'

или когда я прикрепляю контейнер с помощью:

docker exec -it nginx /bin/sh

а потом :

echo "Hello stdout" > /dev/stdout

Я ничего не вижу в журналах докера. И поскольку мои журналы доступа Nginx перенаправляются в /dev/stdout, я их тоже не вижу.

Что здесь происходит с этим stdout ?


person Tristan    schedule 22.03.2017    source источник


Ответы (1)


Когда вы docker exec увидите, что у вас есть несколько процессов

/ # ps -ef
PID   USER     TIME   COMMAND
    1 root       0:00 nginx: master process nginx -g daemon off;
    6 nginx      0:00 nginx: worker process
    7 root       0:00 /bin/sh
   17 root       0:00 ps -ef
/ # 

а в Linux у каждого процесса есть свои stdin, stdout, stderr (и другие файловые дескрипторы), в /proc/pid/fd

так вот, со своим docker exec (pid 7) вы что-то выводите в

/прок/7/фд/1

Если вы делаете ls -ltr /proc/7/fd/1, отображается что-то вроде /proc/4608/fd/1 -> /dev/pts/2, что означает, что вывод отправляется на терминал.

в то время как ваш процесс nginx (pid 1) отображает его вывод в

/прок/1/фд/1

Если вы делаете ls -ltr /proc/1/fd/1, отображается что-то вроде /proc/1/fd/1 -> pipe:[184442508], что означает, что выходные данные отправляются в драйвер ведения журнала докеров.

person user2915097    schedule 22.03.2017
comment
Я пытаюсь понять, но: 1. проблема воспроизводима с простым альпийским образом 2. есть только один /dev/stdout, так что я думаю, он должен выбрать, на какой /proc/xxx/fd/1 он ссылается , я ошибся ? - person Tristan; 22.03.2017
comment
Кроме того, вы говорите, что эти инструкции из официального образа Nginx никогда не будут работать? # пересылать журналы запросов и ошибок в сборщик журналов докеров RUN ln -sf /dev/stdout /var/log/nginx/access.log \ && ln -sf /dev/stderr /var/log/nginx/error.log - person Tristan; 22.03.2017
comment
Хорошо, я отвечу на свои вопросы: 1. Я думаю, что docker exec создаст оболочку, которая не является основным процессом 2. Нет, есть не только один /dev/stdout, это динамическое устройство, связанное с текущим процессом 3 Инструкции на самом деле работают, если вы не пытаетесь отображать файлы изнутри контейнера, а используете только журналы докеров nginx, которые будут показывать как журналы доступа, так и журналы ошибок. Если вам нужны постоянные журналы, просто используйте тома. - person Tristan; 22.03.2017
comment
Спасибо, это отличное объяснение. Знаете ли вы, есть ли способ заставить docker exec отправлять вывод в драйвер ведения журнала Docker, а не обратно в вызывающий скрипт? - person user3789553; 30.03.2021