Ответ 1
в то время как мы можем установить несколько процессов без супервизора, только один процесс может быть запущен, когда запускается прогон докеров, и когда контейнер остановлен, только PID 1 будет отправлен, а другой текущий процесс не будет прекращен изящно.
Да, хотя это зависит от того, как выполняется ваш основной процесс (переднего плана или фона) и как он собирает дочерние процессы.
Это то, что подробно описано в разделе Треппинг сигналов в контейнерах Docker
docker stop
останавливает запущенный контейнер, отправив ему сигналSIGTERM
, пусть основной процесс обработает его, а после периода отсрочки используетSIGKILL
для завершения приложения.Сигнал, отправленный в контейнер, обрабатывается основным процессом, который выполняется (PID 1).
Если приложение находится на переднем плане, то есть приложение является основным процессом в контейнере (PID1), оно может обрабатывать сигналы напрямую.
Но:
Сигнал, который должен сигнализироваться, может быть фоновым, и вы не можете посылать какие-либо сигналы напрямую. В этом случае одним из решений является установка shell- script в качестве точки входа и организация всей обработки сигнала в script.
Более подробная информация приведена в разделе Docker и проблема PID 1 по сбору зомби"
Unix разработан таким образом, что родительские процессы должны явно "ждать" для завершения дочернего процесса, чтобы получить статус выхода. Процесс зомби существует до тех пор, пока родительский процесс не выполнит это действие, используя семейство системных вызовов
waitpid()
.Действие вызова waitpid() для дочернего процесса, чтобы исключить его зомби, называется "пожинать".
Процесс
init
- PID 1 - имеет специальную задачу. Его задача - "принять" осиротевшие дочерние процессы.
Операционная система ожидает, что процесс init также получит усыновленных детей.
Проблема с Docker:
Мы видим, что многие люди запускают только один процесс в своем контейнере, и они думают, что когда они запускают этот единственный процесс, они сделаны.
Но, скорее всего, этот процесс не написан, чтобы вести себя как правильный процесс инициализации.
То есть вместо того, чтобы правильно использовать принятые процессы, он, вероятно, ожидает, что другойinit
процесс выполнит эту работу, и это правильно.
Использование изображения типа phusion/baseimage-docker
помогает управлять одним (или несколькими) процессами, сохраняя при этом основной процесс, совместимый с процессом.
Он использует runit
вместо supervisord
для управления несколькими процессами:
Runit не существует, чтобы решить проблему пожинания. Скорее, он поддерживает несколько процессов. Множество процессов рекомендуется для обеспечения безопасности (посредством изоляции процессов и пользователей).
Runit использует меньше памяти, чем Supervisord, потому что Runit написан на C и Supervisord в Python.
И в некоторых случаях использование перезапуска процесса в контейнере предпочтительнее перезапуска всех контейнеров.
Это изображение включает my_init
script, который заботится о проблеме "пожинания".
В baseimage-docker мы рекомендуем запускать несколько процессов в одном контейнере. Не обязательно несколько сервисов. Логическая услуга может состоять из нескольких процессов ОС, и мы предоставляем возможности для этого.