Docker存储驱动之OverlayFS简介
簡(jiǎn)介
OverlayFS是一種和AUFS很類似的文件系統(tǒng),與AUFS相比,OverlayFS有以下特性:
1) 更簡(jiǎn)單地設(shè)計(jì);
2) 從3.18開始,就進(jìn)入了Linux內(nèi)核主線;
3) 可能更快一些。
因此,OverlayFS在Docker社區(qū)關(guān)注度提高很快,被很多人認(rèn)為是AUFS的繼承者。就像宣稱的一樣,OverlayFS還很年輕。所以,在生成環(huán)境使用它時(shí),還是需要更加當(dāng)心。
Docker的overlay存儲(chǔ)驅(qū)動(dòng)利用了很多OverlayFS特性來構(gòu)建和管理鏡像與容器的磁盤結(jié)構(gòu)。
自從Docker1.12起,Docker也支持overlay2存儲(chǔ)驅(qū)動(dòng),相比于overlay來說,overlay2在inode優(yōu)化上更加高效。但overlay2驅(qū)動(dòng)只兼容Linux kernel4.0以上的版本。
注意:自從OverlayFS加入kernel主線后,它在kernel模塊中的名稱就被從overlayfs改為overlay了。但是為了在本文中區(qū)別,我們使用OverlayFS代表整個(gè)文件系統(tǒng),而overlay/overlay2表示Docker的存儲(chǔ)驅(qū)動(dòng)。
overlay和overlay2
OverlayFS(overlay)的鏡像分層與共享
OverlayFS使用兩個(gè)目錄,把一個(gè)目錄置放于另一個(gè)之上,并且對(duì)外提供單個(gè)統(tǒng)一的視角。這兩個(gè)目錄通常被稱作層,這個(gè)分層的技術(shù)被稱作union mount。術(shù)語上,下層的目錄叫做lowerdir,上層的叫做upperdir。對(duì)外展示的統(tǒng)一視圖稱作merged。
下圖展示了Docker鏡像和Docker容器是如何分層的。鏡像層就是lowerdir,容器層是upperdir。暴露在外的統(tǒng)一視圖就是所謂的merged。
注意鏡像層和容器層是如何處理相同的文件的:容器層(upperdir)的文件是顯性的,會(huì)隱藏鏡像層(lowerdir)相同文件的存在。容器映射(merged)顯示出統(tǒng)一的視圖。
overlay驅(qū)動(dòng)只能工作在兩層之上。也就是說多層鏡像不能用多層OverlayFS實(shí)現(xiàn)。替代的,每個(gè)鏡像層在/var/lib/docker/overlay中用自己的目錄來實(shí)現(xiàn),使用硬鏈接這種有效利用空間的方法,來引用底層分享的數(shù)據(jù)。注意:Docker1.10之后,鏡像層ID和/var/lib/docker中的目錄名不再一一對(duì)應(yīng)。
創(chuàng)建一個(gè)容器,overlay驅(qū)動(dòng)聯(lián)合鏡像層和一個(gè)新目錄給容器。鏡像頂層是overlay中的只讀lowerdir,容器的新目錄是可寫的upperdir。
overlay中鏡像和容器的磁盤結(jié)構(gòu)
下面的docker pull命令展示了Docker host下載一個(gè)由5層組成的鏡像。
$ sudo docker pull ubuntuUsing default tag: latest latest: Pulling from library/ubuntu5ba4f30e5bea: Pull complete 9d7d19c9dc56: Pull complete ac6ad7efd0f9: Pull complete e7491a747824: Pull complete a3ed95caeb02: Pull complete Digest: sha256:46fb5d001b88ad904c5c732b086b596b92cfb4a4840a3abd0e35dbb6870585e4 Status: Downloaded newer image for ubuntu:latest上圖的輸出結(jié)果顯示pull了5個(gè)目錄包含了5個(gè)鏡像層,每一層在/var/lib/docker/overlay/下都有自己的目錄。還是再次提醒下,如你所見,Docker1.10之后,鏡像層和目錄名不再對(duì)應(yīng)。
$ 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鏡像層目錄中,共享的數(shù)據(jù)使用的是硬鏈接,他們的inode號(hào)相同。這樣做有效地利用了磁盤。
$ ls -i /var/lib/docker/overlay/38f3ed2eac129654acef11c32670b534670c3a06e483fce313d72e3e0a15baa8/root/bin/ls19793696 /var/lib/docker/overlay/38f3ed2eac129654acef11c32670b534670c3a06e483fce313d72e3e0a15baa8/root/bin/ls$ ls -i /var/lib/docker/overlay/55f1e14c361b90570df46371b20ce6d480c434981cbda5fd68c6ff61aa0a5358/root/bin/ls19793696 /var/lib/docker/overlay/55f1e14c361b90570df46371b20ce6d480c434981cbda5fd68c6ff61aa0a5358/root/bin/ls容器也在/var/lib/docker/overlay/下。使用ls -l命令查看容器目錄,會(huì)發(fā)現(xiàn)以下文件和目錄。
$ 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這四個(gè)文件系統(tǒng)對(duì)象都是OverlayFS的組件。lower-id文件包含了容器的鏡像層最頂層的ID。
$ cat /var/lib/docker/overlay/ec444863a55a9f1ca2df72223d459c5d940a721b2288ff86a3f27be28b53be6c/lower-id55f1e14c361b90570df46371b20ce6d480c434981cbda5fd68c6ff61aa0a5358 upper目錄是容器的可讀寫層。任何對(duì)容器的改變都寫在這個(gè)目錄中。
merged目錄就是容器的mount point,這就是暴露的鏡像(lowerdir)和容器(upperdir)的統(tǒng)一視圖。任何對(duì)容器的改變也影響這個(gè)目錄。
work目錄是OverlayFS功能需要的,會(huì)被如copy_up之類的操作使用。
可以通過mount命令來核實(shí)上面的描述是否正確。
OverlayFS(overlay2)的鏡像分層與共享
overlay驅(qū)動(dòng)只工作在一個(gè)lower OverlayFS層之上,因此需要硬鏈接來實(shí)現(xiàn)多層鏡像,但overlay2驅(qū)動(dòng)原生地支持多層lower OverlayFS鏡像(最多128層)。
因此overlay2驅(qū)動(dòng)在合層相關(guān)的命令(如build和commit)中提供了更好的性能,與overlay驅(qū)動(dòng)對(duì)比,消耗了更少的inode。
overlay2中鏡像和容器的磁盤結(jié)構(gòu)
docker pull ubuntu下載了包含5層的鏡像,可以看到在/var/lib/docker/overlay2中,有6個(gè)目錄。
$ ls -l /var/lib/docker/overlay2total 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 ll目錄包含了很多軟連接,使用短名稱指向了其他層。短名稱用于避免mount參數(shù)時(shí)達(dá)到頁面大小的限制。
$ ls -l /var/lib/docker/overlay2/ltotal 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在最低層中,有個(gè)link文件,包含了前面提到的這個(gè)層對(duì)應(yīng)的短名稱;還有個(gè)diff目錄,包含了這個(gè)鏡像的內(nèi)容。
$ ls /var/lib/docker/overlay2/3a36935c9df35472229c57f4a27105a136f5e4dbef0f87905b2e506e494e348b/diff link$ cat /var/lib/docker/overlay2/3a36935c9df35472229c57f4a27105a136f5e4dbef0f87905b2e506e494e348b/link6Y5IM2XC7TSNIJZZFLJCS6I4I4$ ls /var/lib/docker/overlay2/3a36935c9df35472229c57f4a27105a136f5e4dbef0f87905b2e506e494e348b/diffbin 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/223c2864175491657d238e2664251df13b63adb8d050924fd1bfcdb278b866f7diff link lower merged work$ cat /var/lib/docker/overlay2/223c2864175491657d238e2664251df13b63adb8d050924fd1bfcdb278b866f7/lowerl/6Y5IM2XC7TSNIJZZFLJCS6I4I4$ ls /var/lib/docker/overlay2/223c2864175491657d238e2664251df13b63adb8d050924fd1bfcdb278b866f7/diff/etc sbin usr var運(yùn)行容器包含的目錄同樣有著類似的文件和目錄。注意在lower文件中,使用:符號(hào)來分割不同的底層,并且順序是從高層到底層。
$ ls -l /var/lib/docker/overlay/<directory-of-running-container>$ cat /var/lib/docker/overlay/<directory-of-running-container>/lowerl/DJA75GUWHWG7EWICFYX54FIOVT:l/B3WWEFKBG3PLLV737KZFIASSW7:l/JEYMODZYFCZFYSDABYXD5MF6YO:l/UL2MW33MSE3Q5VYIKBRN4ZAGQP:l/NFYKDW6APBCCUCTOUSYDH4DXAT:l/6Y5IM2XC7TSNIJZZFLJCS6I4I4mount的結(jié)果如下:
$ mount | grep overlayoverlay 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讀寫
有三種場(chǎng)景,容器會(huì)通過overlay只讀訪問文件。
容器層不存在的文件。如果容器只讀打開一個(gè)文件,但該容器不在容器層(upperdir),就要從鏡像層(lowerdir)中讀取。這會(huì)引起很小的性能損耗。
只存在于容器層的文件。如果容器只讀權(quán)限打開一個(gè)文件,并且容器只存在于容器層(upperdir)而不是鏡像層(lowerdir),那么直接從鏡像層讀取文件,無額外性能損耗。
文件同時(shí)存在于容器層和鏡像層。那么會(huì)讀取容器層的文件,因?yàn)槿萜鲗?#xff08;upperdir)隱藏了鏡像層(lowerdir)的同名文件。因此,也沒有額外的性能損耗。
有以下場(chǎng)景容器修改文件。
第一次寫一個(gè)文件。容器第一次寫一個(gè)已經(jīng)存在的文件,容器層不存在這個(gè)文件。overlay/overlay2驅(qū)動(dòng)執(zhí)行copy-up操作,將文件從鏡像層拷貝到容器層。然后容器修改容器層新拷貝的文件。
然而,OverlayFS工作在文件級(jí)別而不是塊級(jí)別。也就是說所有的OverlayFS的copy-up操作都會(huì)拷貝整個(gè)文件,即使文件非常大但卻只修改了一小部分,這在容器寫性能上有著顯著的影響。不過,有兩個(gè)方面值得注意:
? copy-up操作只發(fā)生在第一次寫文件時(shí)。后續(xù)的對(duì)同一個(gè)文件的寫操作都是直接針對(duì)拷貝到容器層的那個(gè)新文件。
? OverlayFS只工作在兩層中。這比AUFS要在多層鏡像中查找時(shí)性能要好。
刪除文件和目錄。刪除文件時(shí),容器會(huì)在鏡像層創(chuàng)建一個(gè)whiteout文件,而鏡像層的文件并沒有刪除。但是,whiteout文件會(huì)隱藏它。
容器中刪除一個(gè)目錄,容器層會(huì)創(chuàng)建一個(gè)不透明目錄。這和whiteout文件隱藏鏡像層的文件類似。
重命名目錄。只有在源路徑和目的路徑都在頂層容器層時(shí),才允許執(zhí)行rename操作。否則,會(huì)返回EXDEV。
因此,你的應(yīng)用需要能夠處理EXDEV,并且回滾操作,執(zhí)行替代的“拷貝和刪除”策略。
在Docker中配置overlay/overlay2存儲(chǔ)驅(qū)動(dòng)
為了給Docker配置overlay存儲(chǔ)驅(qū)動(dòng),你的Docker host必須運(yùn)行在Linux kernel3.18版本之上,而且加載了overlay內(nèi)核驅(qū)動(dòng)。對(duì)于overlay2驅(qū)動(dòng),kernel版本必須在4.0或以上。OverlayFS可以運(yùn)行在大多數(shù)Linux文件系統(tǒng)之上。不過,現(xiàn)在最建議在生產(chǎn)環(huán)境中使用ext4。
下面的步驟講述了如何在Docker host中配置使用OverlayFS。
注意:在開始配置之前,如果你已經(jīng)在使用Docker daemon,并且有一些想保留的鏡像,簡(jiǎn)易你push它們到Docker hub中。
1) 如果Docker daemon正在運(yùn)行,需要先停止其運(yùn)行。
2) 檢查kernel版本,確認(rèn)overlay的內(nèi)核模塊是否加載。
$ uname -r4.4.0-64-generic$ lsmod | grep overlayoverlay# 如果上面命令沒有輸出,說明驅(qū)動(dòng)沒有加載,可以如下操作 $ modprobe overlay3) 使用overlay/overlay2存儲(chǔ)驅(qū)動(dòng)來啟動(dòng)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的標(biāo)志到DOCKER_OPTS中,這樣就可以持久化配置,不再需要啟動(dòng)daemon時(shí)手動(dòng)指定--storage-driver標(biāo)志了。比如,可以將配置持久化到配置文件/etc/default/docker中,將下面內(nèi)容加入該文件中。
DOCKER_OPTS="--storage-driver=overlay2"4) 檢查daemon是否已經(jīng)使用了overlay/overlay2存儲(chǔ)驅(qū)動(dòng)。
$ docker infoContainers: 0 Images: 0 Storage Driver: overlay2 Backing Filesystem: extfs <output truncated>注意輸出結(jié)果顯示后端文件系統(tǒng)使用的是extfs。雖然支持多種文件系統(tǒng),但是生產(chǎn)環(huán)境中還是建議使用extfs(尤其ext4)。
OverlayFS和Docker性能
一般來說,overlay/overlay2驅(qū)動(dòng)更快一些,幾乎肯定比aufs和devicemapper更快,在某些情況下,可能比btrfs也更快。即便如此,在使用overlay/overlay2存儲(chǔ)驅(qū)動(dòng)時(shí),還是需要注意以下一些方面:
- Page Caching,頁緩存。OverlayFS支持頁緩存共享,也就是說如果多個(gè)容器訪問同一個(gè)文件,可以共享一個(gè)或多個(gè)頁緩存選項(xiàng)。這使得overlay/overlay2驅(qū)動(dòng)高效地利用了內(nèi)存,是PaaS平臺(tái)或者其他高密度場(chǎng)景的一個(gè)很好地選項(xiàng)。
- copy_up。和AuFS一樣,在容器第一次修改文件時(shí),OverlayFS都需要執(zhí)行copy-up操作,這會(huì)給寫操作帶來一些延遲——尤其這個(gè)要拷貝的文件很大時(shí)。不過,一旦文件已經(jīng)執(zhí)行了這個(gè)向上拷貝的操作后,所有后續(xù)對(duì)這個(gè)文件的操作都只針對(duì)這份容器層的新拷貝而已。
OverlayFS的copy_up操作比AuFS的copy_up操作要快。因?yàn)锳UFS支持比OverlayFS支持更多的層數(shù),如果需要在多層查找文件時(shí),就可能導(dǎo)致比較大的延遲。 - Inode limits。使用overlay存儲(chǔ)驅(qū)動(dòng)可能導(dǎo)致過多的inode消耗,尤其是Docker host上鏡像和容器的數(shù)目增長(zhǎng)時(shí)。大量的鏡像,或者很多容器啟停,,會(huì)迅速消耗掉該Docker host上的inode。overlay2存儲(chǔ)驅(qū)動(dòng)不存在這個(gè)問題。
不幸的是,只能在文件系統(tǒng)創(chuàng)建時(shí)指定inode的個(gè)數(shù)。因此,可以考慮將/var/lib/docker放在一個(gè)單獨(dú)的設(shè)備文件系統(tǒng)中,或者在創(chuàng)建文件系統(tǒng)時(shí)指定inode個(gè)數(shù)。
以下一些方法可以提供OverlayFS的性能。 - 使用Solid State Devices(SSD)。
使用數(shù)據(jù)卷。數(shù)據(jù)卷能提高更好的性能,因?yàn)槠淅@過存儲(chǔ)驅(qū)動(dòng),不會(huì)引起超配、copy-on-write可能會(huì)導(dǎo)致的隱患。
OverlayFS兼容性
有以下兩點(diǎn)OverlayFS和其他文件系統(tǒng)不太兼容:- open(2)。OverlayFS支持吃POSIX標(biāo)準(zhǔn)的一個(gè)子集。以copy-up操作為例,加入你的應(yīng)用調(diào)用了fd1=open("foo", O_RDONLY) 和 fd2=open("foo", O_RDWR),你的應(yīng)用期望fd1和fd2指向同一個(gè)文件,然而,因?yàn)閏opy-up操作,會(huì)導(dǎo)致指向不同的文件。
rename(2),這個(gè)和前面提到AuFS一致。
小結(jié)
overlay/overlay2存儲(chǔ)驅(qū)動(dòng)已經(jīng)成為了Docker存儲(chǔ)驅(qū)動(dòng)的首選,并且性能優(yōu)于AuFS和devicemapper。不過,他們也帶來了一些與其他文件系統(tǒng)的不兼容性,如對(duì)open和rename操作的支持。另外,overlay與overlay2相比,overlay2支持了多層鏡像,優(yōu)化了inode使用。然而,使用這兩種驅(qū)動(dòng)時(shí),需要注意你的Docker host的kernel版本。
轉(zhuǎn)載于:https://www.cnblogs.com/styshoo/p/6503953.html
總結(jié)
以上是生活随笔為你收集整理的Docker存储驱动之OverlayFS简介的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 根据json对象的某一属性对其进行排序
- 下一篇: deferred对象和promise对象