OverlayFS是一个与AUFS类似的现代联合(union)文件系统。与AUFS比较,OverlayFS存在如下优势:
因此,OverlayFS在Docker社区迅速普及,许多人认为这可以代替AUFS。虽然OverlayFS发展前景很好,但仍然不够成熟。因此在生产环境上部署前,请慎重考虑。
Docker的overlay存储驱动利用OverlayFS几个功能来构建和管理镜像和容器在硬盘的结构。
从1.12版本起,Docker也提供了overlay2存储驱动,它比overlay在inode的使用方面更高效。不过overlay2只能用在Linux内核 4.0和更高的版本。
本文使用OverlayFS表示文件系统,overlay/overlay2表示存储驱动。
OverLayFS在一台Linux主机维护两个目录,一个在另一个上面,并提供一个统一的视图。这些目录通常称为数据层,用来叠加它们的技术叫做联合挂载(union mount)。OverlayFS底层称为“lowerdir”,顶层称为“upperdir”。通过它自己的”merged”目录提供一个统一视图。
下图显示一个Docker镜像和Docker容器是如何分层的。镜像数据层是“lowerdir”,容器数据层是”uppperdir”。通过目录为”merged”提供一个统一视图,该目录是容器的挂载点。下图显示Docker结构是如何映射到OverlayFS结构的。
注意看容器数据层和镜像数据层能包含同样的文件。当出现此情况时,容器数据层”upperdir”的这个文件是显性的并隐藏了在镜像数据层“lowerdir”的相同文件的存在。容器挂载“merged”呈现一个统一视图。
overlay驱动只在两个层工作。这意味着多层的镜像无法实现为多个OverlayFS层。而是每个镜像数据层在自己的/var/lib/docker/overlay目录下实现多层关系。然后使用硬链接引用与更低层共享的数据。从Docker 1.10起,镜像数据层ID不再与/var/lib/docker下的目录名称相关。
要创建一个容器,overlay驱动将镜像顶层与一个新目录结合。镜像顶层是overlay的只读“lowerdir”。容器新的目录是可写的“upperdir”。
下面的docker pull命令显示Docker主机下载一个由5个层组成的Docker镜像。
每个镜像数据层在/var/lib/docker/overlay/下都有自己的对应目录。这些目录存储着每个镜像数据层的数据。
下面的命令输出显示5个存储着刚才下载的每个镜像数据层的数据的目录。不过就如你看到的镜像数据层ID没有匹配/var/lib/docker/overlay下目录的名称。
镜像数据层目录包含该层唯一的文件和与更低层共享目录的硬链接。这样可以提升空间有效利用率。
容器也在位于/var/lib/docker/overlay的Docker主机文件系统硬盘上。如果你使用ls -l命令查看与运行容器相关的目录,你会看到如下文件和目录。
这四个文件系统对象是OverlayFS的部件。lower-id文件包含容器基于的镜像的顶层ID。在OverlayFS上称为“loverdir”。
upper目录是容器的可写数据层。所有对容器的更改都是写到这个目录。
merged目录是容器的挂载点。这是镜像”loverdir”和容器“upperdir”的统一视图。任何对这个容器的修改将马上反映到这个目录。
work目录是OverlayFS执行操作时所需的目录。如执行copy_up操作。
你可以从mount命令的输出来验证这些结构。
overlay驱动仅支持单个lower OverlayFS层并且需要硬链接来实现多层的镜像,overlay2驱动原生支持多个lower OverlayFS层(最大到128层)。
因此overlay2驱动为与层相关的docker命令(如docker build和docker commit)提供了更好的性能,并且比overlay驱动消耗更少的inodes。
使用docker pull ubuntu命令下载一个5层的镜像后,你可以在/var/lib/docker/overlay2目录下看到6个目录。
l目录包含缩短的层标识符的软链接。这些缩短的标识符用于避免挂载参数的页大小限制。
最低层包含一个link文件,该文件包含缩短的标识符名称,diff目录包含其数据。
第二层包含一个lower文件,该文件包含该层下一层的位置,diff目录包含该层数据。同时也包含了merged和work目录。
运行中的容器的目录也有类似的文件和目录。注意lower列表以冒号:分隔,并且从高层到低层排序。
mount的命令输出如下:
下面是容器使用ovelay对文件进行的读取操作的三个场景。
下面是容器中更改文件的几个场景。
要配置Docker使用ovelay存储驱动,你的Docker主机必须运行在加载有overlay内核模式的3.18版本的Linux内核或更高的版本上。对于overlay2驱动,内核版本必须为4.0或更高版本。OverlayFS能用在大多数支持的Linux文件系统上。不过在生产环境中推荐使用ext4。
下面是配置Docker主机使用OverlayFS的步骤。假设你已经停止docker daemon。
1.如果docker在运行,先停止它。
2.验证内核版本和overlay内核模式是否加载
3.带overlay/overlay2存储驱动启动docker。
另外,你可以通过编辑docker的配置文件增加–storage-driver=overlay到DOCKER_OPTS行来强制docker自动启动时启用overlay/overlay2驱动。
4.验证docker是否已经是使用overlay/overlay2存储驱动。
一般来说,overlay/overlay2驱动性能应该很好。大多时候会比aufs和devicemapper要好。在一些场景下可能比btrfs还高。我们在使用overlay/overlay2存储驱动时需要注意几点与性能相关的事项。
你只能在文件系统创建时指定inodes的数量。因此你可能希望把/var/lib/docker放置在有一个自己的文件系统的不同设备,或者在文件系统创建时手动指定inodes的数量。
下面的两点性能优化同样适合于OverlayFS。