为什么使用 chroot 取消共享不会像 /proc 那样隔离 /dev?

为什么使用 chroot 取消共享不会像 /proc 那样隔离 /dev?

我正在关注Kevin Boone 从头开始​​的容器

我在 /mnt/container/ 下有 alpine 迷你根文件系统

我对挂载如何与 chroot 和 unshare 一起工作有点困惑。

如果我们取消分享,则无需取消分享

chroot /mnt/container /bin/sh -l

我们在主机上得到一个带有“/”(根)的容器(某种)/mnt/container

如果我们运行以下命令,则在容器内;

mount -t proc proc /proc >& /dev/null
mount -t devtmpfs dev /dev/ >& /dev/null

我们看到我们已经挂载了主机系统的 /proc 和 /dev,因此我们可以看到主机上正在运行的进程,ps -ef并且也可以在 /dev 中创建一个文件,该文件将在主机上创建。这是预期的,因为仍然没有命名空间隔离。

为了创建命名空间隔离,我们这样做;

unshare -mpfu chroot /mnt/container /bin/sh -l

然后在容器内运行

mount -t proc proc /proc >& /dev/null
mount -t devtmpfs dev /dev/ >& /dev/null

这次ps -ef将只显示容器内的两个进程。我的理解(如果我错了,请纠正我)是mount -t proc proc /proc >& /dev/null没有挂载主机系统的 /proc,而是创建了一个 procfs 类型的新目录 /proc,因此隔离。

但是,这就是问题所在,容器内的 /dev 仍然与主机的 /dev 相同。我仍然可以在 /dev 中创建文件,它会显示在主机上。

为什么/dev不像/proc那样被隔离?

答案1

devtmpfs没有命名空间(参见基于它的shmem上下文初始化),并且它也不适合在用户命名空间内使用(请参阅devtmpfs 对于命名空间来说有什么特殊之处吗?权限问题)。

人们曾尝试改变这一点,例如Seth Forshee 提交的 2014 年补丁系列。但内核维护者,特别是 Greg KH,认为devtmpfs在主机和用户命名空间之间共享一个实例,甚至是一个命名空间感知的实例,没有用

将命名空间 devtmpfs 从 Loopdevfs 讨论中分离出来可能是明智的。然而,为了捍卫命名空间的 devtmpfs,我想说,对于用户空间来说,在每次容器启动时,将设备中的全局 devtmpfs 绑定挂载到私有 tmpfs(出于 systemd 的考虑,它不能仅仅位于容器 rootfs 上) ,似乎值得避免。

我认为必须在容器中选择您想要的设备节点是一件好事。事实上,无论如何,你都必须在内核中做同样的事情,用户空间在这里做出决定有什么问题,特别是因为它比内核更清楚地知道自己想要做什么。

基本上,如果您需要/dev在用户命名空间内,则应该手动填充它。

/proc 如何与 PID 命名空间交互?解释了该/proc行为。

答案2

Kevin Boone 的容器技术并不等同于 Docker 或虚拟机可能实现的容器化技术。

在 Linux 上,/dev 和 /proc 不是文件系统目录。它们是操作系统的特殊实体,恰好可以作为文件系统(如对象)访问。

许多命令需要检查这些实体的内容。

名为“dev”和“proc”的目录可以在任何地方创建,但它们可能看起来只是真正的 /dev 和 /proc 伪文件系统目录的“overalys”。

相关内容