我正在尝试在 Ubuntu 中使用挂载命名空间。到目前为止,我可以使用以下命令创建一个空的挂载命名空间:
# mkdir test
# unshare --mount
# mount none test -t tmpfs
# cd test
# pivot_root . .
# cd / <--- test becomes /
当我检查LXC
Ubuntu 容器时,该mount
命令显示以下内容:
由于挂载命名空间最初获取了挂载点的副本,因此我假设/dev/sda1
容器内部是全局的/dev/sda1
(因为/dev/sda1
一旦启动,容器内部就没有了),但/
容器内部的内容对应于它的 rootfs。熟悉 LXC 的人能否解释一下 LXCpivot_root
在容器内执行之前会执行哪些挂载操作?
要查看 LXC 实际做了什么,让我们创建一个新容器并通过以下方式跟踪其启动过程
strace(1)
:生成的跟踪被写入lxclog文件,这里是它最相关的部分(省略号由我添加,省略了一些不重要的调用):
首先,一个新进程(PID 14677)由
lxc-start
(PID 14671)使用产生clone(2)
并被放置在新的挂载命名空间(CLONE_NEWNS
标志)中。然后在这个新的挂载命名空间中,容器的根文件系统(/var/lib/lxc/testcontainer/rootfs)绑定(MS_BIND
标志)到/usr/lib64/lxc/rootfs,然后成为新的根。最后,当容器初始化完成后,进程 14677 成为容器的init
.这里重要的是容器的挂载命名空间的根目录是属于主机根 FS的目录的绑定挂载。这就是为什么容器的根挂载仍然有/dev/sda1作为
mount(8)
输出中的源。但是,还有一个没有显示的差异mount(8)
- 要查看它,请尝试findmnt(8)
在容器内:findmnt(8)
将此与主机系统的输出进行比较:请注意,源是相同的,但在容器内您还可以看到绑定挂载的源目录。