考虑以下内容,它在后台运行$ 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的一个特征吗?),理想情况下,一个更权威的来源会很好。
答案 0 :(得分:3)
好吧,我似乎已经提出了一些更确凿的证据,证明这实际上是Linux内核正在终止。在clone(2)
手册页中,有一个有用的部分:
CLONE_NEWPID (自Linux 2.6.24起)
在新命名空间中创建的第一个进程(即进程 使用CLONE_NEWPID标志创建的)具有PID 1,并且是 "初始化"命名空间的过程。孤儿的孩子 命名空间内的内容将被重新分配给此进程而不是 的init(8)。与传统的init进程不同," init"一个过程 PID命名空间可以终止,如果是,则终止所有进程 命名空间终止。
不幸的是,关于命名空间中的进程到底是如何被终止的仍然是模糊的,但也许这是因为,与正常的进程退出不同,进程表中没有任何条目。无论情况如何,似乎很清楚: