$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 /执行一个睡眠进程,然后bash退出.当Docker容器死亡时,睡眠过程也会死亡.
我的问题是:睡眠过程被杀死的机制是什么?我尝试在一个子进程中捕获SIGTERM,似乎没有被绊倒.我的推测是,当关闭集群正在使用的cgroup时,Docker或者Linux内核会发送SIGKILL,但是我没有找到任何文档来澄清这一点.
编辑最接近我的解释是从baseimage-docker的以下引用:
If your init process is your app,then it’ll probably only shut down itself,not all the other processes in the container. The kernel will then forcefully kill those other processes,not giving them a chance to gracefully shut down,potentially resulting in file corruption,stale temporary files,etc. You really want to shut down all your processes gracefully.
因此,至少根据这一点,这意味着当容器退出时,内核将向所有剩余的进程发送一个SIGKILL.但是我仍然希望清楚它如何决定这样做(即,它是cgroups的一个特征?),理想的是一个更权威的来源将是不错的.
解决方法
CLONE_NEWPID (since Linux 2.6.24)
The first process created in a new namespace (i.e.,the process@H_403_26@ created using the CLONE_NEWPID flag) has the PID 1,and is the@H_403_26@ “init” process for the namespace. Children that are orphaned@H_403_26@ within the namespace will be reparented to this process rather than@H_403_26@ init(8). Unlike the traditional init process,the “init” process of a@H_403_26@ PID namespace can terminate,and if it does,all of the processes in@H_403_26@ the namespace are terminated.
不幸的是,命名空间中的进程究竟如何终止,但也许是因为与正常进程退出不同,进程表中没有任何条目.无论如何,似乎很清楚:
内核本身正在杀死其他进程>他们没有以一种允许他们有机会进行清理的方式被杀死,使它(几乎)与SIGKILL相同