AUFS 的英文全称为 Advanced Mult-Layered Unification Filesystem, 曾经是 Another Mult-Layered Unification Filesystem, 显然, 现在的内涵规格更高些. 说明: 本文的演示环境为 Ubuntu 16.04.
Union File System
Union File System, 简称 UnionFS, 是一种为 Linux,FreeBSD 和 NetBSD 操作系统设计的, 把其它文件系统联合到一个联合挂载点的文件系统服务. 它使用 branch 把不同文件系统的文件和目录 "透明地" 覆盖, 形成一个单一一致的文件系统. 这些 branch 或者是 read-only 的, 或者是 read-write 的, 所以当对这个虚拟后的联合文件系统进行写操作的时候, 系统是真正写到了一个新的文件中. 看起来这个虚拟后的联合文件系统是可以对任何文件进行操作的, 但是其实它并没有改变原来的文件. 这是因为 Union File System 用到了一个重要的资源管理技术: 写时复制.
写时复制 (copy-on-write, 常被简写为 CoW), 也叫隐式共享, 是一种提高资源使用效率的资源管理技术. 它的思想是: 如果一个资源是重复的, 在没有对资源做出修改前, 并不需要立即复制出一个新的资源实例, 这个资源被不同的所有者共享使用. 当任何一个所有者要对该资源做出修改时, 复制出一个新的资源实例给该所有者进行修改, 修改后的资源成为其所有者的私有资源. 通过这种资源共享的方式, 可以显著地减少复制相同资源带来的消耗, 但是这样做也会在进行资源的修改时增加一部分开销.
创建 AUFS
我们可以通过 mount 命令手动创建 AUFS, 接下来我们就用这种方式来演示 AUFS 的主要特征.
创建演示用的目录和文件
先创建一个名称为 aufs 的文件夹用作实验目录:
$ mkdir aufs
然后在 aufs 中创建名称为 mnt 的目录作为文件系统的挂载点:
$ mkdir aufs/mnt
接下来在 aufs 目录下创建 container-layer 文件夹 (模拟容器的读写层), 并且在文件夹中创建文件 container-layer.txt, 文件的内容初始化为 "I am container layer":
- $ mkdir aufs/container-layer
- $ echo "I am container layer"> aufs/container-layer/container-layer.txt
最后在 aufs 目录下创建三个文件夹 image-layer1,image-layer2,image-layer3(用它们来模拟容器的镜像层). 在这三个文件夹中分别创建文件, 并初始化为对应的内容:
- $ mkdir aufs/{
- image-layer1,image-layer2,image-layer3
- }
- $ echo "I am image layer 1"> aufs/image-layer1/image-layer1.txt
- $ echo "I am image layer 2"> aufs/image-layer2/image-layer2.txt
- $ echo "I am image layer 3"> aufs/image-layer3/image-layer3.txt
准备的目录和文件结构如下图所示:
创建 AUFS 文件系统
mount 是一个非常强大的命令, 我们可以用它来创建 AUFS 文件系统. 下面的命令把 container-layer,image-layer1,image-layer2,image-layer3 以 AUFS 的方式挂载到刚才创建的 mnt 目录下:
- $ cd aufs
- $ sudo mount -t aufs -o dirs=./container-layer:./image-layer1:./image-layer2:./image-layer3 none ./mnt
挂载完成后可以看到 mnt 目录下的文件结构为:
注意, 在 mount 命令中我们没有指定要挂载的 4 个文件夹的权限信息, 其默认行为是: dirs 指定的左边起第一个目录是 read-write 权限, 后续目录都是 read-only 权限. 我们可以通过下面的方式查看详情:
其中的 si_99b90cdd124201eb 目录是系统为 mnt 这个挂载点创建的, 从上图中我们可以清楚的看到各个目录的挂载权限.
验证写时复制
下面让我们向 mnt/image-layer2.txt 文件中写入些数据, 看看会发生什么变化?
$ echo "I changed mnt/image-layer2.txt">> mnt/image-layer2.txt
查看 mnt/image-layer2.txt 的内容, 发现已经变化了:
- I am image layer 2
- I changed mnt/image-layer2.txt
再去看看 image-layer2/image-layer2.txt, 发现它的内容没有变化, 还是:
I am image layer 2
原因在哪里呢? 去 container-layer 目录下看看:
这里多了一个 image-layer2.txt 文件, 其内容如下:
原来, 当尝试向 mnt/image-layer2.txt 中写入文件时, 系统首先在 mnt 目录下查找名为 image-layer2.txt 的文件, 将其拷贝到 read-write 层的 container-layer 目录中, 接着对 container-layer 目录中的 image-layer2.txt 的文件进行写操作. 这个过程也就是 AUFS 的实际工作原理.
至此, 我们完成了一个简单的 AUFS demo. 可以看出 AUFS 的原理并不是很复杂, 但是当与容器技术相结合后, 就展示出来超强的魅力, 并成为初代 docker 默认的存储驱动. 虽然当前 docker 默认的存储驱动已经演进到了 overlay2, 但是学习 AUFS 依然可以帮助我们深入理解 docker 中的文件系统.
参考:
维基百科 AUFS https://en.wikipedia.org/wiki/Aufs
- Linux AuFS Examples https://www.thegeekstuff.com/2013/05/linux-aufs/
- AUFS Source Code http://aufs.sourceforge.net/
- Docker Use the AUFS storage driver
《自己动手写 docker》
来源: https://www.cnblogs.com/sparkdev/p/11237347.html