libcontainer、runc 和 nsenter bootstrap

libcontainer, runc and nsenter bootstrap

我是 docker/containers 的新手,正在尝试通过查看代码来更好地理解它。

看看 runC,看起来它使用 libcontainer 的方式与旧代码库中的 nsinit 非常相似,我试图以此为起点来了解如何使用 libcontainer 以及更深入地了解 libcontainer 的工作原理有效。

我觉得有点难以理解的一件事是 bootstrap 进程和对 nsexec 的 C 代码的调用。

我大致理解在调用应用程序 (runC/libcontainer) 可以将控制权移交给容器进程之前需要对命名空间等进行一些初始化,但我似乎无法找到一个好的步骤对此的解释。有人知道这方面的好文档吗?

我假设作为此 bootstrap 过程的一部分,C 代码将使用 "init" cmd 行标志回调到(clone/child 的)runC 中是否正确?

看起来这里有一个很好的解释:- https://groups.google.com/a/opencontainers.org/forum/#!msg/dev/CC1XH92oMrE/G1GRnBDGCAAJ

这里有一个解释。您可以阅读 this document,但老实说,它有点过时了。实际上这就是它的工作原理。

当你在 Go 程序中导入 "github.com/opencontainers/runc/libcontainer/nsenter" 时,我们有一些神奇的 __attribute__ 东西告诉 Go 编译器使 nsexec 运行 before[=27] =] 围棋 运行 时间 "boots"。实际上,这意味着每次您 运行 任何 运行C 程序时,我们的代码(在 github.com/opencontainers/runc/libcontainer/nsenter/nsexec.c 中)运行 会比 Go 运行 时间开始。

当您 运行 正常用户进程时,此代码实际上不执行任何操作,只是调用 运行C。但是,如果您的进程将成为容器初始化进程(它设置了 _LIBCONTAINER_INITPIPE 环境变量),那么它将从 _LIBCONTAINER_INITPIPE 指定的文件描述符中读取一堆配置信息并设置命名空间和其他相应的事情。所有这些设置完成后,该函数将 return 并且 Go 运行 时间将启动到 runc init 代码,然后完成容器的设置。

所有这些代码与 libcontainer 在 运行C 拆分之前的工作方式非常相似。