Docker 存储驱动

2018-11-28 0 By admin

镜像存储驱动graphdriver是所有容器镜像相关操作的最终执行者。
Docker最开始采用AUFS作为文件系统,也得益于AUFS分层的概念,实现了多个Container可以共享同一个image。
但由于AUFS未并入Linux内核,且只支持Ubuntu,考虑到兼容性问题,在Docker 0.7版本中引入了存储驱动。
目前,Docker支持AUFS、Btrfs、Device mapper、OverlayFS、ZFS五种存储驱动。
就如Docker官网上说的,没有单一的驱动适合所有的应用场景,要根据不同的场景选择合适的存储驱动,才能有效的提高Docker的性能。

基础说明

vfs

vfs是接口的“原生”的实现,完全没有使用联合文件系统或者写时复制技术,而是将所有的分层依次拷贝到静态的子文件夹中,然后将最终结果挂载到容器的根文件系统。
它并不适合实际或者生产环境使用,但是对于需要进行简单验证的场景,或者需要测试Docker引擎的其他部件的场景,是很有价值的。
Docker引擎开发者用来构建Docker自己所使用的Dockerfile,也是采用vfs来作为里边Docker的graphdriver。

联合文件系统 Union FS

现有的graphdriver中只有少部分是真正的有写时复制语义的联合文件系统:Overlay的两个版本,从Docker早期就存在的aufs。
记住联合文件系统只是一个基于文件的接口,通过把一组目录交错起来来,形成一个单一视图。
所以与它不是一个真正的文件系统,如ext4或者xfs,它仅仅是站在一个已有的文件系统上提供了这些功能。在一些场景,对于底层文件系统是有要求的,并且Docker也会同时检查请求的联合文件系统和底层的文件系统,来保证它们是兼容的。

特定文件系统的实现

剩下的graphdriver都是建立在具体文件系统实现的基础上,需要依赖其内置特性(如快照)能提供必需的能力。这些包含devicemaper、zfs和btrfs驱动。在这每一个情形中,你都需要新建一个磁盘并用该文件系统格式化磁盘(或者为了快速测试,用循环挂载的文件作为磁盘),来使用这些选项作为Docker引擎的存储后端。

联合文件系统列表

AUFS

AUFS(AnotherUnionFS)是一种Union FS,是文件级的存储驱动。AUFS能透明覆盖一或多个现有文件系统的层状文件系统,把多层合并成文件系统的单层表示。简单来说就是支持将不同目录挂载到同一个虚拟文件系统下的文件系统。这种文件系统可以一层一层地叠加修改文件。无论底下有多少层都是只读的,只有最上层的文件系统是可写的。当需要修改一个文件时,AUFS创建该文件的一个副本,使用写时复制将文件从只读层复制到可写层进行修改,结果也保存在可写层。在Docker中,底下的只读层就是image,可写层就是Container。

Overlay

Overlay是Linux内核3.18后支持的,也是一种Union FS,和AUFS的多层不同的是Overlay只有两层:一个upper文件系统和一个lower文件系统,分别代表Docker的镜像层和容器层。当需要修改一个文件时,使用CoW将文件从只读的lower复制到可写的upper进行修改,结果也保存在upper层。在Docker中,底下的只读层就是image,可写层就是Container。

Device mapper

Device mapper是Linux内核2.6.9后支持的,提供的一种从逻辑设备到物理设备的映射框架机制,在该机制下,用户可以很方便的根据自己的需要制定实现存储资源的管理策略。前面讲的AUFS和OverlayFS都是文件级存储,而Device mapper是块级存储,所有的操作都是直接对块进行操作,而不是文件。Device mapper驱动会先在块设备上创建一个资源池,然后在资源池上创建一个带有文件系统的基本设备,所有镜像都是这个基本设备的快照,而容器则是镜像的快照。所以在容器里看到文件系统是资源池上基本设备的文件系统的快照,并不有为容器分配空间。当要写入一个新文件时,在容器的镜像内为其分配新的块并写入数据,这个叫用时分配。当要修改已有文件时,再使用CoW为容器快照分配块空间,将要修改的数据复制到在容器快照中新的块里再进行修改。Device mapper 驱动默认会创建一个100G的文件包含镜像和容器。每一个容器被限制在10G大小的卷内,可以自己配置调整。

Btrfs

Btrfs被称为下一代写时复制文件系统,并入Linux内核,也是文件级级存储,但可以像Device mapper一直接操作底层设备。Btrfs把文件系统的一部分配置为一个完整的子文件系统,称之为subvolume 。那么采用 subvolume,一个大的文件系统可以被划分为多个子文件系统,这些子文件系统共享底层的设备空间,在需要磁盘空间时便从底层设备中分配,类似应用程序调用 malloc()分配内存一样。为了灵活利用设备空间,Btrfs 将磁盘空间划分为多个chunk 。每个chunk可以使用不同的磁盘空间分配策略。比如某些chunk只存放metadata,某些chunk只存放数据。这种模型有很多优点,比如Btrfs支持动态添加设备。用户在系统中增加新的磁盘之后,可以使用Btrfs的命令将该设备添加到文件系统中。Btrfs把一个大的文件系统当成一个资源池,配置成多个完整的子文件系统,还可以往资源池里加新的子文件系统,而基础镜像则是子文件系统的快照,每个子镜像和容器都有自己的快照,这些快照则都是subvolume的快照。

ZFS

ZFS 文件系统是一个革命性的全新的文件系统,它从根本上改变了文件系统的管理方式,ZFS 完全抛弃了“卷管理”,不再创建虚拟的卷,而是把所有设备集中到一个存储池中来进行管理,用“存储池”的概念来管理物理存储空间。过去,文件系统都是构建在物理设备之上的。为了管理这些物理设备,并为数据提供冗余,“卷管理”的概念提供了一个单设备的映像。而ZFS创建在虚拟的,被称为“zpools”的存储池之上。每个存储池由若干虚拟设备(virtual devices,vdevs)组成。这些虚拟设备可以是原始磁盘,也可能是一个RAID1镜像设备,或是非标准RAID等级的多磁盘组。于是zpool上的文件系统可以使用这些虚拟设备的总存储容量。