了解挂载命名空间在 Linux 中的工作原理

Lan*_*ard 5 linux filesystems mount namespace virtual-file-system

我正在阅读有关挂载命名空间的信息,请参阅:

在挂载命名空间中,您可以挂载和卸载文件系统,而不会影响主机文件系统。因此,您可以安装一组完全不同的设备(通常更少)。

我试图了解linux namespaces和 LXC 等,但我不太明白上面的陈述是什么意思。

我想了解的是容器 (1) 如何拥有这样的文件:

/foo/a.txt
/foo/bar/b.txt
Run Code Online (Sandbox Code Playgroud)

另一个容器 (2) 可以有这样的文件:

/foo/a.txt
/foo/x.txt
/foo/bar/b.txt
/foo/bar/y.txt
Run Code Online (Sandbox Code Playgroud)

Where/foo/a.txt/foo/bar/b.txton 容器 (1) 和 (2) 是相同的路径,但它们可能具有不同的内容:

# container (1)
cat /foo/a.txt #=> Hello from (1)

# container (2)
cat /foo/a.txt #=> Hello from (2)
Run Code Online (Sandbox Code Playgroud)

这意味着物理系统上的文件(我对此一无所知)以一种方式存储,可能分散在各处。但是操作系统中有一个“虚拟”文件的集中式数据库,如下所示:

db:
  container1:
    foo:
      a.txt: Hello from a from (1)
      bar:
        b.txt: Hello from b from (1)
  container2:
    foo:
      a.txt: Hello from a from (2)
      x.txt: Hello from x from (2)
      bar:
        b.txt: Hello from b from (2)
        y.txt: Hello from y from (2)
Run Code Online (Sandbox Code Playgroud)

然后是物理文件的另一个操作系统数据库,它可能如下所示:

drive1:
  dir1:
    foo:
      a.txt
      bar:
        b.txt
  dir2:
    foo:
      a.txt
      x.txt
      bar:
        b.txt
        y.txt
Run Code Online (Sandbox Code Playgroud)

因此,当您在容器中创建文件时,实际上是在创建 2 个新记录:

  1. 1 为驱动器级物理文件映射
  2. 1 为容器级虚拟文件映射

这就是我想象的工作方式。这就是我如何看到有一种方法可以(1)向用户(在 LXC 容器或 cgroup(我不太了解)中)展示一个完整的“文件系统”,在其中他们可以(2) 创建自己的完全可定制的目录结构(可能具有与完全不同的虚拟文件系统相同的命名文件/目录/路径),这样 (3) 来自多个不同虚拟文件系统/容器的文件不会互相覆盖。

想知道这是否是它的工作原理,或者如果不是,它实际上是如何工作的(或它是如何工作的概述)。

sou*_*edi 7

挂载命名空间在挂载文件系统的排列上有所不同。

这是非常灵活的,因为挂载可以是文件系统内子目录的绑定挂载。

# unshare --mount  # run a shell in a new mount namespace

# mount --bind /usr/bin/ /mnt/
# ls /mnt/cp
/mnt/cp

# exit  # exit the shell, and hence the mount namespace

# ls /mnt/cp
ls: cannot access '/mnt/cp': No such file or directory
Run Code Online (Sandbox Code Playgroud)

您可以使用该命令列出当前的安装集findmnt

在完整的容器中,根挂载将被替换,并且您可以使用完全独立的挂载树。这涉及到一些额外的细节,比如pivot_root()系统调用。您可能不需要确切地知道如何做到这一点。此处提供了一些详细信息:如何使用 Linux 命名空间执行 chroot?