Подтвердить что ты не робот

Что происходит с другими процессами, когда заканчивается контейнер 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 ко всем оставшимся процессам. Но мне все же хотелось бы ясности относительно того, как он решает это сделать (т.е. Является ли это особенностью групп?), И в идеале более авторитетный источник будет приятным.

4b9b3361

Ответ 1

Хорошо, я, кажется, придумал еще несколько убедительных доказательств того, что это, по сути, ядро ​​Linux, делающее завершение. На странице руководства clone(2) есть этот полезный раздел:

CLONE_NEWPID (начиная с Linux 2.6.24)

Первый процесс, созданный в новом пространстве имен (т.е. процесс созданный с использованием флага CLONE_NEWPID) имеет PID 1 и является "init" для пространства имен. Дети, осиротели в пространстве имен будет репрезентативным для этого процесса, а не инициализации (8). В отличие от традиционного процесса инициализации, процесс init Пространство имен PID может завершиться, и если это произойдет, все процессы в пространство имен завершено.

К сожалению, это все еще неясно, как прекращаются процессы в пространстве имен, но, возможно, это потому, что в отличие от обычного выхода процесса в таблице процессов нет записи. В любом случае представляется очевидным, что:

  • Ядро само убивает другие процессы
  • Они не убиты способом, который позволяет им делать очистку, делая ее (почти?) идентичной SIGKILL