本文的目的
Docker原生提供了多種存儲驅(qū)動,用戶需要做的是結(jié)合自己的場景選用其中之一。沒有一種存儲驅(qū)動是適合所有場景的。本文先簡單介紹如下幾種存儲驅(qū)動:AUFS、DeviceMapper、Btrfs、overlayFs、ZFS,之后說明PPTV在構(gòu)建DCOS的選型過程。
如何指定存儲驅(qū)動
用戶決定使用哪款驅(qū)動,要在Docker守護進程啟動時指定,當然指定的驅(qū)動必須被底層操作系統(tǒng)支持。如更換存儲驅(qū)動,需重啟守護進程。指定存儲驅(qū)動的方法可參考Docker官網(wǎng),操作簡單方便。各存儲驅(qū)動都封裝了統(tǒng)一接口供守護進程調(diào)用,一旦完成初始化,存儲驅(qū)動的差異對守護進程來說是透明的。
Copy alt="物聯(lián)網(wǎng)" width="550" height="303" />
圖1 AUFS鏡像層容器層
DeviceMapper
DeviceMapper使用預分配技術(shù)來實現(xiàn)鏡像分層,DeviceMapper的寫時復制技術(shù)是基于塊級別的,不同于AUFS基于文件級別。當Docker守護進程啟動時,會創(chuàng)建預分配機制所必須的兩個塊設(shè)備:用作存儲池的數(shù)據(jù)設(shè)備和維護元數(shù)據(jù)的設(shè)備,守護進程在預分配的存儲池上創(chuàng)建一個基礎(chǔ)設(shè)備,所有新的鏡像層都是基礎(chǔ)設(shè)備的一個快照,基礎(chǔ)設(shè)備的大小默認為10GB,可以在守護進程啟動時通過dm.basesize參數(shù)來修改這一配置。DeviceMapper有兩種模式,默認為loop模式,生產(chǎn)環(huán)境建議使用direct-lvm模式,原因為loop模式是基于兩個稀疏文件創(chuàng)建虛擬的塊設(shè)備的,影響性能。

圖2 DeviceMapper鏡像層容器層
Btrfs
Btrfs以塊為單位存儲數(shù)據(jù),一個塊就是一段原始存儲。Docker利用Btrfs的子卷特性,每一個新創(chuàng)建的容器都會被分配一個新的Btrfs子卷,如果存在父鏡像層,那么它會以父鏡像層子卷的一個快照的形式創(chuàng)建。

圖3 Btrfs鏡像層容器層
OverlayFs
OverlayFs是一個聯(lián)合文件系統(tǒng),與AUFS的做法有些類似,由于合并目錄,overlayFs在查找效率方面作了不小的改進,不同于AUFS鏡像層越多則查找時間越長?;趏verlayFs技術(shù)有兩種存儲驅(qū)動:overlay與overlay2,根據(jù)官方文檔,overlay要求內(nèi)核版本3.18以上,overlay2要求內(nèi)核版本4.0以上。但是我們經(jīng)過嘗試,可以在3.10內(nèi)核使用overlay。

圖4 overlay鏡像層容器層
ZFS
ZFS是Sun公司(現(xiàn)在的Oracle)發(fā)明的并在CDDL條款下開源。而由于CDDL與GPL開源條款的不兼容,ZFS無法并入Linux內(nèi)核主線。不過ZFS alt="物聯(lián)網(wǎng)" width="550" height="294" />
圖5 ZFS鏡像層容器層
我們的現(xiàn)狀
在過去的一段時間,我們使用loop模式的DeviceMapper作為存儲驅(qū)動,是Docker默認的,在使用過程中遇到一些問題。
[[email protected] Deploy]# docker stop
b977235038bce3176279bdd27cf84b12755eff0ed08d6a11b09e5e8e97480f78
b977235038bce3176279bdd27cf84b12755eff0ed08d6a11b09e5e8e97480f78
[[email protected] Deploy]# docker rm
b977235038bce3176279bdd27cf84b12755eff0ed08d6a11b09e5e8e97480f78
Error response from daemon: Driver devicemapperfailed to remove root filesystem
b977235038bce3176279bdd27cf84b12755eff0ed08d6a11b09e5e8e97480f78
: Device is Busy
如上面所示問題,不只一次出現(xiàn),目前都沒有完全解決,最終只能用重啟Docker的方法,如果在生產(chǎn)環(huán)境中遇到這樣的問題,應該是大家不希望看到的。
我們分析產(chǎn)生該問題的原因還是在于loop模式的的devicemapper所用的數(shù)據(jù)設(shè)備和元數(shù)據(jù)設(shè)備都只是綁定到回環(huán)設(shè)備上的稀疏文件,如不做特別的配置,這些文件大小一般看上去是100GB(如下圖所示loop0)和2GB(如下圖所示loop1),由于使用預分配機制,在實際寫入數(shù)據(jù)之前,并不會真正占用100GB和2GB的磁盤空間。這樣的機制讓我們想到兩個問題:1、稀疏文件性能不太好,且文件本身可能會損壞;2、由于預分配機制,待需要占用的時候,如果實際磁盤空間已經(jīng)沒有那么多了,就會發(fā)生異常。
[[email protected]]#lsblk
NAME MAJ:MINRM SIZE RO TYPE MOUNTPOINT
fd0 8:0 0 4k 0 disk