Docker 容器内的进程是什么样的?

slm*_*slm 36 virtual-machine docker

我最近多次听到关于什么是 Docker 容器的混淆,更具体地说,关于我在 Docker 容器内调用的命令和进程,内部发生了什么。

有人可以提供有关正在发生的事情的高级概述吗?

slm*_*slm 61

Docker 被扔进了虚拟化桶中,因为人们认为它以某种方式虚拟化了底层的硬件。这是一个误称,从 Docker 使用的术语中渗透出来,主要是术语容器。

然而,Docker 在虚拟化系统硬件方面并没有做任何神奇的事情。相反,它利用 Linux 内核围绕关键设施构建“围栏”的能力,这允许进程与网络、文件系统和权限(除其他外)等资源进行交互,从而产生您正在交互的错觉具有功能齐全的系统。

这是一个示例,它说明了当我们启动一个 Docker 容器然后通过调用/bin/bash.

$ docker run -it ubuntu:latest /bin/bash
root@c0c5c54062df:/#
Run Code Online (Sandbox Code Playgroud)

现在从这个容器内部,如果我们运行ps -eaf

    SS01

切换到我们登录到托管 Docker 容器的主机系统的另一个终端选项卡,我们可以看到容器“实际”占用的进程空间:

    SS02

现在,如果我们返回 Docker 选项卡并在其中启动几个进程并将它们全部设为后台,我们可以看到我们现在有几个子进程在主 Bash 进程下运行,我们最初是作为 Docker 容器启动的一部分启动的。

注意:这些进程是 4 个sleep 1000正在后台运行的命令。

    SS03

请注意在 Docker 容器内部如何为进程分配 48-51 的进程 ID (PID)。ps -eaf在他们的输出中也可以看到它们:

    SS04

然而,在下一张图片中,Docker 正在执行的大部分“魔法”都被揭示了出来。

    SS05

看看这 4 个sleep 1000进程如何实际上只是我们原始 Bash 进程的子进程?还要注意,我们原来的 Docker 容器/bin/bash实际上也是 Docker 守护进程的子进程。

现在,如果我们等待 1000+ 秒让原始sleep 1000命令完成,然后再运行 4 个新命令,然后像这样启动另一个 Docker 容器:

$ docker run -it ubuntu:latest /bin/bash
root@450a3ce77d32:/#
Run Code Online (Sandbox Code Playgroud)

主机的输出ps -eaf如下所示:

    SS06

和其他 Docker 容器一样,都将显示为 Docker 守护进程下的进程。

所以你看,Docker 真的不是虚拟化(传统意义上的),它正在围绕各种内核资源构建“围栏”,并限制给定进程 + 子进程的可见性。