一,前言
衆所周知,docker鏡像技術的基礎是聯合檔案系統(UnionFS),其檔案系統是分層的,那它的分層機制是什麼樣的呢?共分為幾種層呢?又是怎麼工作的呢?
目前docker支援的聯合檔案系統有很多種,包括:AUFS、overlay、overlay2、DeviceMapper、VSF等
Linux 中各發行版實作的 UnionFS 各不相同,是以docker在不同 linux 發行版中使用的也不同。通過docker info 指令可以檢視目前系統所使用哪種 UnionFS,常見的幾種發行版使用如下:
CentOS, Storage Driver: overlay2、overlay
debain, Storage Driver: aufs
RedHat, Storage Driver: devicemapper
二,介紹
下面我們就以Centos發行版的overlay2檔案系統進行介紹,其實不管是什麼發行版,其原理都如出一轍。
先來看張圖:

從上述圖中可以看到三個層結構,即lowerdir、upperdir、merged層
對應的,使用docker inspect [容器ID]就可以看到這幾個層所在的位置
"GraphDriver": {
"Name": "overlay2",
"Data": {
"LowerDir": "/var/lib/docker/overlay2/45abab78c6fd022d9ce132a0fb995f9e91bc0a807ccc73e2461fce6c9b68b250/root",
"MergedDir": "/var/lib/docker/overlay2/dc838cbc7d903a4bfd6bd0280a6910c063f2d1f03439e917ebc773fccc377402/merged",
"UpperDir": "/var/lib/docker/overlay2/dc838cbc7d903a4bfd6bd0280a6910c063f2d1f03439e917ebc773fccc377402/upper",
"WorkDir": "/var/lib/docker/overlay2/dc838cbc7d903a4bfd6bd0280a6910c063f2d1f03439e917ebc773fccc377402/work"
}
},
1、lowerdir層:
其中lowerdir是隻讀的鏡像層(image layer),其中就包含bootfs/rootfs層,bootfs(boot file system)主要包含bootloader和kernel,bootloader主要是引導加載kernel,當boot成功 kernel 被加載到記憶體中,bootfs就被umount了,rootfs(root file system)包含的就是典型Linux系統中的/dev、/proc、/bin、/etc等标準目錄。
lowerdir是可以分很多層的,除了bootfs/rootfs層以外,還可以通過Dockerfile建立很多image層,建構過程如下:
Dockerfile中每一個指令都會生成一個新的image層,如上圖所示。
當FROM時就已經生成了bootfs/rootfs層,也就是kernel和base層。
2、upperdir層
upperdir層是lowerdir的上一層,隻有這一層可讀可寫的,其實就是Container層,在啟動一個容器的時候會在最後的image層的上一層自動建立,所有對容器資料的更改都會發生在這一層。
3、merged層
merged層就是聯合挂載層,也就是給使用者暴露的統一視覺,将image層和container層結合,就如最上邊的圖中描述一緻,同一檔案,在此層會展示離它最近的層級裡的檔案内容,或者可以了解為,隻要container層中有此檔案,便展示container層中的檔案内容,若container層中沒有,則展示image層中的。
三,聯合挂載系統的工作原理
1、讀:
如果檔案在upperdir(容器)層,直接讀取檔案;
如果檔案不在upperdir(容器)層,則從鏡像層(lowerdir)讀取;
2、寫:
首次寫入:如果upperdir中不存在,overlay和overlay2執行copy_up操作,把檔案從lowdir拷貝到upperdir中,由于overlayfs是檔案級别的(即使隻有很少的一點修改,也會産生copy_up的動作),後續對同一檔案的再次寫入操作将對已經複制到容器層的檔案副本進行修改,這也就是嘗嘗說的寫時複制(copy-on-write)。
删除檔案或目錄:當檔案被删除時,在容器層(upperdir)建立whiteout檔案,鏡像層(lowerdir)的檔案是不會被删除的,因為它們是隻讀的,但without檔案會阻止它們顯示,當目錄被删除時,在容器層(upperdir)一個不透明的目錄,這個和上邊的whiteout的原理一樣,組織使用者繼續通路,image層不會發生改變
3、注意事項
- copy_up操作隻發生在檔案首次寫入,以後都是隻修改副本,
- overlayfs隻适用兩層目錄,,相比于比AUFS,查找搜尋都更快。
- 容器層的檔案删除隻是一個“障眼法”,是靠whiteout檔案将其遮擋,image層并沒有删除,這也就是為什麼使用docker commit 送出儲存的鏡像會越來越大,無論在容器層怎麼删除資料,image層都不會改變。
4、容器整體構成圖
此圖中沒有展現聯合挂載層
四,docker與VM的對比
帶着問題看事物,docker容器為什麼啟動這麼快呢???
先來看一張docker與VM的對比圖:
可以清楚的看到,VM比docker多了Hypervisor 和 Guest OS的過程,也正是省略了這些過程使docker技高一籌,問題又來了,為什麼docker可以省略這些過程呢?
- Hypervisor:主要作用是實作硬體資源虛拟化;因為docker容器上程式直接使用的都是實體機的硬體資源,是以不需要資源虛拟化的過程,也是以在CPU、記憶體使用率上docker将會在效率上明顯提高