libcontainer,runc和nsenter bootstrap

我对docker/容器相当新,并试图通过查看代码来更好地理解它。

看看runC,它看起来像使用libcontainer很像旧的代码库中的nsinit,我试图用它作为了解如何使用libcontainer以及深入了解libcontainer如何工作的一个起点。

其中一个我觉得有点棘手的东西是引导程序和调用nsexec的C代码。

我广泛地理解,在调用应用程序(runC / libcontainer)可以将控制交给容器进程之前,需要对名称空间等进行一些初始化,但似乎无法find一个好的一步一步的解释。 有没有人知道这方面的好文档?

我是否正确地认为,作为这个引导过程的一部分,C代码会用“init”cmd行标志调用回runC(的clone / child)?

这是一个解释。 你可以阅读这个文档,但说实话,这有点过时了。 有效的是这是如何工作的。

当您在Go程序中导入"github.com/opencontainers/runc/libcontainer/nsenter"时,我们有一些神奇的__attribute__东西,告诉Go编译器在Go运行时“启动” 之前运行nsexec。 实际上,这意味着每次运行任何runC程序时,我们的代码(在github.com/opencontainers/runc/libcontainer/nsenter/nsexec.c )都会在Go运行时开始之前运行。

当你运行一个普通的用户进程时,这段代码实际上并没有做任何事情,只是调用了runC。 但是,如果你的进程是容器初始化进程(它具有_LIBCONTAINER_INITPIPE环境variables集),那么它将从_LIBCONTAINER_INITPIPE指定的_LIBCONTAINER_INITPIPE读取一堆configuration信息,并相应地设置命名空间和其他东西。 完成所有这些设置后,函数将返回,Go运行时将引导到runc init代码,然后完成容器的设置。

所有这些代码都与在runC拆分之前libcontainer如何工作非常相似。