您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码:  验证码,看不清楚?请点击刷新验证码 必填



  求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
 
   
 
 
     
   
 订阅
  捐助
PPTV聚力传媒 DCOS Docker存储方式的研究选型
 
作者:张正宜  来源:微信 发布于 2016-10-12
  2254  次浏览      20
 

本文的目的

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

如何指定存储驱动

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

Copy On Write技术

想要有效的使用存储驱动,需要了解Docker如何存储镜像以及容器如何使用镜像。Docker镜像含有启动Docker容器所需的文件系统结构及其内容。在传统的Linux操作系统内核启动时,首先挂载一个只读的rootfs,当系统检测其完整性后,再将其切换为读写模式。而在Docker架构中,当Docker daemon为Docker容器挂载rootfs时,沿用了Linux内核启动时的方法,即将rootfs设为只读模式,在挂载完毕之后,在已有的只读rootfs上再挂载一个读写层。这样。可读写层处于Docker容器文件系统的最顶层,其下可能挂载多个只读层,只有在Docker容器运行过程中文件系统发生变化时,才会把文件拷贝到读写层再修改,这样的技术被称为写时复制(Copy On Write)。存储驱动提供了接口支持镜像分层与写时复制机制。

AUFS

Docker团队最开始在dotCloud内部便使用AUFS来运行容器,因此AUFS有最长的历史,也就拥有较为丰富的运维经验。AUFS层层堆叠多个文件系统层,然后每一层都对外公开一个单独的挂载点供访问。它每一次的查找总是先从最顶层开始,当某个文件需要作读写操作时该文件将会被复制到最顶层,因此在性能方面的瓶颈主要在于需要写入大文件的场景。不过AUFS存储驱动最主要的问题还是AUFS文件系统本身没有被纳入主流的Linux内核版本。

图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 On Linux(ZoL)项目提供了一个可以单独安装的内核模块和用户空间工具。除非你在ZoL项目上已经有大量的实践经验,现阶段并不推荐在生产环境中使用zfs作为Docker的存储驱动。

如下图所示,镜像的最底层(base layer)是一个ZFS文件系统。每一个镜像子层都是一个基于下层ZFS快照的ZFS克隆实体。一个容器的文件系统是一个ZFS克隆,下层是从镜像层创建的快照。所有数据实体都从zpool分配空间。

图5 ZFS镜像层容器层

我们的现状

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

[root@oak-qa-04 Deploy]# docker stop

b977235038bce3176279bdd27cf84b12755eff0ed08d6a11b09e5e8e97480f78

b977235038bce3176279bdd27cf84b12755eff0ed08d6a11b09e5e8e97480f78

[root@oak-qa-04 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、由于预分配机制,待需要占用的时候,如果实际磁盘空间已经没有那么多了,就会发生异常。

[root@oak-qa-05]#lsblk
NAME MAJ:MINRM SIZE RO TYPE MOUNTPOINT
fd0 8:0 0 4k 0 disk
sda1
sda2
loop0 7:0 0 100G 0 loop
loop1 7:1 0 2G 0 loop

接下来如何选择

用户可根据自己的实际需要,考虑以下几个方面:容器密度、文件大小、是否IO密集等,以及自己在使用方面的喜好,来选择一种。

由于AUFS没有并入linux内核主线,overlay没有完全支持POSIX标准,ZFS也存在兼容性问题。鉴于DeviceMapper(loop模式)之前遇到种种问题,所以我们计划在Btrfs与DeviceMapper(direct-lvm模式)两者中选一种,下面对他们进行一些IO性能的测试,之后在现有环境中部分部署Btrfs,部分部署DeviceMapper,对稳定性进行比较。

大家对于打算使用的存储驱动,可以关注官方网站的bug列表,也是一个可参考的因素。

IO性能测试

使用IOzone测试工具,该工具参数多样,可灵活使用,测试各种读写,我们结合自己的场景,主要测试读的速度,主要关注文件大小在几百kKB到几MB之间的数据,仅比较Btrfs与DeviceMapper。

测试环境

宿主机配置如下:

测试1

Read(读测试),文件大小为4k到128k,以record 4k来传输,测试结果如下图所示:

红色为Btrfs,蓝色为DeviceMapper;

横坐标为文件大小,单位为kBytes,纵坐标为传输速度,单位为kBytes/s;

图6 测试1

测试2

Read(读测试),文件大小为128k到8192k,以record 4k来传输,测试结果如下图所示:

红色为Btrfs,蓝色为DeviceMapper;

横坐标为文件大小,单位为kBytes,纵坐标为传输速度,单位为kBytes/s;

图7 测试2

测试3

Read(读测试),文件大小为256k到16384k,以record 256k来传输,测试结果如下图所示:

红色为Btrfs,蓝色为DeviceMapper;

横坐标为文件大小,单位为kBytes,纵坐标为传输速度,单位为kBytes/s;

图8 测试3

测试4

Reread(对刚读过的文件重读),文件大小为4k到128k,以record 4k来传输,测试结果如下图所示:

红色为Btrfs,蓝色为DeviceMapper;

横坐标为文件大小,单位为kBytes,纵坐标为传输速度,单位为kBytes/s;

图9 测试4

测试5

Reread(对刚读过的文件重读),文件大小为128k到8192k,以record 4k来传输,测试结果如下图所示:

红色为Btrfs,蓝色为DeviceMapper;

横坐标为文件大小,单位为kBytes,纵坐标为传输速度,单位为kBytes/s;

图10 测试5

测试6

Reread(对刚读过的文件重读),文件大小为256k到16384k,以record 256k来传输,测试结果如下图所示:

红色为Btrfs,蓝色为DeviceMapper;

横坐标为文件大小,单位为kBytes,纵坐标为传输速度,单位为kBytes/s;

图11 测试6

测试7

Random read(随机读),文件大小为4k到128k,以record 4k来传输,测试结果如下图所示:

红色为Btrfs,蓝色为DeviceMapper;

横坐标为文件大小,单位为kBytes,纵坐标为传输速度,单位为kBytes/s;

图12 测试7

测试8

Random read(随机读),文件大小为128k到8192k,以record 4k来传输,测试结果如下图所示:

红色为Btrfs,蓝色为DeviceMapper;

横坐标为文件大小,单位为kBytes,纵坐标为传输速度,单位为kBytes/s;

图13 测试8

测试9

Random read(随机读),文件大小为256k到16384k,以record 256k来传输,测试结果如下图所示:

红色为Btrfs,蓝色为DeviceMapper;

横坐标为文件大小,单位为kBytes,纵坐标为传输速度,单位为kBytes/s;

图14 测试9

小结

对于我们目前打算用docker上线的pp云等服务,主要关注从几百KB到几MB大小的文件,只需考虑读,写的操作是采用挂载卷的方式,不会直接写在容器里。在读的方面,devicemapper比Btrfs性能略好。在稳定性方面的比较,由于线下的试验并不能完全模仿线上的场景,初步打算上线时一部分容器运行在devicemapper存储驱动的环境下,一部分容器运行在Btrfs存储驱动的环境下,进行观察、比较。

   
2254 次浏览       20
 
相关文章

云计算的架构
对云计算服务模型
云计算核心技术剖析
了解云计算的漏洞
 
相关文档

云计算简介
云计算简介与云安全
下一代网络计算--云计算
软浅析云计算
 
相关课程

云计算原理与应用
云计算应用与开发
CMMI体系与实践
基于CMMI标准的软件质量保证
最新活动计划
LLM大模型应用与项目构建 12-26[特惠]
QT应用开发 11-21[线上]
C++高级编程 11-27[北京]
业务建模&领域驱动设计 11-15[北京]
用户研究与用户建模 11-21[北京]
SysML和EA进行系统设计建模 11-28[北京]

专家视角看IT与架构
软件架构设计
面向服务体系架构和业务组件的思考
人人网移动开发架构
架构腐化之谜
谈平台即服务PaaS
更多...   
相关培训课程

云计算原理与应用
Windows Azure 云计算应用

摩托罗拉 云平台的构建与应用
通用公司GE Docker原理与实践
某研发中心 Openstack实践
知名电子公司 云平台架构与应用
某电力行业 基于云平台构建云服务
云计算与Windows Azure培训
北京 云计算原理与应用