主要回答的問題
- aufs原始的用途
- aufs的普通演示
- aufs在docker中的使用的演示
- aufs,overlays的架構
- 明白docker鏡像的本質只是文件.
docker容器就是在鏡像層上又增加了可讀寫的容器層,然后聯合掛載到宿主機的一個掛載點上。使得運行時對容器的所有修改都只針對這個容器層,不影響鏡像文件 - aufs缺點,overlays優點
- aufs沒有加入linux內核, ubuntu默認支持,centos默認不支持。
設置CentOS支持aufs
[/sys/fs/aufs/目錄]
-
/sys/fs目錄 按照設計是用於描述系統中所有文件系統,包括文件系統本身和
按文件系統分類存放的已掛載點,但目前只有 fuse,gfs2 等少數文件系統支持 sysfs 接口,一些傳統的虛擬文件系統(VFS)層次控制參數仍然在 sysctl (/proc/sys/fs) 接口中中; -
使用 /sys 文件系統訪問 Linux 內核
sysfs 虛擬文件系統提供了一種比 proc 更為理想的訪問內核數據的途徑
https://www.ibm.com/developerworks/cn/linux/l-cn-sysfs/index.html
root@192:/tmp/aufs# ls /sys/fs/
aufs bpf cgroup ecryptfs ext4 fuse pstore
root@192:/tmp/aufs# ls /sys/fs/ext4/
features sda1
root@192:/tmp/aufs# ls /sys/fs/aufs/
config si_e8bf3ef3161c9271
aufs的架構
- 只讀層+讀寫層 mount> 宿主機的union掛載點, 作為容器的根目錄。
只讀層就是鏡像,讀寫層是執行docker run時新增的容器層, 對容器的修改就是對union掛載點的修改,只影響讀寫層。
直接修改宿主機的掛載點,也就是修改容器的根目錄,反之亦然。

aufs的關鍵技術
看起來這個虛擬后的聯合文件系統是可以對任何文件進行操作的,但是其實它並沒有改變原來的文件。這是因為 Union File System 用到了一個重要的資源管理技術:寫時復制。
但是 aufs 出現的時間要比 docker 長很多,它常見的用法包括
參考附錄1
- Linux 光盤演示和教程,錄制了 Linux 的光盤可以用來讓用戶體驗,但是光盤的內容是只讀的,可以通過 aufs 把光盤和 U 盤或者磁盤 mount 到一起,用戶對文件的修改保存到后面的存儲上
- 如果系統上因為各種原因,不同用戶的 home 目錄保存在不同的路徑和磁盤上,可以通過 aufs 把它們 mount 到一起,統一進行操作
AUFS演示
centos默認是沒有啟動aufs的,然后安裝過程中出現了不少問題,所以就用ubuntu來演示了。
第一個例子
參考附錄1
base 作為底層的目錄
top 作為上層的目錄
mnt: aufs 使用的掛載點,會把上面兩個目錄掛載到這里
第2個例子
參考附錄2(包含圖示講解)
// 掛載后未修改時,container-layer目錄有1個文件
root@192:/tmp/aufs# tree
.
├── container-layer
│ └── container-layer.txt
├── image-layer1
│ ├── image-layer1.txt
│ └── subdir1
│ └── subdir1.txt
├── image-layer2
│ ├── image-layer2.txt
│ └── subdir2
│ └── subdir2.txt
├── image-layer3
│ ├── image-layer3.txt
│ └── subdir3
│ └── subdir3.txt
├── mnt
│ ├── container-layer.txt
│ ├── image-layer1.txt
│ ├── image-layer2.txt
│ ├── image-layer3.txt
│ ├── subdir1
│ │ └── subdir1.txt
│ ├── subdir2
│ │ └── subdir2.txt
│ └── subdir3
│ └── subdir3.txt
└── run.sh
11 directories, 15 files
// 2. 對rw層(readwrite)的文件進行修改。直接修改。
root@192:/tmp/aufs# echo 666 > ./mnt/container-layer.txt
root@192:/tmp/aufs# cat container-layer/container-layer.txt
666
// 3. 對ro層(readonly)的文件進行修改。copy到rw讀寫層之后再wrtie。(copy on write)
root@192:/tmp/aufs# echo 777 > ./mnt/image-layer1.txt
root@192:/tmp/aufs# cat image-layer1/image-layer1.txt
I am image layer 1
root@192:/tmp/aufs# cat ./mnt/image-layer1.txt
777
// 4. 對ro層進行修改后的目錄樹,container-layer目錄(rw層)增加了1個文件
root@192:/tmp/aufs# tree
.
├── container-layer
│ ├── container-layer.txt
│ └── image-layer1.txt // ydd:這是copy on write的文件
├── image-layer1
│ ├── image-layer1.txt
│ └── subdir1
│ └── subdir1.txt
├── image-layer2
│ ├── image-layer2.txt
│ └── subdir2
│ └── subdir2.txt
├── image-layer3
│ ├── image-layer3.txt
│ └── subdir3
│ └── subdir3.txt
├── mnt
│ ├── container-layer.txt
│ ├── image-layer1.txt
│ ├── image-layer2.txt
│ ├── image-layer3.txt
│ ├── subdir1
│ │ └── subdir1.txt
│ ├── subdir2
│ │ └── subdir2.txt
│ └── subdir3
│ └── subdir3.txt
└── run.sh
11 directories, 16 files
演示docker使用aufs作為storage driver
借助這個場景來理解:宿主機如何往運行中的docker容器中傳輸文件--Q: docker運行中的容器又是存在哪里的
AUFS的缺點
參考附錄1
- 最大的問題是它不沒有進入到 Linux 內核,因此不能保證可移植性,雖然像 ubuntu 這種發行版默認支持 aufs,但並不是所有系統都如此,比如
centos 就默認沒有提供 aufs 支持。之所以沒有合並到內核,據說是因為 aufs 的實現代碼很冗雜,Linus 認為代碼質量太差,雖然開發者多次精簡,最終還是沒有進入到內核,而且在短時間內也不會有什么變化。 - 我們至少能看到兩個性能問題:第一次修改一個大文件會非常耗時;另外層級過多也會影響整體的讀寫性能。
docker默認的存儲驅動已經演進到了overlay2
-
overlay架構 / /附錄5

-
附錄3
雖然當前 docker 默認的存儲驅動已經演進到了 overlay2,但是學習 AUFS 依然可以幫助我們深入理解 docker 中的文件系統。 -
附錄4
在最新的 Docker 中,overlay2 取代了 aufs 成為了推薦的存儲驅動,但是在沒有 overlay2 驅動的機器上仍然會使用 aufs 作為 Docker 的默認驅動。
其他對容器鏡像的理解
附錄4
- Docker 鏡像其實本質就是一個壓縮包,我們可以使用下面的命令將一個 Docker 鏡像中的文件導出:
- 容器和鏡像的區別就在於,所有的鏡像都是只讀的,而每一個容器其實等於鏡像加上一個可讀寫的層,也就是同一個鏡像可以對應多個容器。
