Docker容器实战(七) - Docker存储隔离原理?(下)

联合文件系统(Union File System,UnionFS)

最主要的功能是将多个不同位置的目录联合挂载(union mount)到同一目录。


容器有了进程隔离(视野隔离),CGroup资源隔离,还缺少隔离的文件系统,可认为Unionfs是容器房间里的地板,将多个文件目录挂载给某个容器进程,供其独享。


为了解决该问题,Docker在Ubuntu发行版上默认使用AuFS(Advanced Union FS)支持Docker镜像的Layer,也支持其他UnionFS的版本。


比如,现在有两个目录A、B,分别有俩文件:


$ tree
.
├── A
│  ├── a
│  └── x
└── B
  ├── b
  └── x

然后使用联合挂载,将这俩目录挂载到一个公共目录C上:

$ mkdir C
$ mount -t aufs -o dirs=./A:./B none ./C


再查看目录C的内容,就能看到目录A和B下的文件被合并到了一起:

$ tree ./C
./C
├── a
├── b
└── x

可见,在这个合并后的目录C里,有a、b、x三个文件,并且x文件只有一份。这就是“合并”。如果在目录C里对a、b、x文件做修改,这些修改也会在对应的目录A、B中生效。


AuFS全称Another UnionFS,后改名为Alternative UnionFS,再后来干脆改名叫作Advance UnionFS,从这些名字中你应该能看出这样两个事实:

  • 对Linux原生UnionFS的重写和改进
  • Linus一直不让AuFS进入Linux内核主干,只能在Ubuntu和Debian这些发行版上使用


对于AuFS来说,它最关键的目录结构在/var/lib/docker路径下的diff目录:

/var/lib/docker/aufs/diff/<layer_id>

不同的是,Docker镜像使用的rootfs,往往由多个“层”组成:

docker image inspect ubuntu:latest
...
     "RootFS": {
      "Type": "layers",
      "Layers": [
        "sha256:f49017d4d5ce9c0f544c...",
        "sha256:8f2b771487e9d6354080...",
        "sha256:ccd4d61916aaa2159429...",
        "sha256:c01d74f99de40e097c73...",
        "sha256:268a067217b5fe78e000..."
      ]
    }

可以看到,这个Ubuntu镜像,实际上由五个层组成。

这五个层就是五个增量rootfs,每一层都是Ubuntu操作系统文件与目录的一部分;而在使用镜像时,Docker会把这些增量联合挂载在一个统一的挂载点上(等价于前面例子里的“/C”目录)。


这个挂载点就是/var/lib/docker/aufs/mnt/,比如:

/var/lib/docker/aufs/mnt/6e3be5d2ecccae7cc0fcfa2a2f5c89dc21ee30e166be823ceaeba15dce645b3e

不出意外的,这个目录里面正是一个完整的Ubuntu操作系统:

$ ls /var/lib/docker/aufs/mnt/6e3be5d2ecccae7cc0fcfa2a2f5c89dc21ee30e166be823ceaeba15dce645b3e
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var

那么,前面提到的五个镜像层,又是如何被联合挂载成这样一个完整的Ubuntu文件系统的呢?

这个信息记录在AuFS的系统目录/sys/fs/aufs下面。

首先,通过查看AuFS的挂载信息,我们可以找到这个目录对应的AuFS的内部ID(也叫:si):


$ cat /proc/mounts| grep aufs
none /var/lib/docker/aufs/mnt/6e3be5d2ecccae7cc0fc... aufs rw,relatime,si=972c6d361e6b32ba,dio,dirperm1 0 0

即,si=972c6d361e6b32ba。

然后使用这个ID,你就可以在/sys/fs/aufs下查看被联合挂载在一起的各个层的信息:

$ cat /sys/fs/aufs/si_972c6d361e6b32ba/br[0-9]*
/var/lib/docker/aufs/diff/6e3be5d2ecccae7cc...=rw
/var/lib/docker/aufs/diff/6e3be5d2ecccae7cc...-init=ro+wh
/var/lib/docker/aufs/diff/32e8e20064858c0f2...=ro+wh
/var/lib/docker/aufs/diff/2b8858809bce62e62...=ro+wh
/var/lib/docker/aufs/diff/20707dce8efc0d267...=ro+wh
/var/lib/docker/aufs/diff/72b0744e06247c7d0...=ro+wh
/var/lib/docker/aufs/diff/a524a729adadedb90...=ro+wh

从这些信息里,我们可以看到,镜像的层都放置在/var/lib/docker/aufs/diff目录下,然后被联合挂载在/var/lib/docker/aufs/mnt里面。

上一篇:京东测试微信一级入口 618一起抢微信红包


下一篇:C#中无法将文件”obj\debug\XXX.dll复制到“bin\Debug\XXX.dll” 拒绝访问