您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關Docker存儲驅動中AUFS有什么用的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。
AUFS曾是Docker默認的首選存儲驅動。它非常穩定、有很多真實場景的部署、很強的社區支持。它有以下主要優點:
極短的容器啟動時間。
有效的存儲利用率。
有效的內存利用率。
雖然如此,但由于它沒有包含在Linux內核主線中,所有很多Linux發行版并不支持AUFS。
AUFS是一種聯合文件系統。它使用同一個Linux host上的多個目錄,逐個堆疊起來,對外呈現出一個統一的文件系統。AUFS使用該特性,實現了Docker鏡像的分層。下圖展示出ubuntu:latest的鏡像的分層。
注意:在Docker1.10之前,layer的ID對應著其在/var/lib/docker下的目錄名稱,但在Docker1.10之后,不再有這種直接的對應關系。
對于一個容器來說,只有頂層的容器layer是可讀寫的,而下面的layer都是只讀的。
Docker使用AUFS的CoW(Copy-on-Write)技術來實現鏡像共享和最小化磁盤空間的使用。AUFS作用于文件層,也就是說AUFS CoW拷貝整個文件——即使文件只修改了一點點的內容。所以,它對容器的性能影響很明顯,尤其拷貝多層鏡像下的大文件,或者是在一個深層次的目錄樹中進行搜索。
不過,在給定的容器中,這種拷貝到頂層layer的操作,每個文件只會做一次。隨后,對該文件的讀寫操作,都只針對容器頂層可讀寫layer的拷貝文件。
通過上面的介紹,很容易想到。如果要在容器中刪除一個非頂層layer的文件,肯定不會在下層layer中直接刪除,因為下層layer對于容器來說都是只讀的。AUFS存儲驅動要刪除一個文件,是通過在容器頂層layer增加一個whiteout文件來實現的。這個whiteout文件可以隱藏下層只讀layer中文件的存在,容器感知不到只讀層layer中文的存在。事實上,無論該文件在下層只讀layer中是否還存在,容器都認為這個文件被刪除了。
AUFS未能完美的支持rename(2)重命名操作,會返回EXDEV[“cross-device link not permitted”],即使源路徑和目的路徑都在同一個AUFS層。因此,你的應用需要能處理EXDEV,可以用“拷貝再刪除”的策略來替代rename操作。
我在這里做了一個測試,寫了一個簡單地C程序,該程序將目錄test重命名為目錄gaga,并打印出rename的結果。該程序在普通服務器上完美運行,那么在容器中呢?開始做測試吧。
$ mkdir build-rename $ cd build-rename $ mkdir test
$ vim test.c #include<stdio.h> #include <fcntl.h> int main(void) { char oldname[100] = "test", newname[100]="gaga"; int ret = rename(oldname, newname); if (ret == 0) printf("rename ok.\n"); else printf("ret = %d\n", ret); return 0; }
編譯該程序,生成可執行文件a.out。
$ gcc test.c
$ vim Dockerfile FROM ubuntu WORKDIR /usr/src/app COPY ./* /usr/src/app/ CMD /usr/src/app/a.out
$ docker build -t rename:v1.0 ./
$ docker run --rm rename:v1.0 ret = -1
該容器啟動后會執行可執行文件a.out,重命名一個目錄。可見結果,rename重命名一個目錄的確是返回了失敗。
只有在OS安裝了AUFS的情況下才能使用AUFS存儲驅動,一般來說,Debian/Ubuntu都支持AUFS,而Redhat/CentOS都不支持AUFS。所以,你需要先查看下你的系統是否安裝了AUFS。
$ grep aufs /proc/filesystems nodev aufs
如果以上命令有輸出則表示支持AUFS,否則就說明還未安裝AUFS。可執行以下步驟:
a. 升級你系統的kernel版本到3.13或者更高,另外建議安裝kernel headers;
b. 對于Ubuntu/Debian:安裝linux-image-extra-*包:
$ apt-get install linux-image-extra-$(uname -r) \ linux-image-extra-virtual
如果上述操作無誤,就可以使用AUFS來作為你Docker Daemon的存儲驅動了。
$ dockerd --storage-driver=aufs &
如果想持久化這個配置,可以編輯你的Docker配置文件(如/etc/default/docker,雖然官方已經不建議使用該文件了),并加入--storage-driver=aufs選項到DOCKER_OPTS中。
# Use DOCKER_OPTS to modify the daemon startup options. DOCKER_OPTS="--storage-driver=aufs"
重啟docker daemon(systemctl restart docker.service)后,確認默認存儲驅動是否配置成功:
$ docker info | grep "Storage Driver" Storage Driver: aufs
當dockerd使用AUFS驅動時,驅動把鏡像和容器存儲在Docker host的本地存儲下:/var/lib/docker/aufs。
鏡像層存儲在/var/lib/docker/aufs/diff里。Docker 1.10之后,鏡像對應的目錄名稱不再和鏡像ID意義對應了。
/var/lib/docker/aufs/layers/目錄保存了元數據信息,這些元數據顯示了image層是如何疊加的。該目錄下的每個文件,對應了一個層,而這個文件的內容就是該層之下的層。如:
$ cat /var/lib/docker/aufs/layers/91e54dfb11794fad694460162bf0cb0a4fa710cfa3f60979c177d920813e267c d74508fb6632491cea586a1fd7d748dfc5274cd6fdfedee309ecdcbc2bf5cb82 c22013c8472965aa5b62559f2b540cd440716ef149756e7b958a1b2aba421e87 d3a1f33e8a5a513092f01bb7eb1c2abf4d711e5105390a3fe1ae2248cfde1391
由于base layer之下不再有其它層,所有base layer對應的文件內容是空的。
運行中的容器映射在 /var/lib/docker/aufs/mnt/<container-id>下,這就是AUFS給容器和它下層layer的一個mount point。如果容器沒有運行了,依然還有這個目錄,但卻是個空目錄,因為AUFS只在容器運行是才映射。Docker 1.10之上的版本,目錄名同樣不和容器ID對應。
容器元數據和多種配置文件存放在該目錄下。
$ ls /var/lib/docker/aufs/mnt/670e0053b2ba02ab33dc24daca293e200aa98e871cefec016a5cbf9d41b7cfbf bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
容器的可寫層存儲在目錄 /var/lib/docker/aufs/diff/,即使容器停止了,容器對應的目錄依然存在。只有刪除容器時,對應的目錄才會刪除。
對于PaaS層來說,AUFS存儲驅動是一個很好的選擇。因為AUFS有效地在多個運行容器中共享鏡像,加速了容器啟動時間,減少了容器使用的磁盤空間。
AUFS在多個鏡像層和容器間分享文件所使用的底層機制,高效地使用了系統的頁緩存。
同時,AUFS存儲驅動也帶來了一些容器寫性能上的隱患。這是因為,容器第一次對任何文件的修改,都需要先定位到文件的所在的鏡像層次,并拷貝到容器最頂層的讀寫層。尤其當這些文件存在于很底層,或者文件本身非常大時,性能問題尤其嚴重。
AUFS是Docker在Ubuntu/Debian中的默認存儲驅動,雖然后面可能會被替換掉。但暫時來說,它完美地契合Docker的特性。并且,如何合理使用,其性能非常優異。另外,需要注意的是,AUFS對目錄的重命名支持得不好,在編寫程序時需要注意這點。
感謝各位的閱讀!關于“Docker存儲驅動中AUFS有什么用”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。