iT邦幫忙

2022 iThome 鐵人賽

DAY 8
0
DevOps

那些關於 docker 你知道與不知道的事系列 第 8

Day 08: 什麼是 copy-on-write 跟 whiteout?

  • 分享至 

  • xImage
  •  

回憶一下昨天的進展,我們利用 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

https://ithelp.ithome.com.tw/upload/images/20220922/20151857ZHxfX0chbx.png


現在讓我們來做兩個小實驗:

實驗 1: 修改檔案

編輯 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

https://ithelp.ithome.com.tw/upload/images/20220922/20151857lxbMIkjvGM.png

可以看到 merged/b.txt 的確消失了,但 lower2/b.txt 還在,而且 upper 中還多了一個 b.txt,這邊特別用截圖的方式分享給大家,可以看到 upper/b.txt 的顏色是黃色,跟其他檔案都不太一樣。


以上兩個實驗,是不是有點違反直覺?但這兩個實驗驗證了 OverlayFS 的一些機制,關於這部分 docker 官網其實整理的很好,連結放在最後的參考資料,有興趣的可以看一下,接下來的內容也是根據官網整理出來的。

  1. 讀檔
  • 如果檔案是在 upper 裡,且不存在於 lower 裡 -> 就直接讀取 upper 層裡的檔案
  • 如果檔案不是在 upper 裡,但是在 lower 裡 -> 那就從 lower 層裡讀取,這裡會有一點點性能上的耗損。
  • 如果檔案在 upper 跟 lower 裡都有,那會讀取 upper 層中的那個檔案,也就是上層的檔案會隱藏下層同名的檔案。(不只是 upper 層中的檔案會隱藏下層,透過上述實驗觀察,我們也可以看到 lower1/x.txt 隱藏掉了 lower2/x.txt)
  1. 寫檔
  • 如果檔案是在 upper 裡,且不存在於 lower 裡 -> 就直接修改 upper 層裡的檔案
  • 如果檔案不是在 upper 裡,但是在 lower 裡 -> 會用 copy-on-write (COW)策略來處理,也就是會從 lower 層複製這個要被寫的檔案到 upper 層中,然後再對這個新複製出來的檔案進行寫檔,這個從底層複製到 upper 層的動作稱為 copy_up 操作。這邊要特別注意的是,OverlayFS 的運作方式是 file level 而不是 block level,這意思是,就算這個檔案你只想要改一點點,OverlayFS 的 copy_up 操作仍然會從底層複製整個完整的檔案到上層,可以想像,如果這個檔案很大的話,那勢必會有一些顯著的效能耗損。不過,還好的是,只有第一次要寫底層檔案的時候,才會有 copy_up 這個操作,之後的讀寫就可以直接對 upper 中的這個新檔案進行了。

https://ithelp.ithome.com.tw/upload/images/20220922/20151857pSVyRZHAn7.png

  1. 刪檔:
  • 如果要被刪除的檔案是在 upper 裡,且不存在於 lower 裡 -> 就直接刪除 upper 層裡的檔案
  • 如果要被刪除的檔案不在 upper 裡,但是在 lower 裡 -> 那會在 upper 層建立一個 whiteout 檔案,也就是我們在 upper 中觀察到的 b.txt,在 lower 檔案夾中的檔案不會真的被刪除掉,在 upper 層中的這個 whiteout 檔案會讓這個檔案在聯合目錄中不可被存取到。
  • 如果是要刪除一個存在於 lower 層的檔案夾,那會在 upper 層建立一個 opaque 的檔案夾,跟 whiteout 的用途一樣,他會使下層的同名檔案夾無法被存取到,看起來就像刪掉了一樣。

https://ithelp.ithome.com.tw/upload/images/20220922/20151857FTLuJI4Gq8.png


不知道整理到這邊,大家有沒有好奇以下兩個操作會發生什麼事?

  1. 那如果是對檔案重新命名呢?

這是把 merged/x.txt 改名為 merged/x1.txt 的結果:
https://ithelp.ithome.com.tw/upload/images/20220922/20151857WSepan46qU.png

看起來應該是把 lower1/x.txt copy_up 到 upper 層中,並且在 upper 中做了一個 x.txt 的 whiteout file,使 lower1/x.txt 不可在 merged 中被存取了,也就是結合了寫檔跟刪檔兩個操作。

  1. 實驗 1 在寫 a.txt 時,因為檔案存在於 lower 層,所以進行了 copy_up 將檔案複製到 upper 層來,這時候如果去刪除掉 a.txt,會發生什麼事呢?會因為 upper 中的 a.txt 被刪掉,而使被隱藏的下層檔案變成可存取嗎?答案是不會的,其結果如下:

https://ithelp.ithome.com.tw/upload/images/20220922/20151857Uz2fsy6hDd.png

可以觀察到 upper 中的 a.txt 不見了,但多了一個 whiteout file (標示為黃色) 來下層的 a.txt 不可存取。


關於 overlay 的實驗就到這裡,是不是超有趣的呢?下篇我們再來把 OverlayFS 套進 docker container 與 image 中吧!


參考資料:


上一篇
Day 07: 什麼是 overlay2?
下一篇
Day 09: 所以,到底什麼是 image?
系列文
那些關於 docker 你知道與不知道的事32
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言