使用AUFS存储驱动程序
预计阅读时间:8分钟
AUFS是联合文件系统。在aufs
存储驱动程序是以前用于在多克尔管理图像和层的Ubuntu的默认存储驱动器,以及适用于Debian之前的版本弹力。如果您的Linux内核是4.0或更高版本,并且您使用的是Docker Engine-Community,请考虑使用较新的
overlay2,它比aufs
存储驱动程序具有潜在的性能优势。
笔记
在某些发行版和Docker版本中不支持AUFS。有关支持的平台的更多信息,请参见 先决条件。
先决条件
- 对于Docker Engine-Community,在Ubuntu和Stretch之前的Debian版本中支持AUFS。
- 对于Docker EE,Ubuntu支持AUFS。
- 如果使用Ubuntu,则需要将AUFS模块添加到内核。如果不安装这些软件包,则需要使用
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(在这种情况下,将使用其他默认驱动程序),或者已将Docker显式配置为使用其他驱动程序。检查
/etc/docker/daemon.json
或的输出ps auxw | grep dockerd
以查看Docker是否已使用该--storage-driver
标志启动。
aufs
存储驱动程序如何工作
AUFS是一个联合文件系统,这意味着它将在一个Linux主机上分层多个目录,并将它们显示为一个目录。这些目录在AUFS术语中称为分支,在Docker术语中称为层。
统一过程称为联合安装。
下图显示了基于该ubuntu:latest
映像的Docker容器。
每个映像层和容器层在Docker主机上均表示为内的子目录/var/lib/docker/
。联合安装提供了所有层的统一视图。目录名称并不直接对应于图层本身的ID。
AUFS使用写时复制(CoW)策略来最大化存储效率并最小化开销。
示例:映像和容器在磁盘上的构造
以下docker pull
命令显示了一个Docker主机下载一个包含五层的Docker映像。
$ docker pull ubuntu
Using default tag: latest
latest: Pulling from library/ubuntu
b6f892c0043b: Pull complete
55010f332b04: Pull complete
2955fb827c94: Pull complete
3deef3fcbd30: Pull complete
cf9722e506aa: Pull complete
Digest: sha256:382452f82a8bbd34443b2c727650af46aced0f94a44463c62a9848133ecb1aa8
Status: Downloaded newer image for ubuntu:latest
图像层
警告:请勿直接操作其中的任何文件或目录
/var/lib/docker/
。这些文件和目录由Docker管理。
有关图像和容器层的所有信息都存储在的子目录中/var/lib/docker/aufs/
。
diff/
:每个图层的内容,每个图层的内容存储在单独的子目录中layers/
:有关如何堆叠图像层的元数据。该目录为Docker主机上的每个图像或容器层包含一个文件。每个文件都包含堆栈中其下所有层(其父级)的ID。mnt/
:安装点,每个映像或容器层一个,用于组装和安装容器的统一文件系统。对于只读图像,这些目录始终为空。
容器层
如果容器正在运行,则/var/lib/docker/aufs/
更改内容的方式如下:
diff/
:可写容器层中引入的差异,例如新文件或修改过的文件。layers/
:有关可写容器层的父层的元数据。mnt/
:每个正在运行的容器的统一文件系统的安装点,与从容器内部出现的安装点完全相同。
容器如何读写 aufs
读取文件
考虑三种情况,其中容器打开文件以通过aufs进行读取访问。
-
该文件在容器层中不存在:如果容器打开文件进行读取访问,并且该文件在容器层中尚不存在,则存储驱动程序将在图像层中搜索文件,从图像层正下方的层开始容器层。从找到它的层读取它。
-
该文件仅存在于容器层中:如果容器打开文件以进行读取访问,并且该文件存在于容器层中,则从那里进行读取。
-
该文件同时存在于容器层和图像层中:如果容器打开文件以进行读取访问,并且该文件存在于容器层和一个或多个图像层中,则从容器层中读取文件。容器层中的文件会使图像层中具有相同名称的文件模糊。
修改文件或目录
考虑在某些情况下修改了容器中的文件的情况。
-
第一次写入文件:容器第一次写入现有文件时,该文件在容器(
upperdir
)中不存在。的aufs
驾驶员进行copy_up操作将文件从那里它存在到可写的容器层中的图像层复制。然后,容器将更改写入容器层中文件的新副本。但是,AUFS在文件级别而不是块级别工作。这意味着所有copy_up操作都将复制整个文件,即使该文件非常大且只有一小部分正在被修改。这会对容器写入性能产生明显影响。在具有多层的图像中搜索文件时,AUFS可能会出现明显的延迟。但是,值得注意的是,copy_up操作仅在第一次写入给定文件时发生。随后对同一文件的写入将对已经复制到容器的文件副本进行操作。
-
删除文件和目录:
-
当一个文件是一个容器内删除,一个白斑在容器层中创建的文件。不会删除图像层中文件的版本(因为图像层是只读的)。但是,白化文件会阻止容器使用它。
-
当在容器内删除目录时,将在容器层中创建一个不透明文件。这与停电文件的工作方式相同,并且即使该目录仍然存在于图像层中,也可以有效地防止该目录被访问。
-
-
重命名目录:
rename(2)
AUFS不完全支持调用目录。EXDEV
即使源路径和目标路径都在同一AUFS层上,它也会返回(“不允许跨设备链接”),除非目录中没有子目录。您的应用程序需要设计为处理EXDEV
并退回到“复制和取消链接”策略。
AUFS和Docker性能
总结已经提到的一些与性能相关的方面:
-
AUFS存储驱动程序的性能不如该
overlay2
驱动程序,但是对于容器密度很重要的PaaS和其他类似用例来说,它是一个不错的选择。这是因为AUFS可以在多个运行中的容器之间有效地共享映像,从而缩短了容器的启动时间,并减少了磁盘空间的使用。 -
AUFS如何在图像层和容器之间共享文件的基本机制非常有效地使用了页面缓存。
-
AUFS存储驱动程序可以将显着的延迟引入容器写入性能。这是因为容器第一次写入任何文件时,都需要找到该文件并将其复制到容器的顶层可写层中。当这些文件存在于许多图像层下面并且文件本身很大时,这些等待时间会增加并且变得更加复杂。
绩效最佳实践
以下通用性能最佳实践也适用于AUFS。
-
固态设备(SSD)的读取和写入速度比旋转磁盘快。
-
将卷用于繁重的写工作负载:卷可为繁重的写工作负载提供最佳和最可预测的性能。这是因为它们绕过了存储驱动程序,并且不会产生任何精简配置和写时复制所带来的潜在开销。卷还有其他好处,例如,允许您在容器之间共享数据,并且即使没有正在运行的容器正在使用它们也可以持久保存数据。