使用OverlayFS存储驱动程序
预计阅读时间:18分钟
OverlayFS是一种现代的联合文件系统,与AUFS类似,但速度更快且实现更简单。Docker为OverlayFS提供了两个存储驱动程序:原始的overlay
,更新的和更稳定的overlay2
。
本主题将Linux内核驱动OverlayFS
程序称为overlay
或将Docker存储驱动器称为或overlay2
。
注意:如果使用OverlayFS,请使用
overlay2
驱动程序而不是overlay
驱动程序,因为它在inode利用率方面更为有效。要使用新的驱动程序,您需要Linux内核的版本4.0或更高版本,或者使用3.10.0-514及更高版本的RHEL或CentOS。有关
overlay
vs之间差异的更多信息overlay2
,请检查 Docker存储驱动程序。
注意:有关
fuse-overlayfs
驱动程序,请参阅无根模式文档。
先决条件
OverlayFS是推荐的存储驱动程序,如果满足以下先决条件,则受支持:
- Linux内核的版本4.0或更高版本,或使用内核的版本3.10.0-514或更高版本的RHEL或CentOS。如果使用较旧的内核,则需要使用
overlay
驱动程序(不建议这样做)。 -
在
overlay
和overlay2
驱动程序支持xfs
支持的文件系统,但只d_type=true
启用。使用
xfs_info
验证ftype
选项设置为1
。要xfs
正确格式化 文件系统,请使用标志-n ftype=1
。警告:在不支持d_type的XFS上运行现在会导致Docker跳过使用
overlay
或overlay2
驱动程序的尝试。现有安装将继续运行,但会产生错误。这是为了允许用户迁移其数据。在将来的版本中,这将是一个致命错误,它将阻止Docker启动。 - 更改存储驱动程序会使现有容器和映像在本地系统上不可访问。使用
docker save
保存你已经建立的任何图像或改变存储驱动程序之前,他们推到码头工人集线器或私人注册,这样就不需要再后来创建它们。
使用overlay
或overlay2
存储驱动程序配置Docker
强烈建议您overlay2
尽可能使用驱动程序,而不要使用overlay
驱动程序。Docker EE不支持该overlay
驱动程序。
要将Docker配置为使用overlay
存储驱动程序,您的Docker主机必须运行Linux内核的3.18版本(最好是更新的)并加载了覆盖内核模块。对于overlay2
驱动程序,您的内核版本必须为4.0或更高版本。
在执行此过程之前,您必须首先满足所有 先决条件。
以下步骤概述了如何配置overlay2
存储驱动程序。如果您需要使用旧版overlay
驱动程序,请指定它。
-
停止Docker。
$ sudo systemctl stop docker
-
将的内容复制
/var/lib/docker
到一个临时位置。$ cp -au /var/lib/docker /var/lib/docker.bk
-
如果要使用与使用的备份文件系统不同的备份文件系统
/var/lib/
,请格式化该文件系统并将其装入/var/lib/docker
。确保添加此安装座/etc/fstab
以使其永久。 -
编辑
/etc/docker/daemon.json
。如果尚不存在,请创建它。假设文件为空,请添加以下内容。{ "storage-driver": "overlay2" }
如果
daemon.json
文件包含格式错误的JSON,则Docker无法启动。 -
启动Docker。
$ sudo systemctl start docker
-
验证守护程序正在使用
overlay2
存储驱动程序。使用docker info
命令并查找Storage Driver
和Backing filesystem
。$ docker info Containers: 0 Images: 0 Storage Driver: overlay2 Backing Filesystem: xfs Supports d_type: true Native Overlay Diff: true <...>
码头工人正在使用的overlay2
存储驱动程序,并自动创建覆盖所要求的安装lowerdir
,upperdir
,merged
,和workdir
结构。
继续阅读有关OverlayFS在您的Docker容器中如何工作的详细信息,以及性能建议以及有关其与不同后备文件系统兼容性的限制的信息。
如何overlay2
驱动器的工作原理
如果您仍在使用overlay
驱动程序而不是overlay2
,请参阅
覆盖驱动程序的工作原理。
OverlayFS在单个Linux主机上分层两个目录,并将它们显示为单个目录。这些目录称为“层”,统一过程称为“联合安装”。OverlayFS指的是下层目录aslowerdir
和上层目录a upperdir
。统一视图通过其自己的目录公开merged
。
该overlay2
驱动程序本机最多支持128个较低的OverlayFS层。此功能为与图层相关的Docker命令(例如docker build
和)提供了更好的性能docker commit
,并且在备份文件系统上消耗了更少的inode。
磁盘上的图像和容器层
使用下载五层图像后docker pull ubuntu
,您可以在下看到六个目录/var/lib/docker/overlay2
。
警告:请勿直接操作其中的任何文件或目录
/var/lib/docker/
。这些文件和目录由Docker管理。
$ ls -l /var/lib/docker/overlay2
total 24
drwx------ 5 root root 4096 Jun 20 07:36 223c2864175491657d238e2664251df13b63adb8d050924fd1bfcdb278b866f7
drwx------ 3 root root 4096 Jun 20 07:36 3a36935c9df35472229c57f4a27105a136f5e4dbef0f87905b2e506e494e348b
drwx------ 5 root root 4096 Jun 20 07:36 4e9fa83caff3e8f4cc83693fa407a4a9fac9573deaf481506c102d484dd1e6a1
drwx------ 5 root root 4096 Jun 20 07:36 e8876a226237217ec61c4baf238a32992291d059fdac95ed6303bdff3f59cff5
drwx------ 5 root root 4096 Jun 20 07:36 eca1e4e1694283e001f200a667bb3cb40853cf2d1b12c29feda7422fed78afed
drwx------ 2 root root 4096 Jun 20 07:36 l
新的l
(小写L
)目录包含缩短的层标识符作为符号链接。这些标识符用于避免达到mount
命令参数的页面大小限制。
$ ls -l /var/lib/docker/overlay2/l
total 20
lrwxrwxrwx 1 root root 72 Jun 20 07:36 6Y5IM2XC7TSNIJZZFLJCS6I4I4 -> ../3a36935c9df35472229c57f4a27105a136f5e4dbef0f87905b2e506e494e348b/diff
lrwxrwxrwx 1 root root 72 Jun 20 07:36 B3WWEFKBG3PLLV737KZFIASSW7 -> ../4e9fa83caff3e8f4cc83693fa407a4a9fac9573deaf481506c102d484dd1e6a1/diff
lrwxrwxrwx 1 root root 72 Jun 20 07:36 JEYMODZYFCZFYSDABYXD5MF6YO -> ../eca1e4e1694283e001f200a667bb3cb40853cf2d1b12c29feda7422fed78afed/diff
lrwxrwxrwx 1 root root 72 Jun 20 07:36 NFYKDW6APBCCUCTOUSYDH4DXAT -> ../223c2864175491657d238e2664251df13b63adb8d050924fd1bfcdb278b866f7/diff
lrwxrwxrwx 1 root root 72 Jun 20 07:36 UL2MW33MSE3Q5VYIKBRN4ZAGQP -> ../e8876a226237217ec61c4baf238a32992291d059fdac95ed6303bdff3f59cff5/diff
最低层包含一个名为的文件link
,其中包含缩短的标识符的名称;一个目录包含的名称,diff
其中包含该层的内容。
$ ls /var/lib/docker/overlay2/3a36935c9df35472229c57f4a27105a136f5e4dbef0f87905b2e506e494e348b/
diff link
$ cat /var/lib/docker/overlay2/3a36935c9df35472229c57f4a27105a136f5e4dbef0f87905b2e506e494e348b/link
6Y5IM2XC7TSNIJZZFLJCS6I4I4
$ ls /var/lib/docker/overlay2/3a36935c9df35472229c57f4a27105a136f5e4dbef0f87905b2e506e494e348b/diff
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
最低的第二层以及每个较高的层包含一个名为的文件lower
,该文件表示其父目录,以及一个diff
包含其内容的目录。它还包含一个merged
目录,该目录包含其父层及其本身的统一内容,以及一个work
目录,供OverlayFS在内部使用。
$ ls /var/lib/docker/overlay2/223c2864175491657d238e2664251df13b63adb8d050924fd1bfcdb278b866f7
diff link lower merged work
$ cat /var/lib/docker/overlay2/223c2864175491657d238e2664251df13b63adb8d050924fd1bfcdb278b866f7/lower
l/6Y5IM2XC7TSNIJZZFLJCS6I4I4
$ ls /var/lib/docker/overlay2/223c2864175491657d238e2664251df13b63adb8d050924fd1bfcdb278b866f7/diff/
etc sbin usr var
要查看将overlay
存储驱动程序与Docker一起使用时存在的安装,请使用mount
命令。为了易于阅读,下面的输出被截断了。
$ mount | grep overlay
overlay on /var/lib/docker/overlay2/9186877cdf386d0a3b016149cf30c208f326dca307529e646afce5b3f83f5304/merged
type overlay (rw,relatime,
lowerdir=l/DJA75GUWHWG7EWICFYX54FIOVT:l/B3WWEFKBG3PLLV737KZFIASSW7:l/JEYMODZYFCZFYSDABYXD5MF6YO:l/UL2MW33MSE3Q5VYIKBRN4ZAGQP:l/NFYKDW6APBCCUCTOUSYDH4DXAT:l/6Y5IM2XC7TSNIJZZFLJCS6I4I4,
upperdir=9186877cdf386d0a3b016149cf30c208f326dca307529e646afce5b3f83f5304/diff,
workdir=9186877cdf386d0a3b016149cf30c208f326dca307529e646afce5b3f83f5304/work)
的rw
在第二行示出了overlay
安装件是可读写的。
如何overlay
驱动器的工作原理
此内容仅适用于overlay
驱动程序。Docker建议使用overlay2
不同的
驱动程序。见
该overlay2司机如何工作
的overlay2
。
OverlayFS在单个Linux主机上分层两个目录,并将它们显示为单个目录。这些目录称为“层”,统一过程称为“联合安装”。OverlayFS指的是下层目录aslowerdir
和上层目录a upperdir
。统一视图通过其自己的目录公开merged
。
下图显示了如何将Docker映像和Docker容器分层。图像层是lowerdir
,容器层是upperdir
。统一视图通过名为的目录公开,该目录merged
实际上是容器的安装点。该图显示了Docker构造如何映射到OverlayFS构造。
在图像层和容器层包含相同文件的情况下,容器层“获胜”并掩盖了图像层中相同文件的存在。
该overlay
驱动程序仅适用于两层。这意味着不能将多层图像实现为多个OverlayFS层。而是将每个图像层实现为在之下的自己的目录/var/lib/docker/overlay
。然后,将硬链接用作节省空间的方式,以引用与较低层共享的数据。硬链接的使用会导致索引节点的过度使用,这是对传统overlay
存储驱动程序的已知限制,并且可能需要备份文件系统的其他配置。有关详细信息,请参考overlayFS和Docker性能。
为了创建一个容器,overlay
驱动程序将代表图像顶层的目录与该容器的新目录结合在一起。图像的顶层lowerdir
位于叠加层中,并且是只读的。容器的新目录是,upperdir
并且是可写的。
磁盘上的图像和容器层
以下docker pull
命令显示了一个Docker主机下载一个包含五层的Docker映像。
$ docker pull ubuntu
Using default tag: latest
latest: Pulling from library/ubuntu
5ba4f30e5bea: Pull complete
9d7d19c9dc56: Pull complete
ac6ad7efd0f9: Pull complete
e7491a747824: Pull complete
a3ed95caeb02: Pull complete
Digest: sha256:46fb5d001b88ad904c5c732b086b596b92cfb4a4840a3abd0e35dbb6870585e4
Status: Downloaded newer image for ubuntu:latest
图像层
每个图像层在中都有自己的目录/var/lib/docker/overlay/
,该目录包含其内容,如下所示。图像层ID与目录ID不对应。
警告:请勿直接操作其中的任何文件或目录
/var/lib/docker/
。这些文件和目录由Docker管理。
$ ls -l /var/lib/docker/overlay/
total 20
drwx------ 3 root root 4096 Jun 20 16:11 38f3ed2eac129654acef11c32670b534670c3a06e483fce313d72e3e0a15baa8
drwx------ 3 root root 4096 Jun 20 16:11 55f1e14c361b90570df46371b20ce6d480c434981cbda5fd68c6ff61aa0a5358
drwx------ 3 root root 4096 Jun 20 16:11 824c8a961a4f5e8fe4f4243dab57c5be798e7fd195f6d88ab06aea92ba931654
drwx------ 3 root root 4096 Jun 20 16:11 ad0fe55125ebf599da124da175174a4b8c1878afe6907bf7c78570341f308461
drwx------ 3 root root 4096 Jun 20 16:11 edab9b5e5bf73f2997524eebeac1de4cf9c8b904fa8ad3ec43b3504196aa3801
图像层目录包含该层唯一的文件以及与较低层共享的数据的硬链接。这样可以有效利用磁盘空间。
$ ls -i /var/lib/docker/overlay/38f3ed2eac129654acef11c32670b534670c3a06e483fce313d72e3e0a15baa8/root/bin/ls
19793696 /var/lib/docker/overlay/38f3ed2eac129654acef11c32670b534670c3a06e483fce313d72e3e0a15baa8/root/bin/ls
$ ls -i /var/lib/docker/overlay/55f1e14c361b90570df46371b20ce6d480c434981cbda5fd68c6ff61aa0a5358/root/bin/ls
19793696 /var/lib/docker/overlay/55f1e14c361b90570df46371b20ce6d480c434981cbda5fd68c6ff61aa0a5358/root/bin/ls
容器层
容器也存在于Docker主机文件系统下的磁盘上
/var/lib/docker/overlay/
。如果使用ls -l
命令列出正在运行的容器的子目录,那么将存在三个目录和一个文件:
$ ls -l /var/lib/docker/overlay/<directory-of-running-container>
total 16
-rw-r--r-- 1 root root 64 Jun 20 16:39 lower-id
drwxr-xr-x 1 root root 4096 Jun 20 16:39 merged
drwxr-xr-x 4 root root 4096 Jun 20 16:39 upper
drwx------ 3 root root 4096 Jun 20 16:39 work
该lower-id
文件包含容器所基于的图像顶层的ID,即OverlayFS lowerdir
。
$ cat /var/lib/docker/overlay/ec444863a55a9f1ca2df72223d459c5d940a721b2288ff86a3f27be28b53be6c/lower-id
55f1e14c361b90570df46371b20ce6d480c434981cbda5fd68c6ff61aa0a5358
该upper
目录包含容器的读写层的内容,该层对应于OverlayFS upperdir
。
该merged
目录是联合安装的lowerdir
和upperdir
,该方法包括从正在运行的容器内的文件系统的图。
该work
目录在OverlayFS内部。
要查看将overlay
存储驱动程序与Docker一起使用时存在的安装,请使用mount
命令。为了易于阅读,下面的输出被截断了。
$ mount | grep overlay
overlay on /var/lib/docker/overlay/ec444863a55a.../merged
type overlay (rw,relatime,lowerdir=/var/lib/docker/overlay/55f1e14c361b.../root,
upperdir=/var/lib/docker/overlay/ec444863a55a.../upper,
workdir=/var/lib/docker/overlay/ec444863a55a.../work)
的rw
在第二行示出了overlay
安装件是可读写的。
容器如何使用overlay
或进行读取和写入overlay2
读取文件
考虑三种情况,其中容器打开文件以进行覆盖的读取访问。
-
该文件在容器层中不存在:如果容器打开文件以进行读取访问,并且该文件在容器(
upperdir
)中尚不存在,则可以从映像中读取该文件(lowerdir)
。这将导致很少的性能开销。 -
该文件仅存在于容器层中:如果容器打开文件进行读取访问,并且该文件存在于容器(
upperdir
)中,而不存在于图像(lowerdir
)中,则直接从容器中读取文件。 -
该文件存在于容器层和图像层中:如果容器打开文件以进行读取访问,并且文件存在于图像层和容器层中,则将读取容器层中文件的版本。容器层(
upperdir
)中的文件会使图像层(lowerdir
)中具有相同名称的文件模糊。
修改文件或目录
考虑在某些情况下修改了容器中的文件的情况。
-
第一次写入文件:容器第一次写入现有文件时,该文件在容器(
upperdir
)中不存在。的overlay
/overlay2
驱动器执行一个copy_up操作将文件从图像(复制lowerdir
)到所述容器(upperdir
)。然后,容器将更改写入容器层中文件的新副本。但是,OverlayFS在文件级别而不是块级别工作。这意味着所有OverlayFS copy_up操作都会复制整个文件,即使该文件非常大且只有一小部分正在被修改。这会对容器写入性能产生明显影响。但是,有两点值得注意:
-
copy_up操作仅在第一次写入给定文件时发生。随后对同一文件的写入将对已经复制到容器的文件副本进行操作。
-
OverlayFS仅适用于两层。这意味着性能应优于AUFS,因为AUFS在多层图像中搜索文件时会出现明显的延迟。此优点对驱动程序
overlay
和overlay2
驱动程序均适用 。与初始读取相比,它的overlayfs2
性能稍差overlayfs
,因为它必须遍历更多的层,但是会缓存结果,因此这只是一个小小的代价。
-
-
删除文件和目录:
-
当一个文件是一个容器内删除,一个白斑在容器中创建文件(
upperdir
)。lowerdir
不会删除图像层()中文件的版本(因为lowerdir
只读)。但是,白化文件会阻止容器使用它。 -
当一个目录由容器内删除,一个不透明目录在容器内产生(
upperdir
)。这与中断文件的工作方式相同,并且即使该目录仍然存在于映像(lowerdir
)中,也可以有效地防止该目录被访问。
-
-
重命名目录:
rename(2)
仅当源路径和目标路径都位于顶层时,才允许调用目录。否则,它将返回EXDEV
错误(“不允许跨设备链接”)。您的应用程序需要设计为处理EXDEV
并退回到“复制和取消链接”策略。
OverlayFS和Docker性能
这两个overlay2
和overlay
驱动程序比更高性能aufs
和
devicemapper
。在某些情况下,性能overlay2
可能会更好
btrfs
。但是,请注意以下详细信息。
-
页面缓存。OverlayFS支持页面缓存共享。访问同一文件的多个容器共享该文件的单个页面缓存条目。这使得
overlay
andoverlay2
驱动程序可以有效地利用内存,并且是高密度用例(例如PaaS)的不错选择。 -
copy_up。与AUFS一样,每当容器第一次写入文件时,OverlayFS都会执行复制操作。这会增加写入操作的延迟,尤其是对于大文件。但是,一旦文件被复制,对该文件的所有后续写入都将在上层进行,而无需进行进一步的复制操作。
OverlayFS
copy_up
操作比使用AUFS的相同操作要快,这是因为AUFS支持的层比OverlayFS还要多,并且如果搜索许多AUFS层,可能会产生更大的延迟。overlay2
同样支持多层,但是可以减轻缓存对性能的影响。 -
索引节点限制。使用旧版
overlay
存储驱动程序可能会导致过多的inode消耗。在Docker主机上存在大量映像和容器的情况下尤其如此。增加文件系统可用的索引节点数量的唯一方法是对其进行重新格式化。为避免遇到此问题,强烈建议您overlay2
尽可能使用。
绩效最佳实践
以下通用性能最佳实践也适用于OverlayFS。
-
使用快速存储:固态驱动器(SSD)提供比旋转磁盘更快的读写速度。
-
将卷用于繁重的写工作负载:卷可为繁重的写工作负载提供最佳和最可预测的性能。这是因为它们绕过了存储驱动程序,并且不会产生任何精简配置和写时复制所带来的潜在开销。卷还有其他好处,例如,即使没有正在运行的容器正在使用它们,它也允许您在容器之间共享数据并保留数据。
OverlayFS兼容性限制
总结OverlayFS与其他文件系统不兼容的方面:
-
open(2):OverlayFS仅实现POSIX标准的子集。这可能导致某些OverlayFS操作违反POSIX标准。一种这样的操作是复制操作。假设您的应用程序调用
fd1=open("foo", O_RDONLY)
,然后fd2=open("foo", O_RDWR)
。在这种情况下,您的应用程序期望fd1
并fd2
引用相同的文件。但是,由于在第二次调用之后发生了复制操作open(2)
,因此描述符引用了不同的文件。的fd1
继续引用该文件的图像(在lowerdir
),并且fd2
该文件引用在容器(upperdir
)。一种解决方法是对touch
导致复制操作发生的文件进行处理。所有后续open(2)
无论只读还是读写访问方式,操作都引用容器中的文件(upperdir
)。yum
除非yum-plugin-ovl
安装了软件包,否则已知会受到影响。如果该yum-plugin-ovl
软件包在您的发行版(例如6.8或7.2之前的RHEL / CentOS)中不可用,则可能需要先运行,touch /var/lib/rpm/*
然后再运行yum install
。该软件包实现了touch
上面针对引用的解决方法yum
。 -
named (2):OverlayFS不完全支持
rename(2)
系统调用。您的应用程序需要检测到它的故障并退回到“复制和取消链接”策略。