Docker存储驱动(driver)
Docker有多个存储驱动程序,允许用户使用底层存储设备。
- AUFS
- Btrfs
- Device mapper
- OverlayFS
- ZFS
- VFS
存储驱动的作用
使用共享技术减小镜像体积
下载镜像时,实际是下载了镜像层。每个镜像层都有一个UUID,这个ID通过加密哈希算法得到。这些镜像层都保存在宿主机的文件系统中,每层都有独立的目录。
下载镜像时,Docker Daemon 会检查镜像中的镜像层,与宿主机的文件系统中的镜像层进行比较。如果发现这些镜像层已经存在,Dokcer Daemon 将会忽略这些镜像层,只下载不存在的镜像层。
使用写时复制技术加快容器启动时间
在容器中修改文件时,Docker通过存储驱动,发起一个写时复制操作。不同的存储驱动使用不同的步骤。AUFS和OverlayFS使用下面的步骤:
(1)、在镜像层中寻找需要修改的文件;
(2)、把这个文件从镜像层复制到容器层中;
(3)、在容器层中修改这个文件。
Btrfs,ZFS和其他存储驱动使用不同的步骤实现写时复制。
不同容器占用的存储空间不同。如果在容器中有很多与修改文件、新建文件相关的操作,这些容器会占用更多的存储空间。因为,每次修改文件都会在容器层中分配新的存储空间。如果在容器中,需要大量的写操作,最好使用挂在卷,把这些数据写在挂在卷中。
把文件从镜像层中复制到容器层会带来额外的系统开销,不同的存储驱动产生的开销也不同。一些因素会引起明显的系统开销,如修改大文件,新建大文件,镜像中存在很多镜像层,很深的目录树等。但是这些系统开销仅发生一次,就是在文件第一次被修改时,一旦docker发现文件被修改,就会把文件从镜像层复制到容器层。其后的操作都是在容器层中完成,不会带来额外的开销。
每启动一个容器,Docker Daemon 都会添加一个容器层,并未这个容器层分配一个随机的UUID,这个ID就是Docker run返回的ID。
通过命令 ls /var/lib/docker/containers 可以在宿主机中看到这些容器层。docker 使用写时复制技术,不仅节约了容器的存储空间(不用为每个启动的容器复制镜像层),同时也减少了容器的启动时间。启动容器时,Docker Daemon 只需要为m每个容器新建一个可写的数据层,而不用复制所有的镜像层。
存储驱动的选择
对于所有当前支持的Linux发行版,overlay2是首选的存储驱动程序,不需要任何额外的配置。
当在不支持overlay2的内核3.13的Ubuntu 14.04上运行时,aufs是Docker 18.06和更早版本的首选存储驱动程序。
支持devicemapper,但在生产环境中需要direct-lvm,因为loopback-lvm虽然为零配置,但性能却很差。 以前devicemapper是CentOS和RHEL的推荐存储驱动程序,因为它们的内核版本不支持overlay2。但是,当前版本的CentOS和RHEL现在支持overlay2,现在推荐使用该驱动程序。
如果文件系统是btrfs和zfs存储驱动程序(安装了Docker的主机的文件系统),则使用它们。这些文件系统允许使用高级选项,例如创建“快照”,但需要更多的维护和设置。这些中的每一个都依赖于正确配置的后备文件系统。
vfs存储驱动程序旨在用于测试目的,以及无法使用写时复制文件系统的情况。此存储驱动程序的性能很差,通常不建议在生产中使用。