当Docker容器的PID1退出时,其他进程会怎样? [英] What happens to other processes when a Docker container's PID1 exits?

查看:554
本文介绍了当Docker容器的PID1退出时,其他进程会怎样?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下内容,它们在后台运行 sleep 60 然后退出:

Consider the following, which runs sleep 60 in the background and then exits:

$ 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。然后,它分叉/执行 sleep 进程,然后退出 bash 。当Docker容器死亡时, sleep 进程也会以某种方式死亡。

This will start a Docker container, with bash as PID1. It then fork/execs a sleep process, and then bash exits. When the Docker container dies, the sleep process somehow dies too.

我的问题是:机制是什么 sleep 进程被杀死了?我尝试在子进程中捕获 SIGTERM ,但似乎没有被触发。我的推测是,当关闭容器正在使用的cgroup时,某些东西(无论是Docker还是Linux内核)正在发送 SIGKILL ,但是我找不到任何文档来阐明这一点。

My question is: what is the mechanism by which the sleep process is killed? I tried trapping SIGTERM in a child process, and that appears to not get tripped. My presumption is that something (either Docker or the Linux kernel) is sending SIGKILL when shutting down the cgroup the container is using, but I've found no documentation anywhere clarifying this.

编辑我最接近的解释是来自 baseimage-docker

EDIT The closest I've come to an explanation is the following quote from 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的功能吗?),理想情况下,更权威的信息源将是很好的。

So at least according to this, the implication is that when the container exits, the kernel will sending a SIGKILL to all remaining processes. But I'd still like clarity on how it decides to do that (i.e., is it a feature of cgroups?), and ideally a more authoritative source would be nice.

推荐答案

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

OK, I seem to have come up with some more solid evidence that this is, in fact, the Linux kernel doing the terminating. In the clone(2) man page, there's this useful section:


CLONE_NEWPID (自Linux 2.6.24起)

CLONE_NEWPID (since Linux 2.6.24)

在新名称空间中创建的第一个进程(即,使用CLONE_NEWPID创建的进程
标记)具有PID 1,并且是名称空间的
init过程。命名空间中孤立的
的子级将被重新绑定到此过程,而不是
init(8)。与传统的初始化过程不同,
PID名称空间的 init过程可以终止,如果终止,则
名称空间中的所有过程都将终止。

The first process created in a new namespace (i.e., the process created using the CLONE_NEWPID flag) has the PID 1, and is the "init" process for the namespace. Children that are orphaned within the namespace will be reparented to this process rather than init(8). Unlike the traditional init process, the "init" process of a PID namespace can terminate, and if it does, all of the processes in the namespace are terminated.

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

Unfortunately this is still vague on how exactly the processes in the namespace are terminated, but perhaps that's because, unlike a normal process exit, no entry is left in the process table. Whatever the case is, it seems clear that:


  • 内核本身正在杀死其他进程

  • 他们不会以允许他们有任何机会进行清理的方式被杀死,使其(几乎?)等同于SIGKILL

这篇关于当Docker容器的PID1退出时,其他进程会怎样?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆