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

考虑以下内容,在后台运行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 / exec一个sleep过程,然后bash退出。 当Docker容器死亡时, sleep过程也会死亡。

我的问题是:什么是sleep过程被杀死的机制? 我试图在一个subprocess中捕获SIGTERM ,并且看起来没有被触发。 我的推测是Docker或Linux内核在closures容器使用的cgroup时发送了SIGKILL ,但是我没有发现有关文档的任何说明。

编辑最接近我来解释是从baseimagedocker以下报价:

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

所以至less按照这个意思,这意味着当容器退出时,内核会发送一个SIGKILL给所有剩下的进程。 但是我还是想清楚它是如何决定这样做的(即它是cgroups的一个特征吗?),理想情况下,更权威的来源会更好。

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

CLONE_NEWPID (自Linux 2.6.24起)

在新名称空间(即使用CLONE_NEWPID标志创建的进程)中创建的第一个进程具有PID 1,并且是名称空间的“init”进程。 在命名空间中孤儿的孩子将被重新设置到这个过程而不是init(8)。 与传统的init进程不同,PID命名空间的“init”进程可以终止,如果是的话,命名空间中的所有进程都将终止。

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

  • 内核本身正在杀死其他进程
  • 他们不是以一种让他们有机会进行清理的方式杀死的,使它几乎与SIGKILL相同