当Docker容器的PID1退出时,其他进程会发生什么?

时间:2016-09-28 06:33:23

标签: linux docker cgroups

考虑以下内容,它在后台运行$ 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!!! 然后退出:

bash

这将启动一个Docker容器,sleep为PID1。然后fork /执行bash进程,然后sleep退出。当Docker容器死掉时,sleep进程也会以某种方式死掉。

我的问题是:SIGTERM进程被杀死的机制是什么?我尝试在子进程中捕获SIGKILL,但似乎没有被绊倒。我的假设是,当关闭容器正在使用的cgroup时,某些东西(Docker或Linux内核)正在发送identifierForVendor,但我发现没有文档说明这一点。

编辑我最接近解释的是来自baseimage-docker的以下引用:

  

如果你的init进程是你的应用程序,那么它可能只关闭自己,而不是容器中的所有其他进程。然后,内核将强制终止其他进程,不给他们优雅关闭的机会,可能导致文件损坏,过时的临时文件等。您真的想要优雅地关闭所有进程。

因此,至少根据这一点,暗示当容器退出时,内核将向所有剩余进程发送SIGKILL。但我仍然希望明确它是如何决定这样做的(即,它是cgroups的一个特征吗?),理想情况下,一个更权威的来源会很好。

1 个答案:

答案 0 :(得分:3)

好吧,我似乎已经提出了一些更确凿的证据,证明这实际上是Linux内核正在终止。在clone(2)手册页中,有一个有用的部分:

  

CLONE_NEWPID (自Linux 2.6.24起)

     

在新命名空间中创建的第一个进程(即进程   使用CLONE_NEWPID标志创建的)具有PID 1,并且是   "初始化"命名空间的过程。孤儿的孩子   命名空间内的内容将被重新分配给此进程而不是   的init(8)。与传统的init进程不同," init"一个过程   PID命名空间可以终止,如果是,则终止所有进程   命名空间终止。

不幸的是,关于命名空间中的进程到底是如何被终止的仍然是模糊的,但也许这是因为,与正常的进程退出不同,进程表中没有任何条目。无论情况如何,似乎很清楚:

  • 内核本身正在杀死其他进程
  • 他们没有被允许有机会进行清理的方式被杀死,使它(几乎?)与SIGKILL相同