溫馨提示×

溫馨提示×

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

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

Docker AUFS怎么使用

發(fā)布時間:2021-12-13 17:40:24 來源:億速云 閱讀:116 作者:iii 欄目:云計算

本篇內(nèi)容主要講解“Docker AUFS怎么使用”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Docker AUFS怎么使用”吧!

AUFS是一種Union File System,所謂UnionFS就是把不同物理位置的目錄合并mount到同一個目錄中。UnionFS的一個最主要的應(yīng)用是,把一張CD/DVD和一個硬盤目錄給聯(lián)合 mount在一起,然后,你就可以對這個只讀的CD/DVD上的文件進行修改(當然,修改的文件存于硬盤上的目錄里)。

AUFS又叫Another UnionFS,后來叫Alternative UnionFS,后來可能覺得不夠霸氣,叫成Advance UnionFS。是個叫Junjiro Okajima(岡島順治郎)在2006年開發(fā)的,AUFS完全重寫了早期的UnionFS 1.x,其主要目的是為了可靠性和性能,并且引入了一些新的功能,比如可寫分支的負載均衡。AUFS在使用上全兼容UnionFS,而且比之前的UnionFS在穩(wěn)定性和性能上都要好很多,后來的UnionFS 2.x開始抄AUFS中的功能。但是他居然沒有進到Linux主干里,就是因為Linus不讓,基本上是因為代碼量比較多,而且寫得爛(相對于只有3000行的union mount和10000行的UnionFS,以及其它平均下來只有6000行代碼左右的VFS,AUFS居然有30000行代碼),所以,岡島不斷地改進代碼質(zhì)量,不斷地提交,不斷地被Linus拒掉,所以,到今天AUFS都還進不了Linux主干(今天你可以看到AUFS的代碼其實還好了,比起OpenSSL好N倍,要么就是Linus對代碼的質(zhì)量要求非常高,要么就是Linus就是不喜歡AUFS)。

不過,好在有很多發(fā)行版都用了AUFS,比如:Ubuntu 10.04,Debian6.0, Gentoo Live CD支持AUFS,所以,也OK了。

好了,扯完這些閑話,我們還是看一個示例吧(環(huán)境:Ubuntu 14.04)

首先,我們建上兩個目錄(水果和蔬菜),并在這兩個目錄中放上一些文件,水果中有蘋果和蕃茄,蔬菜有胡蘿卜和蕃茄。

1

2

3

4

5

6

7

8

$ tree

.

├── fruits

│   ├── apple

│   └── tomato

└── vegetables

    ├── carrots

    └── tomato

然后,我們輸入以下命令:

1

2

3

4

5

6

7

8

9

10

11

12

# 創(chuàng)建一個mount目錄

$ mkdir mnt

 

# 把水果目錄和蔬菜目錄union mount到 ./mnt目錄中

$ sudo mount -t aufs -o dirs=./fruits:./vegetables none ./mnt

 

#  查看./mnt目錄

$ tree ./mnt

./mnt

├── apple

├── carrots

└── tomato

我們可以看到在./mnt目錄下有三個文件,蘋果apple、胡蘿卜carrots和蕃茄tomato。水果和蔬菜的目錄被union到了./mnt目錄下了。

我們來修改一下其中的文件內(nèi)容:

1

2

3

4

5

$ echo mnt > ./mnt/apple

$ cat ./mnt/apple

mnt

$ cat ./fruits/apple

mnt

上面的示例,我們可以看到./mnt/apple的內(nèi)容改了,./fruits/apple的內(nèi)容也改了。

1

2

3

4

5

$ echo mnt_carrots > ./mnt/carrots

$ cat ./vegetables/carrots

 

$ cat ./fruits/carrots

mnt_carrots

上面的示例,我們可以看到,我們修改了./mnt/carrots的文件內(nèi)容,./vegetables/carrots并沒有變化,反而是./fruits/carrots的目錄中出現(xiàn)了carrots文件,其內(nèi)容是我們在./mnt/carrots里的內(nèi)容。

也就是說,我們在mount aufs命令中,我們沒有指它vegetables和fruits的目錄權(quán)限,默認上來說,命令行上第一個(最左邊)的目錄是可讀可寫的,后面的全都是只讀的。(一般來說,最前面的目錄應(yīng)該是可寫的,而后面的都應(yīng)該是只讀的)

所以,如果我們像下面這樣指定權(quán)限來mount aufs,你就會發(fā)現(xiàn)有不一樣的效果(記得先把上面./fruits/carrots的文件刪除了):

1

2

3

4

5

6

7

8

9

$ sudo mount -t aufs -o dirs=./fruits=rw:./vegetables=rw none ./mnt

 

$ echo "mnt_carrots" > ./mnt/carrots

 

$ cat ./vegetables/carrots

mnt_carrots

 

$ cat ./fruits/carrots

cat: ./fruits/carrots: No such file or directory

現(xiàn)在,在這情況下,如果我們要修改./mnt/tomato這個文件,那么究竟是哪個文件會被改寫?

1

2

3

4

5

6

7

$ echo "mnt_tomato" > ./mnt/tomato

 

$ cat ./fruits/tomato

mnt_tomato

 

$ cat ./vegetables/tomato

I am a vegetable

可見,如果有重復的文件名,在mount命令行上,越往前的就優(yōu)先級越高。

你可以用這個例子做一些各種各樣的試驗,我這里主要是給大家一個感性認識,就不展開試驗下去了。

那么,這種UnionFS有什么用?

歷史上,有一個叫Knoppix的Linux發(fā)行版,其主要用于Linux演示、光盤教學、系統(tǒng)急救,以及商業(yè)產(chǎn)品的演示,不需要硬盤安裝,直接把CD/DVD上的image運行在一個可寫的存儲設(shè)備上(比如一個U盤上),其實,也就是把CD/DVD這個文件系統(tǒng)和USB這個可寫的系統(tǒng)給聯(lián)合mount起來,這樣你對CD/DVD上的image做的任何改動都會在被應(yīng)用在U盤上,于是乎,你可以對CD/DVD上的內(nèi)容進行任意的修改,因為改動都在U盤上,所以你改不壞原來的東西。

我們可以再發(fā)揮一下想像力,你也可以把一個目錄,比如你的源代碼,作為一個只讀的template,和另一個你的working directory給union在一起,然后你就可以做各種修改而不用害怕會把源代碼改壞了。有點像一個ad hoc snapshot。

Docker把UnionFS的想像力發(fā)揮到了容器的鏡像。你是否還記得我在介紹Linux Namespace上篇中用mount namespace和chroot山寨了一鏡像。現(xiàn)在當你看過了這個UnionFS的技術(shù)后,你是不是就明白了,你完全可以用UnionFS這樣的技術(shù)做出分層的鏡像來。

下圖來自Docker的官方文檔Layer,其很好的展示了Docker用UnionFS搭建的分層鏡像。

Docker AUFS怎么使用

關(guān)于docker的分層鏡像,除了aufs,docker還支持btrfs, devicemapper和vfs,你可以使用 -s 或 –storage-driver= 選項來指定相關(guān)的鏡像存儲。在Ubuntu 14.04下,docker默認Ubuntu的 aufs(在CentOS7下,用的是devicemapper,關(guān)于devicemapper,我會以以后的文章中講解)你可以在下面的目錄中查看相關(guān)的每個層的鏡像:

1

/var/lib/docker/aufs/diff/<id>

在docker執(zhí)行起來后(比如:docker run -it ubuntu /bin/bash ),你可以從/sys/fs/aufs/si_[id]目錄下查看aufs的mount的情況,下面是個示例:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

#ls /sys/fs/aufs/si_b71b209f85ff8e75/

br0      br2      br4      br6      brid1    brid3    brid5    xi_path

br1      br3      br5      brid0    brid2    brid4    brid6

 

# cat /sys/fs/aufs/si_b71b209f85ff8e75/*

/var/lib/docker/aufs/diff/87315f1367e5703f599168d1e17528a0500bd2e2df7d2fe2aaf9595f3697dbd7=rw

/var/lib/docker/aufs/diff/87315f1367e5703f599168d1e17528a0500bd2e2df7d2fe2aaf9595f3697dbd7-init=ro+wh

/var/lib/docker/aufs/diff/d0955f21bf24f5bfffd32d2d0bb669d0564701c271bc3dfc64cfc5adfdec2d07=ro+wh

/var/lib/docker/aufs/diff/9fec74352904baf5ab5237caa39a84b0af5c593dc7cc08839e2ba65193024507=ro+wh

/var/lib/docker/aufs/diff/a1a958a248181c9aa6413848cd67646e5afb9797f1a3da5995c7a636f050f537=ro+wh

/var/lib/docker/aufs/diff/f3c84ac3a0533f691c9fea4cc2ceaaf43baec22bf8d6a479e069f6d814be9b86=ro+wh

/var/lib/docker/aufs/diff/511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158=ro+wh

64

65

66

67

68

69

70

/run/shm/aufs.xino

你會看到只有最頂上的層(branch)是rw權(quán)限,其它的都是ro+wh權(quán)限只讀的。

關(guān)于docker的aufs的配置,你可以在/var/lib/docker/repositories-aufs這個文件中看到。

AUFS的一些特性

AUFS有所有Union FS的特性,把多個目錄,合并成同一個目錄,并可以為每個需要合并的目錄指定相應(yīng)的權(quán)限,實時的添加、刪除、修改已經(jīng)被mount好的目錄。而且,他還能在多個可寫的branch/dir間進行負載均衡。

上面的例子,我們已經(jīng)看到AUFS的mount的示例了。下面我們來看一看被union的目錄(分支)的相關(guān)權(quán)限:

  • rw表示可寫可讀read-write。

  • ro表示read-only,如果你不指權(quán)限,那么除了第一個外ro是默認值,對于ro分支,其永遠不會收到寫操作,也不會收到查找whiteout的操作。

  • rr表示real-read-only,與read-only不同的是,rr標記的是天生就是只讀的分支,這樣,AUFS可以提高性能,比如不再設(shè)置inotify來檢查文件變動通知。

權(quán)限中,我們看到了一個術(shù)語:whiteout,下面我來解釋一下這個術(shù)語。

一般來說ro的分支都會有wh的屬性,比如 “[dir]=ro+wh”。所謂whiteout的意思,如果在union中刪除的某個文件,實際上是位于一個readonly的分支(目錄)上,那么,在mount的union這個目錄中你將看不到這個文件,但是read-only這個層上我們無法做任何的修改,所以,我們就需要對這個readonly目錄里的文件作whiteout。AUFS的whiteout的實現(xiàn)是通過在上層的可寫的目錄下建立對應(yīng)的whiteout隱藏文件來實現(xiàn)的。

看個例子:

假設(shè)我們有三個目錄和文件如下所示(test是個空目錄):

1

2

3

4

5

6

7

8

9

# tree

.

├── fruits

│   ├── apple

│   └── tomato

├── test

└── vegetables

    ├── carrots

    └── tomato

我們?nèi)缦耺ount:

1

2

3

4

5

6

# mkdir mnt

 

# mount -t aufs -o dirs=./test=rw:./fruits=ro:./vegetables=ro none ./mnt

 

# # ls ./mnt/

apple  carrots  tomato

現(xiàn)在我們在權(quán)限為rw的test目錄下建個whiteout的隱藏文件.wh.apple,你就會發(fā)現(xiàn)./mnt/apple這個文件就消失了:

1

2

3

4

# touch ./test/.wh.apple

 

# ls ./mnt

carrots  tomato

上面這個操作和 rm ./mnt/apple是一樣的。

相關(guān)術(shù)語

?Branch – 就是各個要被union起來的目錄(就是我在上面使用的dirs的命令行參數(shù))

  • ?Branch根據(jù)被union的順序形成一個stack,一般來說最上面的是可寫的,下面的都是只讀的。

  • ?Branch的stack可以在被mount后進行修改,比如:修改順序,加入新的branch,或是刪除其中的branch,或是直接修改branch的權(quán)限

?Whiteout 和 Opaque

  • ?如果UnionFS中的某個目錄被刪除了,那么就應(yīng)該不可見了,就算是在底層的branch中還有這個目錄,那也應(yīng)該不可見了。

  • ?Whiteout就是某個上層目錄覆蓋了下層的相同名字的目錄。用于隱藏低層分支的文件,也用于阻止readdir進入低層分支。

  • ?Opaque的意思就是不允許任何下層的某個目錄顯示出來。

  • ?在隱藏低層檔的情況下,whiteout的名字是’.wh.<filename>’。

  • ?在阻止readdir的情況下,名字是’.wh..wh..opq’或者 ’.wh.__dir_opaque’。

相關(guān)問題

看到上面這些,你一定會有幾個問題:

其一、你可能會問,要有文件在原來的地方被修改了會怎么樣?mount的目錄會一起改變嗎?答案是會的,也可以是不會的。因為你可以指定一個叫udba的參數(shù)(全稱:User’s Direct Branch Access),這個參數(shù)有三個取值:

  • udba=none – 設(shè)置上這個參數(shù)后,AUFS會運轉(zhuǎn)的更快,因為那些不在mount目錄里發(fā)生的修改,aufs不會同步過來了,所以會有數(shù)據(jù)出錯的問題。

  • udba=reval – 設(shè)置上這個參數(shù)后,AUFS會去查文件有沒有被更新,如果有的話,就會把修改拉到mount目錄內(nèi)。

  • udba=notify – 這個參數(shù)會讓AUFS為所有的branch注冊inotify,這樣可以讓AUFS在更新文件修改的性能更高一些。

其二、如果有多個rw的branch(目錄)被union起來了,那么,當我創(chuàng)建文件的時候,aufs會創(chuàng)建在哪里呢? aufs提供了一個叫create的參數(shù)可以供你來配置相當?shù)膭?chuàng)建策略,下面有幾個例子。

create=rr | round?robin 輪詢。下面的示例可以看到,新創(chuàng)建的文件輪流寫到三個目錄中

1

2

3

4

5

6

7

8

9

10

hchen$ sudo mount -t aufs  -o dirs=./1=rw:./2=rw:./3=rw -o create=rr none ./mnt

hchen$ touch ./mnt/a ./mnt/b ./mnt/c

hchen$ tree

.

├── 1

│   └── a

├── 2

│   └── c

└── 3

    └── b

create=mfs[:second] | most?free?space[:second] 選一個可用空間最好的分支。可以指定一個檢查可用磁盤空間的時間。

create=mfsrr:low[:second] 選一個空間大于low的branch,如果空間小于low了,那么aufs會使用 round-robin 方式。

更多的關(guān)于AUFS的細節(jié)使用參數(shù),大家可以直接在Ubuntu 14.04下通過 man aufs 來看一下其中的各種參數(shù)和命令。

AUFS的性能

AUFS的性能慢嗎?也慢也不慢。因為AUFS會把所有的分支mount起來,所以,在查找文件上是比較慢了。因為它要遍歷所有的branch。是個O(n)的算法(很明顯,這個算法有很大的改進空間的)所以,branch越多,查找文件的性能也就越慢。但是,一旦AUFS找到了這個文件的inode,那后以后的讀寫和操作原文件基本上是一樣的。

所以,如果你的程序跑在在AUFS下,open和stat操作會有明顯的性能下降,branch越多,性能越差,但是在write/read操作上,性能沒有什么變化。

IBM的研究中心對Docker的性能給了一份非常不錯的性能報告(PDF)《An Updated Performance Comparison of Virtual Machinesand Linux Containers》

我截了兩張圖出來,第一張是順序讀寫,第二張是隨機讀寫。基本沒有什么性能損失的問題。而KVM在隨機讀寫的情況也就有點慢了(但是,如果硬盤是SSD的呢?)

Docker AUFS怎么使用

順序讀寫

Docker AUFS怎么使用

到此,相信大家對“Docker AUFS怎么使用”有了更深的了解,不妨來實際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進入相關(guān)頻道進行查詢,關(guān)注我們,繼續(xù)學習!

向AI問一下細節(jié)

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

AI