Docker Storage Driver

每个 Docker 容器都有一个本地存储空间,用于保存层叠的镜像层(Image Layer)以及挂载的容器文件系统。

默认情况下,容器的所有读写操作都发生在其镜像层上或挂载的文件系统中,所以存储是每个容器的性能和稳定性不可或缺的一个环节。

以往,本地存储是通过存储驱动(Storage Driver)进行管理的,有时候也被称为 Graph Driver 或者 GraphDriver。

虽然存储驱动在上层抽象设计中都采用了栈式镜像层存储和写时复制(Copy-on-Write)的设计思想,但是 Docker 在 Linux 底层支持几种不同的存储驱动的具体实现,每一种实现方式都采用不同方法实现了镜像层和写时复制。虽然底层实现的差异不影响用户与 Docker 之间的交互,但是对 Docker 的性能和稳定性至关重要。

在 Linux 上,Docker 可选择的一些存储驱动包括 AUFS(最原始也是最老的)、Overlay2(可能是未来的最佳选择)、Device Mapper、Btrfs 和 ZFS。

Docker 在 Windows 操作系统上只支持一种存储驱动,即 Windows Filter。

存储驱动的选择是节点级别的。每个 Docker 主机只能选择一种存储驱动,不能为每个容器选择不同的存储驱动。

在 Linux 上,可以通过修改 /etc/docker/daemon.json 文件来修改存储引擎配置,修改完成之后需要重启 Docker 才能够生效。

下面的代码片段展示了如何将存储驱动设置为 overlay2。

{ "storage-driver": "overlay2" }

如果配置所在行不是文件的最后一行,则需要在行尾处增加逗号。

如果读者修改了正在运行 Docker 主机的存储引擎类型,则现有的镜像和容器在重启之后将不可用,这是因为每种存储驱动在主机上存储镜像层的位置是不同的(通常在 /var/lib/docker/ <storage-driver>/... 目录下)。

修改了存储驱动的类型,Docker 就无法找到原有的镜像和容器了。切换到原来的存储驱动,之前的镜像和容器就可以继续使用了。

如果希望在切换存储引擎之后还能够继续使用之前的镜像和容器,需要将镜像保存为 Docker 格式,上传到某个镜像仓库,修改本地 Docker 存储引擎并重启,之后从镜像仓库将镜像拉取到本地,最后重启容器。

下面的命令检查 Docker 当前的存储驱动类型。

docker system info

选择存储驱动并正确地配置在 Docker 环境中是一件重要的事情,特别是在生产环境中。

下面的清单可以作为一个参考指南,帮助我们选择合适的存储驱动。同时还可以参阅 Docker 官网上由 Linux 发行商提供的最新文档来做出选择。

Red Hat Enterprise Linux:4.x版本内核或更高版本 + Docker 17.06 版本或更高版本,建议使用 Overlay2。
    Red Hat Enterprise Linux:低版本内核或低版本的 Docker,建议使用 Device Mapper。
    Ubuntu Linux:4.x 版本内核或更高版本,建议使用 Overlay2。
    Ubuntu Linux:更早的版本建议使用 AUFS。
    SUSE Linux Enterprise Server:Btrfs。

需要时刻关注 Docker 文档中关于存储驱动的最新支持和版本兼容列表,尤其是正在使用 Docker 企业版(EE),并且有售后支持合同的情况下,更有必要查阅最新文档。

Device Mapper 配置
大部分 Linux 存储驱动不需要或需要很少的配置。但是,Device Mapper 通常需要合理配置之后才能表现出良好的性能。默认情况下,Device Mapper 采用 loopback mounted sparse file 作为底层实现来为 Docker 提供存储支持。

如果需要的是开箱即用并且对性能没什么要求,那么这种方式是可行的。但这并不适用于生产环境。实际上,默认方式的性能很差,并不支持生产环境。

为了达到 Device Mapper 在生产环境中的最佳性能,需要将底层实现修改为 direct-lvm 模式。这种模式下通过使用基于裸块设备(Raw Block Device)的 LVM 精简池(LVM thin pool)来获取更好的性能。在 Docker 17.06 以及更高的版本中可以配置 direct-lvm 作为存储驱动。

其中最主要的一点是,这种方式只能配置一个块设备,并且只有在第一次安装后才能设置生效。未来可能会有改进,但就目前情况来看配置单一块设备这种方式在性能和可靠性上都有一定的风险。

让 Docker 自动设置 direct-lvm
下面的步骤会将 Docker 配置存储驱动为 Device Mapper,并使用 direct-lvm 模式。

1) 将下面的存储驱动配置添加到 /etc/docker/daemon.json 当中。

{
"storage-driver": "devicemapper",
"storage-opts": [
        "dm.directlvm_device=/dev/xdf",
        "dm.thinp_percent=95",
        "dm.thinp_metapercent=1",
        "dm.thinp_autoextend_threshold=80",
        "dm.thinp_autoextend_percent=20",
        "dm.directlvm_device_force=false"
    ]
}
Device Mapper 和 LVM 是很复杂的知识点,下面简单介绍一下各配置项的含义。

dm.directlvm_device:设置了块设备的位置。为了存储的最佳性能以及可用性,块设备应当位于高性能存储设备(如本地 SSD)或者外部 RAID 存储阵列之上。
    dm.thinp_percent=95:设置了镜像和容器允许使用的最大存储空间占比,默认是 95%。
    dm.thinp_metapercent:设置了元数据存储(MetaData Storage)允许使用的存储空间大小。默认是 1%。
    dm.thinp_autoextend_threshold:设置了 LVM 自动扩展精简池的阈值,默认是 80%。
    dm.thinp_autoextend_percent:表示当触发精简池(thin pool)自动扩容机制的时候,扩容的大小应当占现有空间的比例。
    dm.directlvm_device_force:允许用户决定是否将块设备格式化为新的文件系统。

2) 重启 Docker。

3) 确认 Docker 已成功运行,并且块设备配置已被成功加载。

$ docker system info

主要看以下信息更改了没有

Storage Driver: devicemapper
Pool Name: docker-thinpool
Pool Blocksize: 524.3 kB
Base Device Size: 25 GB
Backing Filesystem: xfs

即使 Docker 在 direct-lvm 模式下只能设置单一块设备,其性能也会显著优于 loopback 模式。

手动配置 Device Mapper 的 direct-lvm
1) 块设备(Block Device)
在使用 direct-lvm 模式的时候,需要有可用的块设备。这些块设备应该位于高性能的存储设备之上,比如本地 SSD 或者外部高性能 LUN 存储。

如果 Docker 环境部署在企业私有云(On-Premise)之上,那么外部 LUN 存储可以使用 FC、iSCSI,或者其他支持块设备协议的存储阵列。

如果 Docker 环境部署在公有云之上,那么可以采用公有云厂商提供的任何高性能的块设备(通常基于 SSD)。
2) LVM配置
Docker 的 Device Mapper 存储驱动底层利用 LVM(Logical Volume Manager)来实现,因此需要配置 LVM 所需的物理设备、卷组、逻辑卷和精简池。应当使用专用的物理卷并将其配置在相同的卷组当中。这个卷组不应当被 Docker 之外的工作负载所使用。

此外还需要配置额外两个逻辑卷,分别用于存储数据和源数据信息。另外,要创建 LVM 配置文件、指定 LVM 自动扩容的触发阈值,以及自动扩容的大小,并且为自动扩容配置相应的监控,保证自动扩容会被触发。
3) Docker 配置
修改 Docker 配置文件之前要先保存原始文件(etc/docker/daemon.json),然后再进行修改。

环境中的 dm.thinpooldev 配置项对应值可能跟下面的示例内容有所不同,需要修改为合适的配置。

{
    "storage-driver": "devicemapper",
    "storage-opts": [
        "dm.thinpooldev=/dev/mapper/docker-thinpool",
        "dm.use_deferred_removal=true",
        "dm.use_deferred_deletion=true"
    ]
}
修改并保存配置后,重启 Docker daemon。

Docker存储驱动相关推荐

  1. Docker存储驱动之OverlayFS简介

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

  2. DOCKER存储驱动之DEVICE MAPPER简介

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

  3. Docker——docker存储驱动原理

    摘要 Docker 主要是基于 Namespace.cgroups 和联合文件系统这三大核心技术实现的.联合文件系统(Union File System,Unionfs)是一种分层的轻量级文件系统,它 ...

  4. Docker存储驱动devicemapper介绍和配置

    一.devicemapper介绍 1 2 3 4 5 6 7 8 9 Device Mapper是Linux系统中基于内核的高级卷管理技术框架.Docker的devicemapper存储驱动就是基于该 ...

  5. docker存储驱动模式之direct-lvm配置

    最近在虚拟机上玩docker,但是发现默认安装使用的是loop-lvm的模式做后端存储,这个肯对对后面的实验会造成影响,而且docker官方也不建议在生产环境下使用loop-lvm,下图为docker ...

  6. docker 存储驱动之overlay

    overlay OverlayFS是一个类似于AUFS 的现代联合文件系统,但更快,实现更简单.Docker为OverlayFS提供了一个存储驱动程序. * 注:OverlayFS是内核提供的文件系统 ...

  7. docker 存储驱动之overlay2

    overlay2 overlay2原生支持128层,这提供docker build和docker commit更好的性能支持 在执行完docker pull ubuntu后,可以看到 $ ls -l ...

  8. Docker 存储选型,这些年我们遇到的坑

    戳蓝字"CSDN云计算"关注我们哦! 技术头条:干货.简洁.多维全面.更多云计算精华知识尽在眼前,get要点.solve难题,统统不在话下! 随着Docker 容器技术的不断发展和 ...

  9. 关于docker的存储驱动

    2019独角兽企业重金招聘Python工程师标准>>> #背景 一直以来我的业务都是跑在aufs+ext4的存储驱动结构上,看上去没有什么问题,直到业务报告: 在高并发场景下,auf ...

最新文章

  1. 如何防范Fintech创新中的人工智能、大数据、区块链、云计算技术风险?
  2. 运维笔记--ubuntu安装指定版本的RabbitMQ
  3. SEO优化可以从这几个方面着手
  4. python应用于财务-用6行python代码做一个财务机器人
  5. 进程间通信(1) dll 实现进程的内存共享
  6. mysql 笔试题_MySQL笔试题详解(一)(中等难度)
  7. java学习(55):定义一个抽象类的继承
  8. java基础—IO流——复制一个文件到当前文件夹中
  9. python调用hive与java调用区别_python3.6.5基于kerberos认证的hive和hdfs连接调用方式
  10. error while loading shared libraries: libxx.so: cannot open shared object file: No such file
  11. 利用Python+xarray实现遥感数据——海表温度的经验正交函数(EOF)分解——xarray学习文档02
  12. BUU-CRYPTO1密码学小白 25道入门题 详细解题思路
  13. 基于Vue.js的2048小游戏的设计与实现
  14. 哈斯图 寻找 极小元与极大元 最小元与最大元 上界与下界 最小上界(上确界)和最大下界(下确界)(一看就会)附一练习题
  15. 37岁的老大叔零基础学python,来点鼓励吧
  16. 最浪漫的程序员表白代码打动美人心
  17. 《九日集训》第四天打卡
  18. HTML 全页面内容自由编辑与 HTML 页面全部黑白风格处理
  19. 神牛TT685C闪光灯ETTL模式不同步解决方案
  20. curl 实现qq挂号登录

热门文章

  1. pip设置socks5代理
  2. 12864液晶串口图片显示
  3. c语言未定义标识符using,c++未定义标识符怎么办?
  4. Vi编辑器常用命令以及Shell编程
  5. iOS 获取相册中视频大小
  6. 【VS2017】【Windows SDK】找不到 Windows SDK 版本10.0.18362.0的解决办法
  7. 初识AI——python编程——工具准备
  8. 利用Python爬虫网上的漂亮妹子图
  9. python中print语法错误_Python 3.x中使用print函数出现语法错误(SyntaxError: invalid syntax)的原因...
  10. 借一个项目谈Android应用软件架构,你还在套用MVP 或MVVM吗