## 向您推薦
[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層,每一層都由一些只讀并且描繪系統區別的文件組成.

上下兩張圖對比,可以清晰的看到鏡像分層關系(上圖是官方文檔圖片,可以看到鏡像大小進行了精簡,但是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 存儲驅動的職責就是將鏡像層和可寫容器層管理起來.不同的驅動實現管理的方式也不一致.實現容器與鏡像管理的兩個關鍵技術就是可堆疊的鏡像層和copy-on-write (CoW,寫時復制).
## 簡述寫時復制
舉個例子:小文和小武由不同的老師上數學課,但是他們只有一個習題冊.小文的作業是,練習冊的第十一頁.為了不影響到小武,小文的做法是將第11頁copy,完成作業后上交.這就是一個典型的**寫時復制**
第一次修改一個文件,這個文件首先會從該讀寫層下面的只讀層復制到該讀寫層。該文件的只讀版本依然存在,但是已經被讀寫層中的該文件副本所隱藏。
> 了解了寫時復制,就應該注意一個問題:如果第一次修改鏡像層內包含的文件,文件的size很大.會造成大量的磁盤IO的開銷.所以不建議將需要修改的大文件,集成到鏡像內.可以采用數據卷的方式.
## 數據卷與存儲驅動
當一個容器刪除的時候,寫入該容器的所有數據將被刪除(除了保存在數據卷中的數據)
數據卷是掛載到容器的,docker宿主機上的一個目錄或文件。對數據卷的文件讀寫是不受存儲驅動控制的,接近于本地文件系統讀寫速度.可以掛載多個數據卷到一個容器.也可以多個容器共享一個或多個數據卷.
如圖所示:一個docker宿主機運行2個容器。每個容器有自己的存儲空間,存儲于宿主機本地文件系統 /var/lib/docker/... 另外有一個共享的數據卷在 /data.掛載到兩個容器內實現共享.

## 如何選擇存儲驅動
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.
下面的圖表,顯示了每個存儲驅動的優勢以及不足,請參考:

## 具體到某一個存儲驅動
> 這部分介紹具體的存儲驅動的實現方式,對于技術研究者可以參考學習.對于應用實踐者,可以暫時止步.筆者看了這部分內容,沒有進行翻譯總結.留下待以后完成.
### 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集群
- 其他