AUFS是docker最早支援的儲存引擎。 AUFS是一種Union File System,是檔案層級的儲存驅動,是Docker早期用的儲存驅動,是Docker18.06版本之前,Ubuntu14.04版本前推薦的,支援xfs、ext4檔案。
本教學操作環境: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的分层镜像,除了aufs,docker还支持btrfs, devicemapper和vfs,你可以使用 -s 或 storage-driver= 选项来指定相关的镜像存储。在Ubuntu 14.04下,docker默认Ubuntu的 aufs(在CentOS7下,用的是devicemapper,关于devicemapper,我会以以后的文章中讲解)你可以在下面的目录中查看相关的每个层的镜像:
/var/lib/docker/aufs/diff/<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视频教程》
以上是什麼是docker最早支援的儲存引擎的詳細內容。更多資訊請關注PHP中文網其他相關文章!