1. 程式人生 > >docker 儲存驅動之overlay

docker 儲存驅動之overlay

overlay

OverlayFS是一個類似於AUFS 的現代聯合檔案系統,但更快,實現更簡單。Docker為OverlayFS提供了一個儲存驅動程式。
* 注:OverlayFS是核心提供的檔案系統,overlay和overlay2是docker提供的儲存驅動

設定儲存方式

編輯/etc/docker/daemon.json

{
  "storage-driver": "overlay2",
  "storage-opts": [
    "overlay2.override_kernel_check=true"
  ]
}

overlay原理

OverlayFS將單個Linux主機上的兩個目錄合併成一個目錄。這些目錄被稱為層,統一過程被稱為聯合掛載。OverlayFS關聯的底層目錄稱為lowerdir,
對應的高層目錄稱為upperdir。合併過後統一檢視稱為merged。

下圖是一個docker映象和docke容器的分層圖,docker映象是lowdir,docker容器是upperdir。而統一的檢視層是merged層
這裡寫圖片描述

當映象層和容器層都有相同的檔案時候,使用容器層的檔案,overlay驅動使用兩層,這就意味著,如果是多層的映象就無法使用了,替代的方案是:
每個映象層都在/var/lib/docker/overlay目錄下,通過硬連結的方式把下部的層關聯起來
Docker1.10之後,映象層ID和/var/lib/docker中的目錄名不再一一對應。

$ docker pull ubuntu

Using default tag: latest
latest: Pulling from library/ubuntu

5
ba4f30e5bea: Pull complete 9d7d19c9dc56: Pull complete ac6ad7efd0f9: Pull complete e7491a747824: Pull complete a3ed95caeb02: Pull complete Digest: sha256:46fb5d001b88ad904c5c732b086b596b92cfb4a4840a3abd0e35dbb6870585e4 Status: Downloaded newer image for ubuntu:latest

每個層都在/var/lib/docker/overlay/目錄下面:

$ ls -l /var
/lib/docker/overlay/ total 20 drwx------ 3 root root 4096 Jun 20 16:11 38f3ed2eac129654acef11c32670b534670c3a06e483fce313d72e3e0a15baa8 drwx------ 3 root root 4096 Jun 20 16:11 55f1e14c361b90570df46371b20ce6d480c434981cbda5fd68c6ff61aa0a5358 drwx------ 3 root root 4096 Jun 20 16:11 824c8a961a4f5e8fe4f4243dab57c5be798e7fd195f6d88ab06aea92ba931654 drwx------ 3 root root 4096 Jun 20 16:11 ad0fe55125ebf599da124da175174a4b8c1878afe6907bf7c78570341f308461 drwx------ 3 root root 4096 Jun 20 16:11 edab9b5e5bf73f2997524eebeac1de4cf9c8b904fa8ad3ec43b3504196aa3801

overlay驅動程式只能使用一個較低的OverlayFS層,因此需要硬連結來實現多層影象。
映象層目錄包含對該映象層唯一檔案以及較低層通過硬連結的共享資料,這樣做可以節省空間。

$ ls -i /var/lib/docker/overlay/38f3ed2eac129654acef11c32670b534670c3a06e483fce313d72e3e0a15baa8/root/bin/ls

19793696 /var/lib/docker/overlay/38f3ed2eac129654acef11c32670b534670c3a06e483fce313d72e3e0a15baa8/root/bin/ls

$ ls -i /var/lib/docker/overlay/55f1e14c361b90570df46371b20ce6d480c434981cbda5fd68c6ff61aa0a5358/root/bin/ls

19793696 /var/lib/docker/overlay/55f1e14c361b90570df46371b20ce6d480c434981cbda5fd68c6ff61aa0a5358/root/bin/ls

兩層的ls都是使用相同的ls二進位制檔案

容器層也位於/var/lib/docker/overlay/

$ ls -l /var/lib/docker/overlay/<directory-of-running-container>

total 16
-rw-r--r-- 1 root root   64 Jun 20 16:39 lower-id
drwxr-xr-x 1 root root 4096 Jun 20 16:39 merged
drwxr-xr-x 4 root root 4096 Jun 20 16:39 upper
drwx------ 3 root root 4096 Jun 20 16:39 work

其中,該lower-id是容器映象圖頂層的ID,即Ove​​rlayFS lowerdir。

$ cat /var/lib/docker/overlay/ec444863a55a9f1ca2df72223d459c5d940a721b2288ff86a3f27be28b53be6c/lower-id

55f1e14c361b90570df46371b20ce6d480c434981cbda5fd68c6ff61aa0a5358

該upper目錄包含與OverlayFS相對應的容器的讀寫層的內容upperdir。

該merged目錄是lowerdirand 的聯合裝載upperdir,它包含正在執行的容器內的檔案系統的檢視。

該work目錄是OverlayFS內部的。

通過mount檢視overlay檔案的掛載

$ mount | grep overlay

overlay on /var/lib/docker/overlay/ec444863a55a.../merged
type overlay (rw,relatime,lowerdir=/var/lib/docker/overlay/55f1e14c361b.../root,
upperdir=/var/lib/docker/overlay/ec444863a55a.../upper,
workdir=/var/lib/docker/overlay/ec444863a55a.../work)

在第二行的rw顯示出overlay這層是可寫的

檔案操作

那麼當我們讀寫檔案的時候各層是怎樣合作的呢?下面逐一來看,在此overlay和overlay2的行為是一樣的

  • 如果該檔案在容器層不存在:檔案不存在upperdir中,則從lowdir中讀取
  • 只在容器層存在: 檔案只存在upperdir中,則直接從容器中讀取改檔案
  • 檔案同事存在容器曾和映象層:容器層upperdir會覆蓋映象層lowdir中的檔案

修改

  • 首次寫入: 改檔案在upperdir中不存在,在overlay和overlay2中,執行copy_up操作,把檔案從lowdir拷貝到upperdir。然後所以的更改都是在容器
    層內修改副本的操作,由於overlayfs是檔案級別的,不是塊級別的,這就意味著即使檔案只有很少的一點修改,也會產生的copy_up的行為,不過有兩點需要
    注意:
    copy_up操作只發生在檔案首次寫入,以後都是隻修改副本
    overlayfs只適用兩層,因此效能很好,查詢搜尋都更快

  • 刪除檔案和目錄: 當檔案在容器被刪除時,在容器層(upperdir)建立whiteout檔案,映象層的檔案是不會被刪除的,因為他們是隻讀的,但without檔案
    會阻止他們展現,當目錄在容器內被刪除時,在容器層(upperdir)一個不透明的目錄,這個和上面whiteout原理一樣,阻止使用者繼續訪問,即便映象層仍然
    存在

重新命名

rename(2)這個系統呼叫只在源和目標都在頂層,否則會報 error (“cross-device link not permitted”)

效能對比

使用overlay和overlay2驅動效能好於aufs和devicemapper,在實際生產環境overlay2的效能高於btrfs,但還有一些細節
* 頁快取:overlayfs支援頁快取共享,也就是說如果多個容器訪問同一個檔案,可以共享同一個頁快取。這使得overlay/overlay2驅動高效地利用了記憶體
* copy_up:aufs和overlayfs,由於第一次寫入都會導致copy_up,尤其是大檔案,會導致寫延遲,以後的寫入不會有問題。由於overlayfs層級
比aufs的多,所以ovelayfs的拷貝高於aufs
* inode限制:使用overlay儲存驅動可能導致inode過度消耗,特別是當容器和映象很多的情況下,所以建議使用overlay2.

高效能建議

  • 使用高效能磁碟如:SSD
  • 如果是搞IO:建議使用外掛高效能盤

但 overlay2驅動程式本身最多支援128個較低的OverlayFS層。此功能可為與層相關的Docker命令(如docker buildand)提供更好的效能docker commit,並在後備檔案系統上佔用更少的inode。