概述

Docker 是一种容器化技术,允许开发者将应用程序及其依赖打包成隔离的容器(/tag/docker-container)。在 Docker 中,init 进程负责管理容器内部运行的所有进程,并确保容器以一个良好的行为方式运行,即作为一个标准的 Unix 进程(/linux/linux-processes-guide)。发送到容器的信号,如关机信号,可以由这个进程处理。此外,它通过提供清晰且有组织的过程树,使调试容器进程变得更容易。

本文将讨论如何使用 –init 参数与 docker run 命令结合使用,以及其带来的好处。

了解容器进程管理

容器进程管理指的是管理在容器内部运行的进程的做法。对于容器化应用的稳定性和可靠性而言,适当的进程管理至关重要。通常,容器化应用由容器内多个进程组成。为了正确运行应用,这些进程需要按照特定顺序启动并管理。此外,这些进程还需要能够优雅地处理信号,如关机信号。

我们可以通过 docker run 命令创建并运行从映像生成的容器。此命令可以配置容器环境和行为的各种参数。另外,使用 docker run 命令时加上 –init 参数,我们可以有效地管理容器内的进程。init 进程可以启动并管理容器内的其他进程,并能处理信号,确保容器正确运行。

如何在 docker run 命令中使用 –init 参数

我们可以在 docker run 命令中作为选项使用 –init 参数来启动容器作为主进程(PID 1),并且启动并管理容器内部的其他所有进程。为了正确管理和处理信号,此参数确保容器作为 Unix 进程运行。带有 –init 参数运行 Docker 容器确保一个进程作为主进程运行。

为了理解 –init 参数的工作原理,我们将分别运行带和不带 –init 参数的 Docker 容器。以下是我们首先查看不带 –init 参数运行 Docker 容器的命令:

$ docker run -it --rm centos /bin/bash
Unable to find image 'centos:latest' locally
latest: Pulling from library/centos
a1d0c7532777: Pull complete 
Digest: sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f432b177
Status: Downloaded newer image for centos:latest

从输出中可以看到,容器成功运行。让我们检查容器内的进程:

$ ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 17:30 pts/0    00:00:00 /bin/bash
root        14     1  0 17:35 pts/0    00:00:00 ps -ef

如上输出所示,PID 1 由 /bin/bash 开始。现在,让我们使用 –init 参数运行相同的容器:

$ docker run -it --init --rm centos /bin/bash
Unable to find image 'centos:latest' locally
...
Status: Downloaded newer image for centos:latest

上述命令基于 centos 映像创建了一个容器,并启用了 –init 参数。接下来,让我们查看容器内部运行的所有进程:

$  ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 17:38 pts/0    00:00:00 /sbin/docker-init -- /bin/bash
root         7     1  0 17:38 pts/0    00:00:00 /bin/bash
root        16     7  0 17:40 pts/0    00:00:00 ps -ef

在上述输出中,可以看到 PID 1 使用 /sbin/docker-init/bin/bash 参数启动。由于在容器中使用了 –init 参数,/sbin/docker-init 控制容器内部的所有进程。因此,如果此进程失败,容器将停止运行。容器的 init 进程管理容器内子进程。

–init 参数的益处

Docker 中的 –init 参数是一个有用的选项,提供了多种优势,包括改进的进程管理、适当的信号处理、降低僵尸进程风险以及增强安全性。在生产环境中使用它既简单又方便。向 docker run 命令添加 –init 参数确保我们的容器得到妥善管理和保护。

如果我们没有正确清理子进程,则当容器中的进程终止时,它可能会成为僵尸进程。因此,容器中的 init 进程确保它正确清理所有进程,从而降低容器中僵尸进程的风险。此外,容器的 init 进程作为非 root 用户运行,增加了额外的安全层。结果是,恶意行为者无法利用潜在的安全漏洞。

总结

在这篇文章中,我们学习了如何在 docker run 命令中使用 –init 参数。首先,我们探讨了 Docker 中的容器进程管理。然后,我们探讨了运行带和不带 –init 参数的容器的命令。最后,我们也研究了在 Docker 中使用 –init 参数带来的好处。