溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Docker存儲(chǔ)驅(qū)動(dòng)中AUFS有什么用

發(fā)布時(shí)間:2021-11-19 11:05:34 來源:億速云 閱讀:163 作者:小新 欄目:云計(jì)算

這篇文章給大家分享的是有關(guān)Docker存儲(chǔ)驅(qū)動(dòng)中AUFS有什么用的內(nèi)容。小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過來看看吧。

簡介

  AUFS曾是Docker默認(rèn)的首選存儲(chǔ)驅(qū)動(dòng)。它非常穩(wěn)定、有很多真實(shí)場景的部署、很強(qiáng)的社區(qū)支持。它有以下主要優(yōu)點(diǎn):
  極短的容器啟動(dòng)時(shí)間。
  有效的存儲(chǔ)利用率。
  有效的內(nèi)存利用率。
  雖然如此,但由于它沒有包含在Linux內(nèi)核主線中,所有很多Linux發(fā)行版并不支持AUFS。

特性

鏡像分層和部署

  AUFS是一種聯(lián)合文件系統(tǒng)。它使用同一個(gè)Linux host上的多個(gè)目錄,逐個(gè)堆疊起來,對外呈現(xiàn)出一個(gè)統(tǒng)一的文件系統(tǒng)。AUFS使用該特性,實(shí)現(xiàn)了Docker鏡像的分層。下圖展示出ubuntu:latest的鏡像的分層。
  
  注意:在Docker1.10之前,layer的ID對應(yīng)著其在/var/lib/docker下的目錄名稱,但在Docker1.10之后,不再有這種直接的對應(yīng)關(guān)系。
  對于一個(gè)容器來說,只有頂層的容器layer是可讀寫的,而下面的layer都是只讀的。

讀寫文件

  Docker使用AUFS的CoW(Copy-on-Write)技術(shù)來實(shí)現(xiàn)鏡像共享和最小化磁盤空間的使用。AUFS作用于文件層,也就是說AUFS CoW拷貝整個(gè)文件——即使文件只修改了一點(diǎn)點(diǎn)的內(nèi)容。所以,它對容器的性能影響很明顯,尤其拷貝多層鏡像下的大文件,或者是在一個(gè)深層次的目錄樹中進(jìn)行搜索。
  不過,在給定的容器中,這種拷貝到頂層layer的操作,每個(gè)文件只會(huì)做一次。隨后,對該文件的讀寫操作,都只針對容器頂層可讀寫layer的拷貝文件。

刪除文件

  通過上面的介紹,很容易想到。如果要在容器中刪除一個(gè)非頂層layer的文件,肯定不會(huì)在下層layer中直接刪除,因?yàn)橄聦觢ayer對于容器來說都是只讀的。AUFS存儲(chǔ)驅(qū)動(dòng)要?jiǎng)h除一個(gè)文件,是通過在容器頂層layer增加一個(gè)whiteout文件來實(shí)現(xiàn)的。這個(gè)whiteout文件可以隱藏下層只讀layer中文件的存在,容器感知不到只讀層layer中文的存在。事實(shí)上,無論該文件在下層只讀layer中是否還存在,容器都認(rèn)為這個(gè)文件被刪除了。

重命名目錄

  AUFS未能完美的支持rename(2)重命名操作,會(huì)返回EXDEV[“cross-device link not permitted”],即使源路徑和目的路徑都在同一個(gè)AUFS層。因此,你的應(yīng)用需要能處理EXDEV,可以用“拷貝再刪除”的策略來替代rename操作。
  我在這里做了一個(gè)測試,寫了一個(gè)簡單地C程序,該程序?qū)⒛夸泃est重命名為目錄gaga,并打印出rename的結(jié)果。該程序在普通服務(wù)器上完美運(yùn)行,那么在容器中呢?開始做測試吧。

創(chuàng)建docker build目錄,進(jìn)入該目錄。并在該目錄下創(chuàng)建子目錄test。

$ mkdir build-rename
$ cd build-rename
$ mkdir test

創(chuàng)建文件test.c

$ 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;
}

  編譯該程序,生成可執(zhí)行文件a.out。

$ gcc test.c

創(chuàng)建Dockerfile

$ vim Dockerfile

FROM ubuntu
WORKDIR /usr/src/app
COPY ./* /usr/src/app/
CMD /usr/src/app/a.out

生成鏡像。

$ docker build -t rename:v1.0 ./

運(yùn)行容器

$ docker run --rm rename:v1.0
ret = -1

  該容器啟動(dòng)后會(huì)執(zhí)行可執(zhí)行文件a.out,重命名一個(gè)目錄??梢娊Y(jié)果,rename重命名一個(gè)目錄的確是返回了失敗。

配置AUFS

準(zhǔn)備

  只有在OS安裝了AUFS的情況下才能使用AUFS存儲(chǔ)驅(qū)動(dòng),一般來說,Debian/Ubuntu都支持AUFS,而Redhat/CentOS都不支持AUFS。所以,你需要先查看下你的系統(tǒng)是否安裝了AUFS。

$ grep aufs /proc/filesystems
nodev   aufs

  如果以上命令有輸出則表示支持AUFS,否則就說明還未安裝AUFS??蓤?zhí)行以下步驟:
  a. 升級你系統(tǒng)的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的存儲(chǔ)驅(qū)動(dòng)了。

$ dockerd --storage-driver=aufs &

  如果想持久化這個(gè)配置,可以編輯你的Docker配置文件(如/etc/default/docker,雖然官方已經(jīng)不建議使用該文件了),并加入--storage-driver=aufs選項(xiàng)到DOCKER_OPTS中。

# Use DOCKER_OPTS to modify the daemon startup options.
DOCKER_OPTS="--storage-driver=aufs"

  重啟docker daemon(systemctl restart docker.service)后,確認(rèn)默認(rèn)存儲(chǔ)驅(qū)動(dòng)是否配置成功:

$ docker info | grep "Storage Driver"

Storage Driver: aufs

本地存儲(chǔ)和AUFS

  當(dāng)dockerd使用AUFS驅(qū)動(dòng)時(shí),驅(qū)動(dòng)把鏡像和容器存儲(chǔ)在Docker host的本地存儲(chǔ)下:/var/lib/docker/aufs。

鏡像

  鏡像層存儲(chǔ)在/var/lib/docker/aufs/diff里。Docker 1.10之后,鏡像對應(yīng)的目錄名稱不再和鏡像ID意義對應(yīng)了。
  /var/lib/docker/aufs/layers/目錄保存了元數(shù)據(jù)信息,這些元數(shù)據(jù)顯示了image層是如何疊加的。該目錄下的每個(gè)文件,對應(yīng)了一個(gè)層,而這個(gè)文件的內(nèi)容就是該層之下的層。如:

$ cat /var/lib/docker/aufs/layers/91e54dfb11794fad694460162bf0cb0a4fa710cfa3f60979c177d920813e267c

d74508fb6632491cea586a1fd7d748dfc5274cd6fdfedee309ecdcbc2bf5cb82
c22013c8472965aa5b62559f2b540cd440716ef149756e7b958a1b2aba421e87
d3a1f33e8a5a513092f01bb7eb1c2abf4d711e5105390a3fe1ae2248cfde1391

  由于base layer之下不再有其它層,所有base layer對應(yīng)的文件內(nèi)容是空的。

容器

  運(yùn)行中的容器映射在 /var/lib/docker/aufs/mnt/<container-id>下,這就是AUFS給容器和它下層layer的一個(gè)mount point。如果容器沒有運(yùn)行了,依然還有這個(gè)目錄,但卻是個(gè)空目錄,因?yàn)锳UFS只在容器運(yùn)行是才映射。Docker 1.10之上的版本,目錄名同樣不和容器ID對應(yīng)。
  容器元數(shù)據(jù)和多種配置文件存放在該目錄下。

$ 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

  容器的可寫層存儲(chǔ)在目錄 /var/lib/docker/aufs/diff/,即使容器停止了,容器對應(yīng)的目錄依然存在。只有刪除容器時(shí),對應(yīng)的目錄才會(huì)刪除。

AUFS在Docker中的性能

  對于PaaS層來說,AUFS存儲(chǔ)驅(qū)動(dòng)是一個(gè)很好的選擇。因?yàn)锳UFS有效地在多個(gè)運(yùn)行容器中共享鏡像,加速了容器啟動(dòng)時(shí)間,減少了容器使用的磁盤空間。
  AUFS在多個(gè)鏡像層和容器間分享文件所使用的底層機(jī)制,高效地使用了系統(tǒng)的頁緩存。
  同時(shí),AUFS存儲(chǔ)驅(qū)動(dòng)也帶來了一些容器寫性能上的隱患。這是因?yàn)?,容器第一次對任何文件的修改,都需要先定位到文件的所在的鏡像層次,并拷貝到容器最頂層的讀寫層。尤其當(dāng)這些文件存在于很底層,或者文件本身非常大時(shí),性能問題尤其嚴(yán)重。

  AUFS是Docker在Ubuntu/Debian中的默認(rèn)存儲(chǔ)驅(qū)動(dòng),雖然后面可能會(huì)被替換掉。但暫時(shí)來說,它完美地契合Docker的特性。并且,如何合理使用,其性能非常優(yōu)異。另外,需要注意的是,AUFS對目錄的重命名支持得不好,在編寫程序時(shí)需要注意這點(diǎn)。

感謝各位的閱讀!關(guān)于“Docker存儲(chǔ)驅(qū)動(dòng)中AUFS有什么用”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,讓大家可以學(xué)到更多知識(shí),如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI