您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關Docker存儲驅動OverlayFS有什么用的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。
OverlayFS是一種和AUFS很類似的文件系統,與AUFS相比,OverlayFS有以下特性:
1) 更簡單地設計;
2) 從3.18開始,就進入了Linux內核主線;
3) 可能更快一些。
因此,OverlayFS在Docker社區關注度提高很快,被很多人認為是AUFS的繼承者。就像宣稱的一樣,OverlayFS還很年輕。所以,在生成環境使用它時,還是需要更加當心。
Docker的overlay存儲驅動利用了很多OverlayFS特性來構建和管理鏡像與容器的磁盤結構。
自從Docker1.12起,Docker也支持overlay2存儲驅動,相比于overlay來說,overlay2在inode優化上更加高效。但overlay2驅動只兼容Linux kernel4.0以上的版本。
注意:自從OverlayFS加入kernel主線后,它在kernel模塊中的名稱就被從overlayfs改為overlay了。但是為了在本文中區別,我們使用OverlayFS代表整個文件系統,而overlay/overlay2表示Docker的存儲驅動。
OverlayFS使用兩個目錄,把一個目錄置放于另一個之上,并且對外提供單個統一的視角。這兩個目錄通常被稱作層,這個分層的技術被稱作union mount。術語上,下層的目錄叫做lowerdir,上層的叫做upperdir。對外展示的統一視圖稱作merged。
下圖展示了Docker鏡像和Docker容器是如何分層的。鏡像層就是lowerdir,容器層是upperdir。暴露在外的統一視圖就是所謂的merged。
注意鏡像層和容器層是如何處理相同的文件的:容器層(upperdir)的文件是顯性的,會隱藏鏡像層(lowerdir)相同文件的存在。容器映射(merged)顯示出統一的視圖。
overlay驅動只能工作在兩層之上。也就是說多層鏡像不能用多層OverlayFS實現。替代的,每個鏡像層在/var/lib/docker/overlay中用自己的目錄來實現,使用硬鏈接這種有效利用空間的方法,來引用底層分享的數據。注意:Docker1.10之后,鏡像層ID和/var/lib/docker中的目錄名不再一一對應。
創建一個容器,overlay驅動聯合鏡像層和一個新目錄給容器。鏡像頂層是overlay中的只讀lowerdir,容器的新目錄是可寫的upperdir。
下面的docker pull命令展示了Docker host下載一個由5層組成的鏡像。
$ sudo docker pull ubuntu Using default tag: latest latest: Pulling from library/ubuntu 5ba4f30e5bea: Pull complete 9d7d19c9dc56: Pull complete ac6ad7efd0f9: Pull complete e7491a747824: Pull complete a3ed95caeb02: Pull complete Digest: sha256:46fb5d001b88ad904c5c732b086b596b92cfb4a4840a3abd0e35dbb6870585e4 Status: Downloaded newer image for ubuntu:latest
上圖的輸出結果顯示pull了5個目錄包含了5個鏡像層,每一層在/var/lib/docker/overlay/下都有自己的目錄。還是再次提醒下,如你所見,Docker1.10之后,鏡像層和目錄名不再對應。
$ 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
鏡像層目錄中,共享的數據使用的是硬鏈接,他們的inode號相同。這樣做有效地利用了磁盤。
$ 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
容器也在/var/lib/docker/overlay/下。使用ls -l命令查看容器目錄,會發現以下文件和目錄。
$ 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
這四個文件系統對象都是OverlayFS的組件。lower-id文件包含了容器的鏡像層最頂層的ID。
$ cat /var/lib/docker/overlay/ec444863a55a9f1ca2df72223d459c5d940a721b2288ff86a3f27be28b53be6c/lower-id 55f1e14c361b90570df46371b20ce6d480c434981cbda5fd68c6ff61aa0a5358
upper目錄是容器的可讀寫層。任何對容器的改變都寫在這個目錄中。
merged目錄就是容器的mount point,這就是暴露的鏡像(lowerdir)和容器(upperdir)的統一視圖。任何對容器的改變也影響這個目錄。
work目錄是OverlayFS功能需要的,會被如copy_up之類的操作使用。
可以通過mount命令來核實上面的描述是否正確。
$ 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)
overlay驅動只工作在一個lower OverlayFS層之上,因此需要硬鏈接來實現多層鏡像,但overlay2驅動原生地支持多層lower OverlayFS鏡像(最多128層)。
因此overlay2驅動在合層相關的命令(如build和commit)中提供了更好的性能,與overlay驅動對比,消耗了更少的inode。
docker pull ubuntu下載了包含5層的鏡像,可以看到在/var/lib/docker/overlay2中,有6個目錄。
$ ls -l /var/lib/docker/overlay2 total 24 drwx------ 5 root root 4096 Jun 20 07:36 223c2864175491657d238e2664251df13b63adb8d050924fd1bfcdb278b866f7 drwx------ 3 root root 4096 Jun 20 07:36 3a36935c9df35472229c57f4a27105a136f5e4dbef0f87905b2e506e494e348b drwx------ 5 root root 4096 Jun 20 07:36 4e9fa83caff3e8f4cc83693fa407a4a9fac9573deaf481506c102d484dd1e6a1 drwx------ 5 root root 4096 Jun 20 07:36 e8876a226237217ec61c4baf238a32992291d059fdac95ed6303bdff3f59cff5 drwx------ 5 root root 4096 Jun 20 07:36 eca1e4e1694283e001f200a667bb3cb40853cf2d1b12c29feda7422fed78afed drwx------ 2 root root 4096 Jun 20 07:36 l
l目錄包含了很多軟連接,使用短名稱指向了其他層。短名稱用于避免mount參數時達到頁面大小的限制。
$ ls -l /var/lib/docker/overlay2/l total 20 lrwxrwxrwx 1 root root 72 Jun 20 07:36 6Y5IM2XC7TSNIJZZFLJCS6I4I4 -> ../3a36935c9df35472229c57f4a27105a136f5e4dbef0f87905b2e506e494e348b/diff lrwxrwxrwx 1 root root 72 Jun 20 07:36 B3WWEFKBG3PLLV737KZFIASSW7 -> ../4e9fa83caff3e8f4cc83693fa407a4a9fac9573deaf481506c102d484dd1e6a1/diff lrwxrwxrwx 1 root root 72 Jun 20 07:36 JEYMODZYFCZFYSDABYXD5MF6YO -> ../eca1e4e1694283e001f200a667bb3cb40853cf2d1b12c29feda7422fed78afed/diff lrwxrwxrwx 1 root root 72 Jun 20 07:36 NFYKDW6APBCCUCTOUSYDH4DXAT -> ../223c2864175491657d238e2664251df13b63adb8d050924fd1bfcdb278b866f7/diff lrwxrwxrwx 1 root root 72 Jun 20 07:36 UL2MW33MSE3Q5VYIKBRN4ZAGQP -> ../e8876a226237217ec61c4baf238a32992291d059fdac95ed6303bdff3f59cff5/diff
在最低層中,有個link文件,包含了前面提到的這個層對應的短名稱;還有個diff目錄,包含了這個鏡像的內容。
$ ls /var/lib/docker/overlay2/3a36935c9df35472229c57f4a27105a136f5e4dbef0f87905b2e506e494e348b/ diff link $ cat /var/lib/docker/overlay2/3a36935c9df35472229c57f4a27105a136f5e4dbef0f87905b2e506e494e348b/link 6Y5IM2XC7TSNIJZZFLJCS6I4I4 $ ls /var/lib/docker/overlay2/3a36935c9df35472229c57f4a27105a136f5e4dbef0f87905b2e506e494e348b/diff bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
第二底層中,lower文件指出了該層的組成。該目錄還有diff、merged和work目錄。
$ ls /var/lib/docker/overlay2/223c2864175491657d238e2664251df13b63adb8d050924fd1bfcdb278b866f7 diff link lower merged work $ cat /var/lib/docker/overlay2/223c2864175491657d238e2664251df13b63adb8d050924fd1bfcdb278b866f7/lower l/6Y5IM2XC7TSNIJZZFLJCS6I4I4 $ ls /var/lib/docker/overlay2/223c2864175491657d238e2664251df13b63adb8d050924fd1bfcdb278b866f7/diff/ etc sbin usr var
運行容器包含的目錄同樣有著類似的文件和目錄。注意在lower文件中,使用:符號來分割不同的底層,并且順序是從高層到底層。
$ ls -l /var/lib/docker/overlay/<directory-of-running-container> $ cat /var/lib/docker/overlay/<directory-of-running-container>/lower l/DJA75GUWHWG7EWICFYX54FIOVT:l/B3WWEFKBG3PLLV737KZFIASSW7:l/JEYMODZYFCZFYSDABYXD5MF6YO:l/UL2MW33MSE3Q5VYIKBRN4ZAGQP:l/NFYKDW6APBCCUCTOUSYDH4DXAT:l/6Y5IM2XC7TSNIJZZFLJCS6I4I4
mount的結果如下:
$ mount | grep overlay overlay on /var/lib/docker/overlay2/9186877cdf386d0a3b016149cf30c208f326dca307529e646afce5b3f83f5304/merged type overlay (rw,relatime, lowerdir=l/DJA75GUWHWG7EWICFYX54FIOVT:l/B3WWEFKBG3PLLV737KZFIASSW7:l/JEYMODZYFCZFYSDABYXD5MF6YO:l/UL2MW33MSE3Q5VYIKBRN4ZAGQP:l/NFYKDW6APBCCUCTOUSYDH4DXAT:l/6Y5IM2XC7TSNIJZZFLJCS6I4I4, upperdir=9186877cdf386d0a3b016149cf30c208f326dca307529e646afce5b3f83f5304/diff, workdir=9186877cdf386d0a3b016149cf30c208f326dca307529e646afce5b3f83f5304/work)
有三種場景,容器會通過overlay只讀訪問文件。
容器層不存在的文件。如果容器只讀打開一個文件,但該容器不在容器層(upperdir),就要從鏡像層(lowerdir)中讀取。這會引起很小的性能損耗。
只存在于容器層的文件。如果容器只讀權限打開一個文件,并且容器只存在于容器層(upperdir)而不是鏡像層(lowerdir),那么直接從鏡像層讀取文件,無額外性能損耗。
文件同時存在于容器層和鏡像層。那么會讀取容器層的文件,因為容器層(upperdir)隱藏了鏡像層(lowerdir)的同名文件。因此,也沒有額外的性能損耗。
有以下場景容器修改文件。
第一次寫一個文件。容器第一次寫一個已經存在的文件,容器層不存在這個文件。overlay/overlay2驅動執行copy-up操作,將文件從鏡像層拷貝到容器層。然后容器修改容器層新拷貝的文件。
然而,OverlayFS工作在文件級別而不是塊級別。也就是說所有的OverlayFS的copy-up操作都會拷貝整個文件,即使文件非常大但卻只修改了一小部分,這在容器寫性能上有著顯著的影響。不過,有兩個方面值得注意:
? copy-up操作只發生在第一次寫文件時。后續的對同一個文件的寫操作都是直接針對拷貝到容器層的那個新文件。
? OverlayFS只工作在兩層中。這比AUFS要在多層鏡像中查找時性能要好。
刪除文件和目錄。刪除文件時,容器會在鏡像層創建一個whiteout文件,而鏡像層的文件并沒有刪除。但是,whiteout文件會隱藏它。
容器中刪除一個目錄,容器層會創建一個不透明目錄。這和whiteout文件隱藏鏡像層的文件類似。
重命名目錄。只有在源路徑和目的路徑都在頂層容器層時,才允許執行rename操作。否則,會返回EXDEV。
因此,你的應用需要能夠處理EXDEV,并且回滾操作,執行替代的“拷貝和刪除”策略。
為了給Docker配置overlay存儲驅動,你的Docker host必須運行在Linux kernel3.18版本之上,而且加載了overlay內核驅動。對于overlay2驅動,kernel版本必須在4.0或以上。OverlayFS可以運行在大多數Linux文件系統之上。不過,現在最建議在生產環境中使用ext4。
下面的步驟講述了如何在Docker host中配置使用OverlayFS。
注意:在開始配置之前,如果你已經在使用Docker daemon,并且有一些想保留的鏡像,簡易你push它們到Docker hub中。
1) 如果Docker daemon正在運行,需要先停止其運行。
$ systemctl stop docker.service
2) 檢查kernel版本,確認overlay的內核模塊是否加載。
$ uname -r 4.4.0-64-generic $ lsmod | grep overlay overlay # 如果上面命令沒有輸出,說明驅動沒有加載,可以如下操作 $ modprobe overlay
3) 使用overlay/overlay2存儲驅動來啟動Docker daemon。
$ dockerd --storage-driver=overlay2 & [1] 29403 root@ip-10-0-0-174:/home/ubuntu# INFO[0000] Listening for HTTP on unix (/var/run/docker.sock) INFO[0000] Option DefaultDriver: bridge INFO[0000] Option DefaultNetwork: bridge <output truncated>
此外,你還可以在Docker的配置文件中添加*--storage-driver=overlay的標志到DOCKER_OPTS中,這樣就可以持久化配置,不再需要啟動daemon時手動指定--storage-driver*標志了。比如,可以將配置持久化到配置文件/etc/default/docker中,將下面內容加入該文件中。
DOCKER_OPTS="--storage-driver=overlay2"
4) 檢查daemon是否已經使用了overlay/overlay2存儲驅動。
$ docker info Containers: 0 Images: 0 Storage Driver: overlay2 Backing Filesystem: extfs <output truncated>
注意輸出結果顯示后端文件系統使用的是extfs。雖然支持多種文件系統,但是生產環境中還是建議使用extfs(尤其ext4)。
一般來說,overlay/overlay2驅動更快一些,幾乎肯定比aufs和devicemapper更快,在某些情況下,可能比btrfs也更快。即便如此,在使用overlay/overlay2存儲驅動時,還是需要注意以下一些方面:
Page Caching,頁緩存。OverlayFS支持頁緩存共享,也就是說如果多個容器訪問同一個文件,可以共享一個或多個頁緩存選項。這使得overlay/overlay2驅動高效地利用了內存,是PaaS平臺或者其他高密度場景的一個很好地選項。
copy_up。和AuFS一樣,在容器第一次修改文件時,OverlayFS都需要執行copy-up操作,這會給寫操作帶來一些延遲——尤其這個要拷貝的文件很大時。不過,一旦文件已經執行了這個向上拷貝的操作后,所有后續對這個文件的操作都只針對這份容器層的新拷貝而已。
OverlayFS的copy_up操作比AuFS的copy_up操作要快。因為AUFS支持比OverlayFS支持更多的層數,如果需要在多層查找文件時,就可能導致比較大的延遲。
Inode limits。使用overlay存儲驅動可能導致過多的inode消耗,尤其是Docker host上鏡像和容器的數目增長時。大量的鏡像,或者很多容器啟停,,會迅速消耗掉該Docker host上的inode。overlay2存儲驅動不存在這個問題。
不幸的是,只能在文件系統創建時指定inode的個數。因此,可以考慮將/var/lib/docker放在一個單獨的設備文件系統中,或者在創建文件系統時指定inode個數。
以下一些方法可以提供OverlayFS的性能。
使用Solid State Devices(SSD)。
使用數據卷。數據卷能提高更好的性能,因為其繞過存儲驅動,不會引起超配、copy-on-write可能會導致的隱患。
有以下兩點OverlayFS和其他文件系統不太兼容:
open(2)。OverlayFS支持吃POSIX標準的一個子集。以copy-up操作為例,加入你的應用調用了fd1=open("foo", O_RDONLY) 和 fd2=open("foo", O_RDWR),你的應用期望fd1和fd2指向同一個文件,然而,因為copy-up操作,會導致指向不同的文件。
rename(2),這個和前面提到AuFS一致。
感謝各位的閱讀!關于“Docker存儲驅動OverlayFS有什么用”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。