回憶一下昨天的進展,我們利用 OverlayFS 的方式 mount 出了 merged 檔案夾,目前檔案結構如下:
~/overlay-test$ tree
.
├── lower1
│ ├── a.txt
│ └── x.txt
├── lower2
│ ├── b.txt
│ └── x.txt
├── merged
│ ├── a.txt
│ ├── b.txt
│ ├── c.txt
│ └── x.txt
├── upper
│ └── c.txt
└── work
└── work [error opening dir]
6 directories, 9 files
現在讓我們來做兩個小實驗:
編輯 merged/a.txt,在這個檔案中加上 "merge" 這個字串:
$ cat merged/a.txt
merge
$ cat lower1/a.txt
(仍是空檔案)
這時候來看一下 upper 檔案夾的內容:
$ tree upper/
upper/
├── a.txt
└── c.txt
0 directories, 2 files
$ cat upper/a.txt
merge
upper 檔案夾裡原本只有 c.txt,但現在 a.txt 卻跑出來了,且其內容跟 merge/a.txt 中的一模一樣,是不是很神奇呢!為什麼編輯了 merged 中的 a.txt,沒有更改到 lower1/a.txt,卻反而讓 upper 裡多一個 a.txt?
讓我們把 merged 中的 b.txt 刪掉:
rm merged/b.txt
~/overlay-test$ tree
可以看到 merged/b.txt 的確消失了,但 lower2/b.txt 還在,而且 upper 中還多了一個 b.txt,這邊特別用截圖的方式分享給大家,可以看到 upper/b.txt 的顏色是黃色,跟其他檔案都不太一樣。
以上兩個實驗,是不是有點違反直覺?但這兩個實驗驗證了 OverlayFS 的一些機制,關於這部分 docker 官網其實整理的很好,連結放在最後的參考資料,有興趣的可以看一下,接下來的內容也是根據官網整理出來的。
copy_up
操作。這邊要特別注意的是,OverlayFS 的運作方式是 file level 而不是 block level,這意思是,就算這個檔案你只想要改一點點,OverlayFS 的 copy_up
操作仍然會從底層複製整個完整的檔案到上層,可以想像,如果這個檔案很大的話,那勢必會有一些顯著的效能耗損。不過,還好的是,只有第一次要寫底層檔案的時候,才會有 copy_up
這個操作,之後的讀寫就可以直接對 upper 中的這個新檔案進行了。whiteout
檔案,也就是我們在 upper 中觀察到的 b.txt,在 lower 檔案夾中的檔案不會真的被刪除掉,在 upper 層中的這個 whiteout
檔案會讓這個檔案在聯合目錄中不可被存取到。opaque
的檔案夾,跟 whiteout
的用途一樣,他會使下層的同名檔案夾無法被存取到,看起來就像刪掉了一樣。不知道整理到這邊,大家有沒有好奇以下兩個操作會發生什麼事?
這是把 merged/x.txt 改名為 merged/x1.txt 的結果:
看起來應該是把 lower1/x.txt copy_up
到 upper 層中,並且在 upper 中做了一個 x.txt 的 whiteout
file,使 lower1/x.txt 不可在 merged 中被存取了,也就是結合了寫檔跟刪檔兩個操作。
copy_up
將檔案複製到 upper 層來,這時候如果去刪除掉 a.txt,會發生什麼事呢?會因為 upper 中的 a.txt 被刪掉,而使被隱藏的下層檔案變成可存取嗎?答案是不會的,其結果如下:可以觀察到 upper 中的 a.txt 不見了,但多了一個 whiteout file (標示為黃色) 來下層的 a.txt 不可存取。
關於 overlay 的實驗就到這裡,是不是超有趣的呢?下篇我們再來把 OverlayFS 套進 docker container 與 image 中吧!