Что происходит с другими процессами, когда заканчивается контейнер Pock1 Docker?
Рассмотрим следующее, которое пробегает sleep 60
в фоновом режиме и затем выходит:
$ cat run.sh
sleep 60&
ps
echo Goodbye!!!
$ docker run --rm -v $(pwd)/run.sh:/run.sh ubuntu:16.04 bash /run.sh
PID TTY TIME CMD
1 ? 00:00:00 bash
5 ? 00:00:00 sleep
6 ? 00:00:00 ps
Goodbye!!!
Это запустит контейнер Docker с bash
как PID1. Затем он выполняет fork/execs процесс sleep
, а затем bash
завершает работу. Когда контейнер Docker умирает, процесс sleep
как-то тоже умирает.
Мой вопрос: каков механизм, по которому убит процесс sleep
? Я попытался поймать ловушку SIGTERM
в дочернем процессе, и похоже, что он не сработает. Моя презумпция заключается в том, что что-то (либо Docker, либо ядро Linux) отправляет SIGKILL
при закрытии группы, используемой контейнером, но я нигде не обнаружил никакой документации, уточняющей это.
РЕДАКТИРОВАТЬ. Ближе всего я пришел к объяснению следующей цитаты из baseimage-docker:
Если ваш процесс инициализации является вашим приложением, то он, вероятно, будет закрыт сам, а не все остальные процессы в контейнере. Затем ядро принудительно уничтожит эти другие процессы, не давая им возможность изящно закрыть, что потенциально может привести к повреждению файлов, устаревшим временным файлам и т.д. Вы действительно хотите завершить все ваши процессы изящно.
Итак, по крайней мере, согласно этому, подразумевается, что при выходе контейнера ядро отправляет SIGKILL ко всем оставшимся процессам. Но мне все же хотелось бы ясности относительно того, как он решает это сделать (т.е. Является ли это особенностью групп?), И в идеале более авторитетный источник будет приятным.
Ответы
Ответ 1
Хорошо, я, кажется, придумал еще несколько убедительных доказательств того, что это, по сути, ядро Linux, делающее завершение. На странице руководства clone(2)
есть этот полезный раздел:
CLONE_NEWPID (начиная с Linux 2.6.24)
Первый процесс, созданный в новом пространстве имен (т.е. процесс созданный с использованием флага CLONE_NEWPID) имеет PID 1 и является "init" для пространства имен. Дети, осиротели в пространстве имен будет репрезентативным для этого процесса, а не инициализации (8). В отличие от традиционного процесса инициализации, процесс init Пространство имен PID может завершиться, и если это произойдет, все процессы в пространство имен завершено.
К сожалению, это все еще неясно, как прекращаются процессы в пространстве имен, но, возможно, это потому, что в отличие от обычного выхода процесса в таблице процессов нет записи. В любом случае представляется очевидным, что:
- Ядро само убивает другие процессы
- Они не убиты способом, который позволяет им делать очистку, делая ее (почти?) идентичной SIGKILL