## 向您推荐
[Dcoker入门与实践系列文章](http://www.zimug.com/360.html)
欢迎加入QQ技术交流群:300139299
## 前言
本文大部分内容,摘自docker官方文档.[Understand images, containers, and storage drivers](https://docs.docker.com/engine/userguide/storagedriver/imagesandcontainers/)
译者没有采取原文翻译的方式,而是结合自己的学习进行了归纳总结.
要想真正的理解docker的存储驱动,需要先了解docker镜像是如何构建和存储,以及容器如何使用镜像.
## 镜像与分层
下面是ubuntu:15.04的镜像分层.一共是4层,每一层都由一些只读并且描绘系统区别的文件组成.
![docker镜像与分层](http://7xqnvr.com1.z0.glb.clouddn.com/%E5%A6%82%E4%BD%95%E9%80%89%E6%8B%A9docker%E5%AD%98%E5%82%A8%E9%A9%B1%E5%8A%A81.png)
上下两张图对比,可以清晰的看到镜像分层关系(上图是官方文档图片,可以看到镜像大小进行了精简,但是ubuntu:15.04镜像的分层结构没变).
```
docker history ubuntu:15.04
IMAGE CREATED CREATED BY SIZE COMMENT
d1b55fd07600 4 months ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0 B
<missing> 4 months ago /bin/sh -c sed -i 's/^#\s*\(deb.*universe\)$/ 1.879 kB
<missing> 4 months ago /bin/sh -c echo '#!/bin/sh' > /usr/sbin/polic 701 B
<missing> 4 months ago /bin/sh -c #(nop) ADD file:3f4708cf445dc1b537 131.3 MB
```
**Docker存储驱动的作用就是:将这些分层的镜像文件堆叠起来,并且提供统一的视图.使container的文件系统看上去和我们普通的文件系统没什么区别.**
当创建一个新的容器的时候,实际上是在镜像的分层上新添加了一层container layer(容器层).之后所有对容器产生的修改,实际都只影响这一层.
![docker镜像与分层2](http://7xqnvr.com1.z0.glb.clouddn.com/%E5%A6%82%E4%BD%95%E9%80%89%E6%8B%A9docker%E5%AD%98%E5%82%A8%E9%A9%B1%E5%8A%A82.png)
**注意**
* 容器层:读写层(可写层)
* 镜像层:只读层
## 容器与分层
镜像与容器的一个主要区别就是,是否具有顶层的读写层(可写层).对于一个容器的数据新增,修改,都存储在可写层.当你删除一个容器的时候,可写层也将被删除(注意:可写层与数据卷的区别).然而镜像层是保持不变的.
下图展示了,多个容器共享一个镜像.镜像层是只读层,不变的.多个容器层在同一个镜像层之上,并且相互独立,互相不影响.
![docker容器与分层](http://7xqnvr.com1.z0.glb.clouddn.com/%E5%A6%82%E4%BD%95%E9%80%89%E6%8B%A9docker%E5%AD%98%E5%82%A8%E9%A9%B1%E5%8A%A83.png)
docker 存储驱动的职责就是将镜像层和可写容器层管理起来.不同的驱动实现管理的方式也不一致.实现容器与镜像管理的两个关键技术就是可堆叠的镜像层和copy-on-write (CoW,写时复制).
## 简述写时复制
举个例子:小文和小武由不同的老师上数学课,但是他们只有一个习题册.小文的作业是,练习册的第十一页.为了不影响到小武,小文的做法是将第11页copy,完成作业后上交.这就是一个典型的**写时复制**
第一次修改一个文件,这个文件首先会从该读写层下面的只读层复制到该读写层。该文件的只读版本依然存在,但是已经被读写层中的该文件副本所隐藏。
> 了解了写时复制,就应该注意一个问题:如果第一次修改镜像层内包含的文件,文件的size很大.会造成大量的磁盘IO的开销.所以不建议将需要修改的大文件,集成到镜像内.可以采用数据卷的方式.
## 数据卷与存储驱动
当一个容器删除的时候,写入该容器的所有数据将被删除(除了保存在数据卷中的数据)
数据卷是挂载到容器的,docker宿主机上的一个目录或文件。对数据卷的文件读写是不受存储驱动控制的,接近于本地文件系统读写速度.可以挂载多个数据卷到一个容器.也可以多个容器共享一个或多个数据卷.
如图所示:一个docker宿主机运行2个容器。每个容器有自己的存储空间,存储于宿主机本地文件系统 /var/lib/docker/... 另外有一个共享的数据卷在 /data.挂载到两个容器内实现共享.
![docker数据卷与存储驱动](http://7xqnvr.com1.z0.glb.clouddn.com/%E5%A6%82%E4%BD%95%E9%80%89%E6%8B%A9docker%E5%AD%98%E5%82%A8%E9%A9%B1%E5%8A%A84.png)
## 如何选择存储驱动
docker目前支持的存储驱动有:OverlayFS,AUFS,Btrfs,Device Mapper,VFS,ZFS。
* docker的存储驱动目前并没有一个通用的,完美的,适用于所有环境的存储驱动.所以需要根据自己的环境来有所选择.
* 存储驱动在不断的改进与发展
* 如果从稳定性上的考量,在安装docker的时候会默认根据你的系统环境配置选择一个存储驱动.通常来说使用这个默认的驱动将减少你遇到bug的机会.
* 如果你的团队使用过RHEL及其相关分支,你可能有关于LVM和Device Mapper的经验.这时建议你使用devicemapper存储驱动.
查看当前docker 引擎的存储驱动
```
#docker info
Containers: 0
Running: 0
Paused: 0
Stopped: 0
Images: 24
Server Version: 1.10.2
Storage Driver: aufs
Root Dir: /var/lib/docker/aufs
Backing Filesystem: extfs
Dirs: 52
Dirperm1 Supported: true
```
如图所示:存储驱动类型为aufs,宿主机文件系统的格式为extfs。
#### 存储驱动与宿主机文件格式
|存储驱动|通常被使用在(宿主机fs格式)|不支持的fs格式|
|--|--|--|
|overlay|ext4 xfs|btrfs aufs overlay overlay2 zfs eCryptfs|
|overlay2|ext4 xfs|btrfs aufs overlay overlay2 zfs eCryptfs|
|aufs|ext4 xfs|btrfs aufs eCryptfs|
|btrfs|btrfs only|N/A|
|devicemapper|direct-lvm|N/A|
|vfs|debugging only|N/A|
|zfs|zfs only|N/A|
#### 设置docker的存储驱动
* 方法一:如设置存储驱动的类型为devicemapper
```
$ dockerd --storage-driver=devicemapper &
```
* 方法二:如设置存储驱动的类型为devicemapper,在DOCKER_OPTS配置参数的最后面加上--storage-driver=devicemapper
```
vim /etc/default/docker
DOCKER_OPTS="<其他配置项> --storage-driver=devicemapper"
```
#### 现状与未来
许多人认为OverlayFS是Docker存储驱动的未来.然而,它仍然不够成熟.稳定性上也不如一些成熟的存储驱动,如:AUFS,devicemapper.
下面的图表,显示了每个存储驱动的优势以及不足,请参考:
![docker存储驱动现状未来](http://7xqnvr.com1.z0.glb.clouddn.com/%E5%A6%82%E4%BD%95%E9%80%89%E6%8B%A9docker%E5%AD%98%E5%82%A8%E9%A9%B1%E5%8A%A85.png)
## 具体到某一个存储驱动
> 这部分介绍具体的存储驱动的实现方式,对于技术研究者可以参考学习.对于应用实践者,可以暂时止步.笔者看了这部分内容,没有进行翻译总结.留下待以后完成.
### AUFS
[Docker and AUFS in practice](https://docs.docker.com/engine/userguide/storagedriver/aufs-driver/)
### device mapper
[Docker and the Device Mapper storage driver](https://docs.docker.com/engine/userguide/storagedriver/device-mapper-driver/)
## 写于
2016年6月21日 发布于: [字母哥博客](http://www.zimug.com)
docker技术日新月异,文中内容可能时刻发生变化.
## 向您推荐
[Dcoker入门与实践系列文章](http://www.zimug.com/360.html)
欢迎加入QQ技术交流群:300139299
- 版权
- 博客主题
- 如何不去做运行3.5G-docker镜像的工程师
- 预备主题
- FastDFS快速入门
- mysql定时创建月表
- SpringMVC-Restful
- Docker生态系统
- The Docker Ecosystem: An Introduction to Common Components
- docker监控指标
- 基于etcd服务发现的overlay跨多宿主机容器网络
- etcd:从应用场景到实现原理的全方位解读
- docker存储驱动详解
- 使用docker/engine-api操作docker
- 提升Docker安全性
- docker安全之用户资源隔离
- marathon
- 开始
- 安装mararhon
- 高可用模式
- 使用marathon
- 应用的部署
- 架构组件
- Dubbo与Zookeeper、SpringMVC整合和使用(负载均衡、容错)
- Openstack架构解析
- haproxy
- Ubuntu系统安装截图
- mesos官方文档
- 关于译者
- mesos基础
- Mesos架构
- 视频与ppt
- 让mesos跑起来
- 快速入门
- 配置
- Containerizer
- Docker Containerizer
- 监控
- 博客文章集
- 煮饺子与mesos之间妙不可言的关系
- linux运维
- 基础篇
- 进阶篇
- mysql
- Ubuntu14.04安装mysql5.6
- MySQL 5.6 replicate原理与实践
- mysql性能
- redis
- redis安装及基础知识
- redis数据结构
- redis命令
- redis数据持久化
- Redis主从复制
- redis集群
- 其他