文章目录
AUFS
AUFS是一个联合文件系统。aufs存储驱动程序以前是默认的存储驱动程序,用于管理Ubuntu的Docker上的镜像和层,以及在Stretch之前的Debian版本。如果Linux内核是4.0或更高版本,并且使用Docker Engine - Community,那么可以考虑使用更新的overlay2,它与aufs存储驱动程序相比具有潜在的性能优势。
前提条件
-
对于Docker Engine - Community,在Ubuntu上支持AUFS,在Stretch之前支持Debian版本。
-
对于Docker EE, Ubuntu支持AUFS。
-
如果使用Ubuntu,需要安装额外的包来将AUFS模块添加到内核中。如果不安装这些包,需要在ubuntu14.04上使用devicemapper(这是不推荐的),或者在ubuntu16.04或更高版本上使用overlay2,也是受支持的。
-
AUFS不能使用以下备份文件系统:AUFS、btrfs或ecryptfs。这意味着包含/var/lib/docker/aufs的文件系统不能是这些文件系统类型之一。
用aufs存储驱动程序配置Docker
如果在启动Docker时将AUFS驱动程序加载到内核中,并且未配置其他存储驱动程序,则Docker默认使用它。
- 使用以下命令来验证您的内核是否支持AUFS。
grep aufs /proc/filesystems nodev aufs
- 检查Docker使用哪个存储驱动程序。
docker info <truncated output> Storage Driver: aufs Root Dir: /var/lib/docker/aufs Backing Filesystem: extfs Dirs: 0 Dirperm1 Supported: true <truncated output>
aufs存储驱动程序如何工作
AUFS是一个联合文件系统
,这意味着它在单个Linux主机上分层多个目录,并将它们显示为单个目录。这些目录在AUFS术语中称为分支,在Docker术语中称为层。
统一的过程称为联合挂载。
下图显示了基于 ubuntu:latest 镜像的Docker容器。
每个镜像层和容器层在Docker主机上均表示为图中的子目录/var/lib/docker/。联合挂载提供了所有层的统一视图。目录名称并不直接对应于镜像层本身的ID。
AUFS使用写时复制(CoW)策略来最大化存储效率并最小化开销
。
示例:映像和磁盘上的容器构造
下面的docker pull命令显示了一个docker主机正在下载一个包含四层的docker镜像。
镜像层
所有镜像层和容器层的信息都存储在 /var/lib/docker/aufs/ 的子目录中。
diff/
:每一层的内容,每一层都存储在一个单独的子目录中。layers/
:关于镜像层如何堆积的元数据。此目录包含Docker主机上每个镜像或容器层的一个文件。每个文件包含堆栈中它下面所有层的id(它的父层)。mnt/
:挂载点,每个镜像或容器层一个,用于组装和挂载容器的统一文件系统。对于只读的镜像,这些目录总是空的。
容器层
如果容器正在运行,则/var/lib/docker/aufs/更改内容的方式如下:
diff/
:可写容器层中引入的差异,如新文件或修改的文件。layers/
:关于可写容器层的父层的元数据。mnt/
:每个运行容器的统一文件系统的挂载点,与容器内的挂载点完全相同。
容器如何使用aufs进行读写操作
读取文件
考虑三种情况,其中容器使用aufs打开文件进行读访问。
该文件在容器层中不存在:
存储驱动程序在镜像层中搜索该文件,从容器层下面的层开始。从找到它的那一层读取。该文件仅存在于容器层中:
文件存在于容器层中,则从该层读取该文件。该文件同时存在于容器层和镜像层:
如果容器打开一个文件进行读取访问,并且该文件存在于容器层和一个或多个镜像层中,则从容器层读取该文件。容器层中的文件掩盖了在镜像层中具有相同名称的文件。
修改文件或目录
考虑容器中的文件被修改的一些场景。
-
第一次写入文件:
容器第一次写入现有文件时,该文件在容器中不存在。aufs驱动程序执行copy_up操作,将文件从存在它的镜像层复制到可写的容器层。然后容器将更改写入容器层中文件的新副本。
但是,AUFS是在文件级别而不是块级别工作的。这意味着所有的copy_up操作都会复制整个文件,即使文件非常大,并且只有一小部分被修改。 -
删除文件和目录 :
- 当在容器中删除文件时,将在容器层中创建一个whiteout文件。镜像层中的文件版本没有被删除(因为镜像层是只读的)。但是,whiteout文件阻止容器使用它。
- 当在容器中删除目录时,将在容器层中创建一个不透明的文件。这与whiteout文件的工作方式相同,可以有效地阻止目录被访问,即使它仍然存在于镜像层中。
重命名目录:
AUFS不完全支持为目录调用rename(2)。它返回EXDEV(“不允许跨设备链接”),即使源路径和目标路径位于同一AUFS层,除非目录没有子目录。应用程序需要设计成处理EXDEV并退回到“复制并断开链接”策略。
AUFS和Docker性能
总结已经提到的一些与性能相关的方面:
-
AUFS存储驱动程序的性能不如overlay2驱动程序,但是对于容器密度很重要的PaaS和其他类似用例来说,它是一个不错的选择。这是因为AUFS在多个正在运行的容器之间有效地共享镜像,从而缩短了容器的启动时间,并减少了磁盘空间的使用。
-
AUFS如何在镜像层和容器之间共享文件的基本机制非常有效地使用了页面缓存。
-
AUFS存储驱动程序可能会在容器写入性能中引入较大的延迟。这是因为容器第一次写入任何文件时,都需要找到该文件并将其复制到容器的顶层可写层中。当这些文件存在于许多镜像层下面并且文件本身很大时,这些等待时间会增加并且变得更加复杂。