Docker - обработка нескольких сервисов в одном контейнере
Я хотел бы запустить две разные службы в моем контейнере Docker и выйти из контейнера, как только одна из них выйдет. Я посмотрел на супервизор, но не могу найти способ заставить его выйти, как только выйдет одно из управляемых приложений. Он пытается перезапустить их до трех раз, как при стандартной настройке, а затем просто сидит и ничего не делает. Может ли супервизор сделать это или есть другой инструмент для этого? Бонус был бы, если бы также был способ позволить обеим управляемым программам писать в стандартный вывод, помеченный их именем приложения, например:
[Program 1] Some output
[Program 2] Some other output
[Program 1] Output again
2 ответа
Так как вы спросили, есть ли другой инструмент... мы разработали и написали мощную замену supervisord
это разработано специально для Docker. Он автоматически завершает работу при выходе из всех приложений, а также имеет специальные параметры службы для управления этим поведением, а также перенаправляет стандартный вывод с помеченными syslog-совместимыми выходными строками. Это открытый исходный код, и используется в производстве.
Вот быстрый старт для Docker: http://garywiz.github.io/chaperone/guide/chap-docker-simple.html
Существует также полный набор протестированных базовых образов, которые являются хорошим примером по адресу: https://github.com/garywiz/chaperone-docker, но они могут быть излишними, и более ранний быстрый запуск может помочь.
Я нашел решения для обоих моих требований, прочитав еще несколько документов.
Выход супервизора при выходе из приложения
Это может быть достигнуто с помощью пользовательского EventListener. Мне пришлось добавить следующий сегмент в мой файл конфигурации супервизора:
[eventlistener:shutdownevent]
command=/shutdownhandler.sh
events=PROCESS_STATE_EXITED
supervisord запустит указанный сценарий и при срабатывании данного события (PROCESS_STATE_EXITED срабатывает после выхода из одной из управляемых программ, и он не перезапускается автоматически) отправит строку, содержащую данные о событии, в сценарии stdin.
Указанный скрипт shutdownhandler содержит:
#!/bin/bash
while :
do
echo -en "READY\n"
read line
kill $(cat /supervisord.pid)
echo -en "RESULT 2\nOK"
done
Сценарий должен указать, что готов, отправив "READY\n" на свой стандартный вывод, после чего он может получить строку данных о событиях на своем стандартном входе. В моем случае использования после получения строки (имеется в виду, что одна из управляемых программ вышла из системы), SIGTERM отправляется процессу supervisord, который находится в pid, который он оставляет в своем файле pid (по умолчанию расположен в корневом каталоге). Для технической полноты я также включил положительный ответ для списка событий, хотя он никогда не должен иметь значения.
Помеченный вывод на стандартный вывод
Я сделал это, просто запустив хвостовой процесс в фоновом режиме перед запуском супервизора, настроив журнал вывода программ и пропустив строки через ts (из пакета moreutils), чтобы добавить к нему тег. Таким образом, он обнаруживается в журналах докера и позволяет легко определить, какая программа действительно написала строку.
tail -fn0 /var/log/supervisor/program1.log | ts '[Program 1]' &