ZFS是下一代的文件系统,支持了很多存储高级特性,如卷管理、快照、和校验、压缩和重复删除技术、拷贝等。

  ZFS由Sun公司创建,现属于Oracle,ZFS是开源的,并基于CDDL license。因为CDDL和GPL不兼容,ZFS不能加入Linux kernel主线。然而,ZFS On Linux(ZoL)项目提供kernel模块和用户空间程序,这些都可以单独的安装。

  ZFS on Linux(ZoL)是一项成熟的技术,但是,现在却不建议在产品中使用zfs存储驱动,当然,除非你对ZoL有着丰富的经验。

  注意:在Linux平台上,有ZFS的FUSE实现,它可以和Docker结合起来使用,但是却不推荐这样使用。原生的ZFS驱动(ZoL)被测试得更多,更有效率,也更广泛地被使用。下面的内容也指的是原生的ZFS驱动。

镜像分层和共享

  Docker的zfs存储驱动使用了ZFS驱动的三个组件:

   ●文件系统

   ●快照

   ●克隆

  ZFS系统提供超配特性,通过按需分配操作从ZFS池(zpool)分配空间。快照和克隆是ZFS系统某个时间点的拷贝,较节省空间。快照是只读的,而克隆是读写的,克隆只能通过快照来创建。下图显示了它们之间这种简单地关系。

  

  图中的实线显示了创建了克隆的过程。第一步创建了一个文件系统的快照,第二步通过快照创建了一份克隆。虚线显示了克隆、文件系统和快照之间的关系。这三个ZFS组件都从同一个下层的zpool申请空间。

  在Docker host上使用zfs存储驱动。镜像的基础层就是一个ZFS文件系统,每个子层都是底层ZFS快照的一个ZFS克隆,容器就是一个ZFS克隆,它基于其镜像最顶层的ZFS快照。所有的ZFS组件都从同一个zpool分配空间。下图显示了一个基于两层镜像的容器是如何使用这些ZFS组件的。

  

  结合上图,下面的过程解释了镜像是如何分层的,容器是如何创建的。

   ▶在Docker host中,镜像的基础层是一个ZFS文件系统。

   文件系统从zpool中消耗空间。

   ▶附加的镜像层是其下层镜像的克隆。

   图中,“Layer 1”是通过创建基础镜像的ZFS快照,然后再通过快照创建克隆来实现的。克隆是可读写的,并且从zpool按需分配空间;而快照是只读的。

   ▶当容器启动时,就会在镜像层上附加一个可读写层。

   上图中,制造了一个镜像顶层的快照,然后再基于快照创建了一份克隆,而这份克隆就是容器的可读写层。

   如果需要改变容器,那么久会从zpool按需分配空间给容器,ZFS默认会分配128K大小的块。

  这种从只读快照创建子层和容器的方法,使得镜像作为不可变对象来维护。

容器使用ZFS读写

  容器从zfs存储驱动读数据的过程非常简单。新启动的容器基于ZFS克隆,这份克隆从初始化开始就共享它底层的所有数据。这意味着使用zfs的读操作非常快,即使正在读的数据并没有拷贝到容器。下图显示了数据块的共享情况。

  

  写新数据是通过按需分配操作来完成的。每次要向容器的一个新区域写数据时,就会从zpool中分配一个新块,也就是说写新数据时容器就会消耗额外的空间。分配给容器的新空间从底层的zpool分配。

  想更新容器的新数据,就得分配新空间给容器,并将这些改变的信息保存在新的块中。原来的块没有改变,下面的镜像依然是不可变的。

Docker中配置ZFS存储驱动

  只有在/var/lib/docker被映射在一个ZFS文件系统上时,才能在docker host上使用zfs存储驱动。本节将介绍如何在Ubuntu上安装原生的ZFS on Linux(ZoL)。

准备

  如果你已经在Docker host上使用过Docker daemon,并且有一些想保存的镜像,那么在执行下面的步骤之前,你需要将这些镜像保存到Docker Hub或者你的私有Docker镜像仓库中。

  停止Docker daemon。另外,确保你在/dev/xvdb(这个设备名可能根据你的OS环境而不同,你需要换成适合你自己的设备名)上有一个空闲块设备。

在Ubuntu16.04 LTS上安装ZFS

  1) 停止Docker daemon。

$ sudo systemctl stop docker.service

  2) 安装zfs包。

 $ sudo apt-get install -y zfs

 Reading package lists... Done
Building dependency tree
<output truncated>

  3) 确认你的zfs模块成功安装并加载。

$ lsmod | grep zfs

 zfs                  2813952  3
zunicode 331776 1 zfs
zcommon 57344 1 zfs
znvpair 90112 2 zfs,zcommon
spl 102400 3 zfs,zcommon,znvpair
zavl 16384 1 zfs

在Ubuntu 14.04 LTS上安装ZFS

  1) 停止Docker daemon。

$ sudo systemctl stop docker.service

  2) 安装software-properties-common包。

$ sudo apt-get install -y software-properties-common

Reading package lists... Done
Building dependency tree
<output truncated>

  3) 添加zfs-native包。

$ sudo add-apt-repository ppa:zfs-native/stable

The native ZFS filesystem for Linux. Install the ubuntu-zfs package.
<output truncated>
gpg: key F6B0FC61: public key "Launchpad PPA for Native ZFS for Linux" imported
gpg: Total number processed: 1
gpg: imported: 1 (RSA: 1)
OK

  4) 获取最新包的列表。

 $ sudo apt-get update

 Ign http://us-west-2.ec2.archive.ubuntu.com trusty InRelease
Get:1 http://us-west-2.ec2.archive.ubuntu.com trusty-updates InRelease [64.4 kB]
<output truncated>
Fetched 10.3 MB in 4s (2,370 kB/s)
Reading package lists... Done

  5) 安装ubuntu-zfs包。

$ sudo apt-get install -y ubuntu-zfs

Reading package lists... Done
Building dependency tree
<output truncated>

  6) 加载zfs模块。

$ sudo modprobe zfs

  7) 确认模块是否正确加载。

$ lsmod | grep zfs

zfs                  2768247  0
zunicode 331170 1 zfs
zcommon 55411 1 zfs
znvpair 89086 2 zfs,zcommon
spl 96378 3 zfs,zcommon,znvpair
zavl 15236 1 zfs

在Docker中配置ZFS

  一旦安装和加载了ZFS,就可以在Docker中配置ZFS了。

   1) 创建一个新的zpool。

$ sudo zpool create -f zpool-docker /dev/xvdb

   上面命令创建了一个名为“zpool-docker”的zpool。这个名称是随意的。

   2) 检查zpool是否存在。

$ sudo zfs list

NAME            USED  AVAIL    REFER  MOUNTPOINT
zpool-docker 55K 3.84G 19K /zpool-docker

   3) 在/var/lib/docker上创建和映射一个新的ZFS文件系统。

$ sudo zfs create -o mountpoint=/var/lib/docker zpool-docker/docker

   4) 检查前面的步骤是否正常工作。

$ sudo zfs list -t all

NAME                 USED  AVAIL  REFER  MOUNTPOINT
zpool-docker 93.5K 3.84G 19K /zpool-docker
zpool-docker/docker 19K 3.84G 19K /var/lib/docker

   可以看到,在/var/lib/docker上映射了一个ZFS文件系统,daemon启动后会自动加载zfs存储驱动。

   5) 启动Docker daemon。

$ sudo service docker start

docker start/running, process 2315

   6) 确认daemon正在使用zfs存储驱动。

$ sudo docker info

Containers: 0
Images: 0
Storage Driver: zfs
Zpool: zpool-docker
Zpool Health: ONLINE
Parent Dataset: zpool-docker/docker
Space Used By Parent: 27648
Space Available: 4128139776
Parent Quota: no
Compression: off
Execution Driver: native-0.2
[...]

Docker中的ZFS性能

  有以下一些因素会影响zfs存储驱动在Docker中的性能。

   ●内存。内存对ZFS性能影响很大,因为ZFS最初被设计成在拥有大量内存的Sun Solaris服务器上使用的。

   ●ZFS特性。使用ZFS特性,如重复删除技术,会增加ZFS的内存使用。就内存使用和效率原因而言,建议关闭FS的重复删除特性。

   ●ZFS缓存。ZFS将磁盘块缓存在被称作adaptive replacement cache(ARC)内存结构体中。ZFS的ARC单拷贝特性使得块的单个缓存拷贝可以被多个文件系统的克隆共享,也就是说多个运行着的容器可以共享缓存块的单个拷贝。这意味着对于PaaS或其他高密度用例来说,ZFS是一个不错的选择。

   ●存储碎片。碎片是诸如ZFS这种copy-on-write文件系统的副产品。不过,ZFS写128K的块时,会分配slab(多个128K的块)来进行CoW操作,从而尝试减少存储碎片。ZFS intent log(ZIL)和 coalescing of writes(delayed writes)也可以帮忙减少碎片。

   ●使用原生的Linux ZFS驱动。虽然Docker zfs存储驱动支持ZFS FUSE实现,但在高性能场景下不建议使用ZFS FUSE。原生的ZFS Linux驱动有着更好的性能。

   ●使用SSD。为了更好的性能,可以使用更快的存储介质(如SSD)。不过,如果你的SSD存储很有限,那么建议你关闭SSD上的ZIL特性。

限制容器写的存储配额

  如果你像实现对每个镜像的存储配额,那么你可以使用--storage-opt选项。

--storage-opt size=256M

  它会限制容器可以写/修改的空间大小(需要ZFS使能特性available)。也就是说,如果你有一个256MB大小的镜像,并且使用了前面的参数选项,那么你对应的容器就有512MB的大小,其中有256MB是可用的。

Docker存储驱动之ZFS简介的更多相关文章

  1. Docker存储驱动之OverlayFS简介

    简介 OverlayFS是一种和AUFS很类似的文件系统,与AUFS相比,OverlayFS有以下特性: 1) 更简单地设计: 2) 从3.18开始,就进入了Linux内核主线: 3) 可能更快一些. ...

  2. Docker存储驱动之AUFS简介

    简介 AUFS是曾是Docker默认的首选存储驱动.它非常稳定.有很多真实场景的部署.很强的社区支持.它有以下主要优点: 极短的容器启动时间. 有效的存储利用率. 有效的内存利用率. 虽然如此,但由于 ...

  3. Docker存储驱动之Btrfs简介

    简介 Btrfs是下一代的copy-on-write文件系统,它支持很多高级特性,使其更加适合Docker.Btrfs合并在内核主线中,并且它的on-disk-format也逐渐稳定了.不过,它的很多 ...

  4. Docker存储驱动Device Mapper,Overlay,AUFS

    Docker存储驱动之Device Mapper简介 - BookShu - 博客园https://www.cnblogs.com/styshoo/p/6528762.html Docker存储驱动之 ...

  5. Docker存储驱动之Device Mapper简介

    Device Mapper是一个基于kernel的框架,它增强了很多Linux上的高级卷管理技术.Docker的devicemapper驱动在镜像和容器管理上,利用了该框架的超配和快照功能.为了区别, ...

  6. Docker存储驱动之总览

    简介 本文会介绍Docker存储驱动的特性,别列出现在已经支持的存储驱动,最后,会介绍如果选型适合你的存储驱动. 可插拔的存储驱动架构 Docker的存储驱动架构是可插拔的,可以让你很方便的将适合你环 ...

  7. 聊一聊docker存储驱动

    目录 镜像的分层特性 容器读写层的工作原理 写时复制 用时配置 Docker存储驱动 AUFS OverlayFS Devicemapper 常用存储驱动对比 AUFS VS OverlayFS Ov ...

  8. 有容云-【原理】Docker存储驱动之AUFS

    编者按:今天聊一聊Docker的Image(镜像)与Container(容器)的存储以及存储驱动之AUFS.   Docker存储驱动简介 Docker内置多种存储驱动,每种存储驱动都是基于Linux ...

  9. DOCKER学习_006:Docker存储驱动

    一 镜像的分层特性 在说docker的文件系统之前,我们需要先想清楚一个问题.我们知道docker的启动是依赖于image,docker在启动之前,需要先拉取image,然后启动.多个容器可以使用同一 ...

随机推荐

  1. DotNet加密方式解析--数字签名

    马上就要过年回村里了,村里没有wifi,没有4G,没有流量,更加重要的是过几天电脑就得卖掉换车票了,得赶紧写几篇博客. 数据安全的相关技术在现在愈来愈变得重要,因为人们对于自身的信息都有一种保护的欲望 ...

  2. jsp+servlet+javaBean+Dao

    一.Servlet程序各模块介绍1.JSP 用于显示.收集数据的部分.2.Servlet 用于验证数据.实例化JavaBean.调用DAO连接数据库.控制页面跳转3.DAO 用于连接数据库及进行数据库 ...

  3. C#进阶系列——使用Advanced Installer制作IIS安装包(二:配置安装包依赖项和自定义dll)

    前言:上篇C#进阶系列——使用Advanced Installer制作IIS安装包(一:配置IIS和Web.config)介绍了下使用Advanced Installer配置IIS和Web.confi ...

  4. MySQL的my-innodb-heavy-4G.ini配置文件的翻译

    我根据MySQL配置文件的英文文档说明,在根据自己所学的知识,使用有道词典对不懂的单词进行了查询,一个一个翻译出来的.有的专业术语翻译的不好,我使用了英文进行标注,例如主机(master)和副机(sl ...

  5. oracle_数据库访问问题

    1.通过JDBC连接数据库时报错“Caused by: oracle.net.ns.NetException: Got minus one from a read call” 网上百度得到: 1:数据 ...

  6. SQL2012还原数据库操作在本地服务器上操作和用别的电脑远程连接到服务器进行操作的文件路径差异

    在数据库服务器上想还原一个数据库到某个备份文件时期的,服务器的数据库文件本身是保存在 D:\DEVDB目录 通过开发电脑上的MS manager来连接数据库服务器操作还原 虽发现文件卡项上,原始文件名 ...

  7. 关于Ansi_Nulls、Quoted_Identifier、Ansi_Padding的用法

    --QUOTED_IDENTIFIER  语法SET QUOTED_IDENTIFIER { ON | OFF } 注释当 SET QUOTED_IDENTIFIER 为 ON 时,标识符可以由双引号 ...

  8. MongoDB学习总结(三) —— 常用聚合函数

    上一篇介绍了MongoDB增删改查命令的基本用法,这一篇来学习一下MongoDB的一些基本聚合函数. 下面我们直奔主题,用简单的实例依次介绍一下. > count() 函数 集合的count函数 ...

  9. 做一个360度看车的效果玩玩(web)

    前几天在 Lexus 官网看到有这样的一个效果:http://www.lexus.com.cn/models/es/360 于是顺手打开控制台看了下他们是怎么做的,发现使用的技术还是比较简单的,通过背 ...

  10. 微信小程序开发之http到https的转化

    小程序从公布到现在已经过去好几个月了,本来从小程序发布出来就准备抱着微信的大腿进行一波小程序开发的,但是由于公司项目小程序暂时不支持,也就只能一直搁浅.过年过来偶然和朋友谈起小程序,觉的工作再忙也得找 ...