exec как компонент конвейера

Для нашего приложения, работающего внутри контейнера, предпочтительно, чтобы оно получало SIGTERM, когда контейнер (изящно) закрывается. В то же время мы хотим, чтобы его вывод попадал в файл журнала.

Поэтому в стартовом скрипте нашего контейнера докеров мы использовали bash exec, подобный этому

exec command someParam >> stdout.log

Это сработало просто отлично, command заменил оболочку, которая была корневым процессом контейнера, и получила SIGTERM.

Поскольку приложение имеет тенденцию вести много журналов, мы решили добавить ротацию журналов с помощью инструмента Apache rotatelogs, т.е.

exec command | rotatelogs -n 10 stdout.log 10M

Увы, кажется, что с помощью канала exec больше не может command заменить оболочку. При взгляде на процессы в работающем контейнере с pstree -p теперь это выглядит так

mycontainer@/#pstree -p
start.sh(1)-+-command(118)
            `-rotatelogs(119)

Таким образом, bash остается корневым процессом и не передает SIGTERM команде. Прежде чем наткнуться на exec, я нашел подход, который устанавливает обработчик сигналов в сценарий bash, который затем сам отправляет SIGTERM процессу command, используя kill. Однако это стало очень запутанным, получение PID также не всегда было простым, и я хотел бы сохранить удобство exec, когда дело доходит до обработки сигналов, и получить конвейер для ротации журнала. Любая идея, как это сделать?


person PalatinateJ    schedule 13.08.2020    source источник
comment
Можете ли вы управлять журналом вне Docker: пусть процесс записывает в свой стандартный вывод как обычно и либо docker run > container.log, либо настроить альтернативную систему ведения журнала Docker? Это позволяет избежать этой проблемы и необходимости иметь инструменты управления журналами внутри контейнера (и позволяет избежать вопроса о том, какая файловая система получает собранные журналы).   -  person David Maze    schedule 13.08.2020
comment
@DavidMaze Фактически мы помещаем все журналы всех наших контейнеров в папку, которая является сетевым ресурсом, чтобы упростить сбор всех журналов в клиентских кластерах без сложного стека обработки журналов (EFK или чего-то еще). Приложения пишут много других лог-файлов (по историческим причинам), так что нам это все равно нужно. Часто мы либо получаем только эти файлы (и ничего на stdout/err), либо только stdout/err. Я должен упомянуть, что в настоящее время мы в основном сосредоточены на K8.   -  person PalatinateJ    schedule 13.08.2020


Ответы (1)


Возможно, вы хотите

exec sh -c 'command | rotatelogs -n 10 stdout.log 10M'
person glenn jackman    schedule 13.08.2020
comment
Привет, @glenn, я попробовал это (на самом деле использую bash -c вместо sh -c... но это дает мне тот же pstree с неработающей обработкой сигналов, что и без, т. е. bash является root с командой и rotatelogs как его дети. - person PalatinateJ; 13.08.2020