docker系列—聊一聊存储驱动OverlayFS

OverlayFS

OverlayFS是一种现代的联合文件系统,与AUFS类似,但是速度更快且实现更简单。Docker为OverlayFS提供了两个存储驱动程序:原始的overlay,更新的和更稳定的overlay2

前提条件

  • overlay2驱动程序支持Docker Engine - Community和Docker EE 17.06.02-ee5及以上,是推荐的存储驱动程序。
  • Linux内核4.0或更高版本,或使用内核3.10.0-514或更高版本的RHEL或CentOS。如果使用一个旧的内核,需要使用overlay驱动程序,这是不推荐的。
  • xfs支持的文件系统支持overlay和overlay2驱动程序,但只有启用了d_type=true。
    使用xfs_info验证ftype选项是否设置为1。要正确格式化xfs文件系统,使用-n ftype=1标志。
  • 更改存储驱动程序会使本地系统上无法访问现有的容器和镜像。在更改存储驱动程序之前,使用docker save来保存已经构建的任何镜像,或者将它们推入docker Hub或私有注册表,这样就不需要在以后重新创建。

使用overlay或overlay2存储驱动程序配置Docker

  1. 停止Docker。
    systemctl stop docker
    
  2. 编辑 vim /etc/docker/daemon.json ,切记,如果不止一项配置,需要 , 隔开
    {
      "storage-driver": "overlay2"
    }
    
    如果daemon.json文件包含格式错误的JSON,则Docker无法启动。
  3. 启动Docker。
    systemctl start docker
    
  4. 验证守护程序正在使用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
    <output truncated>
    

overlay2驱动程序是如何工作的

在一个Linux主机上覆盖两个目录,并将它们表示为一个目录。

这些目录称为层,统一过程称为联合挂载。

OverlayFS将下面的目录称为lowerdir,上面的目录称为upperdir。统一视图通过其自己的目录merged公开。
overlay2驱动程序本身最多支持128个较低的OverlayFS层。该功能为与层相关的Docker命令(如Docker build和Docker committ)提供了更好的性能,并且消耗支持文件系统上的更少的inode。
在这里插入图片描述
当镜像层和容器层包含相同的文件时,容器层“胜出”并掩盖了镜像层中相同文件的存在

创建一个容器,overlay驱动程序将代表镜像顶层的目录和容器的新目录组合在一起。镜像的顶层是覆盖层中的下层,并且是只读的。容器的新目录是upperdir,并且是可写的。

磁盘上的镜像和容器层

镜像层
每个镜像层在磁盘上都有自己的目录,镜像的ID和目录ID不对应。
在这里插入图片描述
镜像层目录包含该层独有的文件以及与较低层共享的数据的硬链接。这样可以有效利用磁盘空间。

容器层
容器也存在于Docker主机文件系统下的磁盘上 /var/lib/docker/overlay/I。
在这里插入图片描述

容器如何使用overlay或overlay2进行读写

文件读取

考虑三种情况

  • 该文件在容器层中不存在: 文件在容器中还不存在(upperdir),则从镜像(lowerdir)中读取该文件。这只会带来很少的性能开销。
  • 该文件仅存在于容器层中: 文件存在于容器中(upperdir),而不在镜像中(lowerdir),则直接从容器中读取该文件。
  • 该文件同时存在于容器层和镜像层: 文件存在于镜像层和容器层中,则读取该文件在容器层中的版本。容器层中的文件(upperdir)掩盖了与镜像层(lowerdir)同名的文件。

修改文件或目录

考虑容器中的文件被修改的一些场景。

  • 第一次写入文件: 容器第一次写入现有文件时, 该文件在容器中不存在(upperdir)。overlay/overlay2驱动程序执行copy_up操作, 将文件从镜像(lowerdir)复制到容器(upperdir)。然后容器将更改写入容器层中文件的新副本。

    但是,OverlayFS是在文件级别而不是块级别工作的。这意味着所有的OverlayFS copy_up操作都会复制整个文件,即使文件非常大,并且只有一小部分被修改。这对容器写性能有明显的影响。然而,有两件事值得注意:

    1. copy_up操作只在第一次将给定文件写入时发生。对同一个文件的操作后续都是在复制到容器层的副本上进行操作。
    2. OverlayFS只适用于两层。这意味着性能应该优于AUFS,后者在搜索多层镜像中的文件时可能会出现明显的延迟。这一优势适用于overlayoverlay2驱动程序。在初始读取时,overlayfs2的性能略低于overlayfs,因为它必须遍历更多的层,但是它会缓存结果,所以这只是很小的损失。
  • 删除文件和目录 :

  1. 当在容器中删除文件时,将在容器中创建一个whiteout文件(upperdir)。镜像层(lowerdir)中的文件的版本没有被删除(因为lowerdir是只读的)。但是,whiteout文件阻止容器使用它。
  2. 当在容器中删除目录时,将在容器中创建一个不透明的目录(upperdir)。这与whiteout文件的工作方式相同,可以有效地阻止对目录的访问,即使它仍然存在于镜像(lowerdir)中。
  • 重命名目录:仅当源和目标路径都位于顶层时,才允许对目录调用rename(2)。否则,它将返回EXDEV错误(“不允许跨设备链接”)。应用程序需要设计成处理EXDEV并退回到“复制并断开链接”策略。

OverlayFS和Docker性能

aufsdevicemapper相比,overlay2overlay驱动程序的性能更好。在某些情况下,overlay2也可能比btrfs表现得更好。但是,请注意以下细节。

  • 页面缓存。OverlayFS支持页面缓存共享。访问同一文件的多个容器共享该文件的单个页面缓存条目。这使得overlayoverlay2驱动程序在内存方面非常高效,对于高密度的用例(比如PaaS)是一个很好的选择。
  • copy_up。与AUFS一样,每当容器第一次写入文件时,OverlayFS都会执行复制操作。这可能会增加写操作的延迟,特别是对于大型文件。但是,一旦文件被复制,对该文件的所有后续写操作都发生在上层,不需要进一步的复制操作。
    OverlayFS的copy_up操作比使用AUFS的相同操作要快,因为AUFS支持比OverlayFS更多的层,如果搜索多个AUFS层,可能会导致更大的延迟。overlay2也支持多层,但是通过缓存可以降低任何性能损失。
  • Inode的限制。使用旧的overlay存储驱动程序会导致过多的inode消耗。在Docker主机上存在大量的镜像和容器时尤其如此。增加文件系统可用inode数量的惟一方法是重新格式化它。为了避免遇到这个问题,强烈建议尽可能使用overlay2。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章