Docker-初始化,僵尸-为什么重要? [英] Docker - init, zombies - why does it matter?

查看:98
本文介绍了Docker-初始化,僵尸-为什么重要?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我确实阅读了这篇文章: https://blog.phusion.nl/2015/01/20/docker-and-the-pid-1-zombie-reaping-problem/

I did read this article: https://blog.phusion.nl/2015/01/20/docker-and-the-pid-1-zombie-reaping-problem/

设置一些背景:文章是关于容器中僵尸的问题,它试图说服我们这是一个真正的问题。

To set some context: Article is about problem with zombies in containers, it try to convince us that it is a real problem.

总的来说,我有百感交集。为什么这有关系 ?毕竟,即使在conananer主机OS中的僵尸能够释放/杀死该僵尸的情况下。我们知道容器中的进程是从宿主OS正常进程的角度来看的(通常,容器中的进程是具有某些名称空间和cgroup的正常进程)。

Generally, I have mixed feelings. Why does it matter ? After all, even in case zombies in conainer host OS is able to release/kill this zombie. We know that process in container is from point of view host OS normal process (and in general process in container is normal process with some namespaces and cgroups).

此外,我们还可以找到信息,以避免僵尸问题,我们应该使用 bash -c ... 。为什么呢也许,更好的选择是使用-init 吗?

Moreover, we can also find information that in order to avoid zombie problem we should use bash -c .... Why ? Maybe, better option is to use --init ?

有人可以解释这些吗?

推荐答案

有关初始化过程给您带来什么的简要但有用的解释,请参见 tini 是Docker在指定-init

For a brief but useful explanation of what an init process gives you, look at tini which is what Docker uses when you specify --init


时使用的

使用Tini有以下好处:

Using Tini has several benefits:


  • 它可以保护您免受意外创建僵尸进程的软件的侵害,因为僵尸进程会(随着时间的推移!)饿死您整个PID的系统
    (并使它无法使用)。

  • 它确保默认信号处理程序适用于您在Docker映像中运行的软件。例如,使用Tini,SIGTERM
    会正确终止您的进程,即使您没有显式为其安装信号
    处理程序也是如此。

这两个问题都会影响容器。容器中的进程仍然是主机上的进程,因此它占用了主机上的PID。无论您在容器中运行什么,都是PID 1,这意味着它必须安装信号处理程序才能获取该信号。

Both these issues affect containers. A process in a container is still a process on the host, so it takes up a PID on the host. Whatever you run in a container is PID 1 which means it has to install a signal handler to get that signal.

Bash恰好包含一个进程收割者,因此在 bash -c 下运行命令可以防止僵尸。除非您捕获,否则Bash默认情况下不会将其作为PID 1处理。

Bash happens to have a process reaper included, so running a command under bash -c can protect against zombies. Bash won't handle signals by default as PID 1 unless you trap them.

首先要了解的是 init 进程不会神奇地删除僵尸。 (正常) init 旨在在无法等待父进程退出并且僵尸四处闲逛时收割僵尸。然后,初始化进程将成为僵尸的父进程,并且可以将其清除。

The first thing to understand is an init process doesn't magically remove zombies. A (normal) init is designed to reap zombies when the parent process that failed to wait on them exits and the zombies hang around. The init process then becomes the zombies parent and they can be cleaned up.

接下来,容器是在自己的PID名称空间中运行的c组进程。停止容器后,将清理此cgroup。容器中的所有僵尸都会在停止处移除。它们无法到达主机 init

Next, a container is a cgroup of processes running in their own PID namespace. This cgroup is cleaned up when the container is stopped. Any zombies that are in a container are removed on stop. They don't reach the hosts init.

第三种使用容器的方式是不同的。大多数运行一个主要过程,而没有其他运行。如果生成了另一个进程,则通常是该主进程的子进程。因此,直到父母退出,僵尸将一直存在。然后,请参阅第2点(僵尸将在容器出口处清除)。

Third is the different ways containers are used. Most run one main process and nothing else. If there is another process spawned it is usually a child of that main process. So until the parent exits, the zombie will exist. Then see point 2 (the zombies will be cleared on container exit).

在容器中运行Node.js,Go或Java应用程序服务器往往不会严重依赖于派生或生成进程。

Running a Node.js, Go or Java app server in a container tends not to rely heavily on forking or spawning of processes.

运行像詹金斯(Jenkins)工人这样的东西,会产生大量涉及炮弹的临时工作,这可能会导致更糟糕的情况,但是这种情况是短暂的,因此请定期退出并清理

Running something like a Jenkins worker that spawns large numbers of ad hoc jobs involving shells can result in a lot worse, but is ephemeral so exits regularly and cleans up

运行同时也产生工作的Jenkins主服务器。容器可能会徘徊很长时间,并留下许多僵尸进程,而这是没有僵尸收割者就可能出现问题的工作量类型。

Running a Jenkins master that also spawns jobs. The container may hang around for a long time and leave a number of zombie processes which is the type of workload that could present a problem without a zombie reaper.

初始化过程可以提供的另一个作用是安装信号处理程序,以便从主机发送信号可以传递到容器过程中。 PID 1有点特殊,因为它需要过程监听要接收的信号。

The other role an init process can provide is to install signal handlers so signals sent from the host can be passed onto the container process. PID 1 is a bit special as it requires the process to listen for a signal for it to be received.

如果可以安装 SIGINT SIGTERM 信号您的PID 1进程中的处理程序,则init进程在这里并没有增加太多。

If you can install a SIGINT and SIGTERM signal handler in your PID 1 process then an init process doesn't add much here.

多个进程应在init进程下运行。 Docker启动时,init将管理如何启动它们。容器对于它所代表的服务实际上是运行所需的内容。当容器停止时,应如何将其传递到每个进程。您可能需要一个更传统的初始化系统,通过 s6 : //github.com/just-containers/s6-overlay rel = noreferrer> s6-overlay 为多流程管理提供了许多有用的容器功能。

Multiple processes should be run under an init process. When Docker starts, the init manages how should they be launched. What is required for the container to actually be "running" for the service it represents. When the container stops, how that should be passed onto each process. You may want a more traditional init system though, s6 via s6-overlay provides a number of useful container features for multi process management.

尤其是当进程是子进程时或更高。 CI工作者(如Jenkins)是第一个想到的例子,其中Java产生命令或shell产生其他命令。

Especially when processes are children of children or beyond. The CI worker (like Jenkins) example is the first that comes to mind where Java spawns command or shells that spawn other commands.

sleep 是一个简单的例子。 docker run busybox sleep 60 不能通过ctrl-c中断或停止,它会在默认的10秒 docker stop终止后被杀死超时。 docker run --init busybox sleep 60 可以正常工作。

sleep is a simple example of this. A docker run busybox sleep 60 can't be interrupted with ctrl-c or stopped, it will be killed after the default 10 second docker stop timeout. docker run --init busybox sleep 60 works as expected.

tini 时,开销很小,并且

有关更多详细信息,请参见。为什么要在大多数情况下不使用-init ? = https://github.com/krallin/tini/issues/8#issuecomment-146135930 rel = noreferrer>此github评论回答为什么?来自tini的创建者的问题。

For more details see this github comment which answers the "why?" question from the creator of tini.

这篇关于Docker-初始化,僵尸-为什么重要?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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