久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

Docker AUFS怎么使用

260次閱讀
沒有評論

共計 6863 個字符,預計需要花費 18 分鐘才能閱讀完成。

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

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

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

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

好了,扯完這些閑話,我們還是看一個示例吧(環境: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

# 創建一個 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 目錄下了。

我們來修改一下其中的文件內容:

1

2

3

4

5

$ echo mnt ./mnt/apple

$ cat ./mnt/apple

mnt

$ cat ./fruits/apple

mnt

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

1

2

3

4

5

$ echo mnt_carrots ./mnt/carrots

$ cat ./vegetables/carrots

 

$ cat ./fruits/carrots

mnt_carrots

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

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

所以,如果我們像下面這樣指定權限來 mount aufs,你就會發現有不一樣的效果(記得先把上面./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

現在,在這情況下,如果我們要修改./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 命令行上,越往前的就優先級越高。

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

那么,這種 UnionFS 有什么用?

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

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

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

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

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

1

/var/lib/docker/aufs/diff/ id

在 docker 執行起來后(比如: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 權限,其它的都是 ro+wh 權限只讀的。

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

AUFS 的一些特性

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

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

rw 表示可寫可讀 read-write。

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

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

權限中,我們看到了一個術語:whiteout,下面我來解釋一下這個術語。

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

看個例子:

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

1

2

3

4

5

6

7

8

9

# tree

.

├── fruits

│  ├── apple

│  └── tomato

├── test

└── vegetables

 ├── carrots

 └── tomato

我們如下 mount:

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

現在我們在權限為 rw 的 test 目錄下建個 whiteout 的隱藏文件.wh.apple,你就會發現./mnt/apple 這個文件就消失了:

1

2

3

4

# touch ./test/.wh.apple

 

# ls ./mnt

carrots  tomato

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

相關術語

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

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

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

?Whiteout  和 Opaque

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

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

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

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

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

相關問題

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

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

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

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

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

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

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

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 方式。

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

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 怎么使用”有了更深的了解,不妨來實際操作一番吧!這里是丸趣 TV 網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

正文完
 
丸趣
版權聲明:本站原創文章,由 丸趣 2023-08-16發表,共計6863字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 白银市| 周至县| 建瓯市| 曲靖市| 宣城市| 吉木萨尔县| 东辽县| 渝北区| 拉孜县| 鄂托克旗| 兴化市| 曲阳县| 绥中县| 开鲁县| 日喀则市| 增城市| 济源市| 五常市| 乡宁县| 广水市| 焉耆| 华蓥市| 黄骅市| 浦北县| 南涧| 砀山县| 珠海市| 白银市| 大厂| 天气| 滦平县| 游戏| 邯郸县| 偏关县| 墨玉县| 潼南县| 莱阳市| 和顺县| 珠海市| 英超| 寿宁县|