DCOS Docker存储方式研究选型

  本文的目的

  Docker原生提供了多种存储驱动,用户需要做的是结合自己的场景选用其中之一。没有一种存储驱动是适合所有场景的。本文先简单介绍如下几种存储驱动:AUFS、DeviceMapper、Btrfs、overlayFs、ZFS,之后说明PPTV在构建DCOS的选型过程。

  如何指定存储驱动

  用户决定使用哪款驱动,要在Docker守护进程启动时指定,当然指定的驱动必须被底层操作系统支持。如更换存储驱动,需重启守护进程。指定存储驱动的方法可参考Docker官网,操作简单方便。各存储驱动都封装了统一接口供守护进程调用,一旦完成初始化,存储驱动的差异对守护进程来说是透明的。

  Copy alt="物联网" width="550" height="303" />

  图1 AUFS镜像层容器层

  DeviceMapper

  DeviceMapper使用预分配技术来实现镜像分层,DeviceMapper的写时复制技术是基于块级别的,不同于AUFS基于文件级别。当Docker守护进程启动时,会创建预分配机制所必须的两个块设备:用作存储池的数据设备和维护元数据的设备,守护进程在预分配的存储池上创建一个基础设备,所有新的镜像层都是基础设备的一个快照,基础设备的大小默认为10GB,可以在守护进程启动时通过dm.basesize参数来修改这一配置。DeviceMapper有两种模式,默认为loop模式,生产环境建议使用direct-lvm模式,原因为loop模式是基于两个稀疏文件创建虚拟的块设备的,影响性能。

物联网

  图2 DeviceMapper镜像层容器层

  Btrfs

  Btrfs以块为单位存储数据,一个块就是一段原始存储。Docker利用Btrfs的子卷特性,每一个新创建的容器都会被分配一个新的Btrfs子卷,如果存在父镜像层,那么它会以父镜像层子卷的一个快照的形式创建。

物联网

  图3 Btrfs镜像层容器层

  OverlayFs

  OverlayFs是一个联合文件系统,与AUFS的做法有些类似,由于合并目录,overlayFs在查找效率方面作了不小的改进,不同于AUFS镜像层越多则查找时间越长。基于overlayFs技术有两种存储驱动:overlay与overlay2,根据官方文档,overlay要求内核版本3.18以上,overlay2要求内核版本4.0以上。但是我们经过尝试,可以在3.10内核使用overlay。

物联网

  图4 overlay镜像层容器层

  ZFS

  ZFS是Sun公司(现在的Oracle)发明的并在CDDL条款下开源。而由于CDDL与GPL开源条款的不兼容,ZFS无法并入Linux内核主线。不过ZFS alt="物联网" width="550" height="294" />

  图5 ZFS镜像层容器层

  我们的现状

  在过去的一段时间,我们使用loop模式的DeviceMapper作为存储驱动,是Docker默认的,在使用过程中遇到一些问题。

  [[email protected] Deploy]# docker stop

  b977235038bce3176279bdd27cf84b12755eff0ed08d6a11b09e5e8e97480f78

  b977235038bce3176279bdd27cf84b12755eff0ed08d6a11b09e5e8e97480f78

  [[email protected] Deploy]# docker rm

  b977235038bce3176279bdd27cf84b12755eff0ed08d6a11b09e5e8e97480f78

  Error response from daemon: Driver devicemapperfailed to remove root filesystem

  b977235038bce3176279bdd27cf84b12755eff0ed08d6a11b09e5e8e97480f78

  : Device is Busy

  如上面所示问题,不只一次出现,目前都没有完全解决,最终只能用重启Docker的方法,如果在生产环境中遇到这样的问题,应该是大家不希望看到的。

  我们分析产生该问题的原因还是在于loop模式的的devicemapper所用的数据设备和元数据设备都只是绑定到回环设备上的稀疏文件,如不做特别的配置,这些文件大小一般看上去是100GB(如下图所示loop0)和2GB(如下图所示loop1),由于使用预分配机制,在实际写入数据之前,并不会真正占用100GB和2GB的磁盘空间。这样的机制让我们想到两个问题:1、稀疏文件性能不太好,且文件本身可能会损坏;2、由于预分配机制,待需要占用的时候,如果实际磁盘空间已经没有那么多了,就会发生异常。

  [[email protected]]#lsblk

  NAME MAJ:MINRM SIZE RO TYPE MOUNTPOINT

  fd0 8:0 0 4k 0 disk