什么是docker最早支持的存儲引擎

AUFS是docker最早支持的存儲引擎。AUFS是一種Union File System,是文件級的存儲驅動,是Docker早期用的存儲驅動,是Docker18.06版本之前,Ubuntu14.04版本前推薦的,支持xfs、ext4文件。

什么是docker最早支持的存儲引擎

本教程操作環境:linux7.3系統、docker20版、Dell G3電腦。

AUFS是docker最早支持的存儲引擎。

Docker 的存儲引擎

Docker 的存儲引擎設計思路是這樣,但是針對不同的文件系統,是由不同的存儲驅動去實現的。下面我們來聊聊 Docker 的存儲驅動。

Docker 主要有一下幾類存儲驅動:

  • overlay2:是當前版本推薦的存儲驅動,無需額外的依賴和配置即可發揮絕佳的性能。在 18.09 版本之后替換了 overlay 存儲驅動。支持 xfs,ext4 文件系統。

  • aufs:Docker 最早期使用的存儲驅動,是 Docker 18.06 版本之前,Ubuntu 14.04 版本前推薦的。支持 xfs,ext4 文件系統。

  • devicemapper:是較早版本的 CentOS 和 RHEL 系統推薦的存儲驅動,因為它們不支持 overlay2,需要 direct-lvm 的支持。

  • btrfs:僅用于 btrfs 文件系統。

  • zfs:僅用于 zfs 文件系統。

  • vfs:不依賴于文件系統,但是性能奇差,主要用來測試。

需要注意的是,overlay2,overlay,aufs 的層是基于文件的,當單文件的寫并發較高時需要大內存的支持,且讀寫層可能因為單個文件而變得很大。devicemapper,btrfs,zfs 的層是基于塊存儲的,因此對于單個文件的高并發影響不大。但是 btrfs 和 zfs 非常消耗內存。

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)

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

$?tree . ├──?fruits │???├──?apple │???└──?tomato └──?vegetables ????├──?carrots ????└──?tomato

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

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

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

$?echo?mnt?>?./mnt/apple $?cat?./mnt/apple mnt $?cat?./fruits/apple mnt

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

$?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的文件刪除了):

$?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這個文件,那么究竟是哪個文件會被改寫?

$?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最早支持的存儲引擎

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

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

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來檢查文件變動通知。

推薦學習:《docker視頻教程

以上就是什么是

? 版權聲明
THE END
喜歡就支持一下吧
點贊12 分享