iT邦幫忙

0

筆記:Docker Image 與 Container 隨筆

  • 分享至 

  • xImage
  •  

筆記:Docker Image 與 Container 隨筆

一層一層 layer 疊起來的 Image

什麼是 image?簡單的解釋,就是一個唯讀範本, docker 可以讀取這個範本然後產生出一個 container 來運行。

一個 Docker Image 的內部是由多個 Layer 所一層一層疊加起來的。每一層 layer 裡面,各自會有各自不同儲存的設定跟檔案。例如第一層 layer 可能是只儲存一些環境設定,第二層 layer 有服務執行相關的檔案……等。最後這些各層不同的 layer 合起來,就是一個 image 檔案。

這些不同的 layer 可以從 docker image inspect [image_name] 指令來觀察到,下完這個指令後出現的描述內容,可以很容易找到 RootFS底下的Layers欄位,裡面就會列出所有的 layer。

在每個 layer 後面都有不同的 hash 值,這可以讓不同的 image 檔案在 container 跑起來時,docker 會幫忙是否已經有同樣的 layer 檔案,有的話就可以拿來重覆使用


檔案聯集的 Union Mount

這麼多層的 layer 之所以可以重疊在一起呈現,是因為有個叫 union mount 的東東在背後運作。

https://ithelp.ithome.com.tw/upload/images/20260415/20144508i9stcC5aFP.png

這時候可以發揮一下想像力,假設電腦裡有2個資料夾,但我們要把他合併(union),然後只用1個資料夾來做呈現。這時候所謂的聯集做法,就是會把FolderA + FolderB二邊都有的資料加起來,最後合併完一起顯示在 merged 資料夾。

--FolderA
  |-file1.txt
  |-file2.txt
--FolderB
  |-file2.txt
  |-file3.txt
--FolderUnion
  |-file1.txt
  |-file2.txt(會被後蓋前)
  |-file3.txt

union mount 是一種概念,就像 SQL 裡的 union 一樣,它不是什麼規格的定義或規範。只要能實作出把二個東西合併(聯集)起來,都算是一種 union mount 的實作。像我在 AWS EC2 測試用所開的 ubuntu 系統,看到的就是 overlayFS。假如是在 windows or mac 上看到的應該就又會不同。

在 union mount 跑起來的時候,可以預期會有 lower, upper & merged 三個部份(還有個 work,但先不提)。

  • lower 層:可以解讀成是唯讀來源。這個來源可以有很多個,在 image 檔裡 lower 層就是剛才提到的很多層的 layer。lower 層的特性是一定是唯讀的,不管對 mount 後的資料做任何異動,都不會影響到 lower 層裡的資料。

  • upper 層:可以解讀成是可修改來源。在 image 檔裡 upper 層就是 container 跑起來的時候產生的。upper 層的特性是,可以對裡面的資料做任何異動,但這些異動都只會影響到 upper 層,決對不會影響到 lower 層。所以當我們在跑一個 container 所傳入的參數設定,其實都會是在 upper 層裡面,不會去動到 lower 層。

  • merged 層:可以解讀成是合併後的結果。剛才的 lower + upper 二個所聯集後的結果,也就是我們在 container 裡所看到的環境跟資料了。


copy-on-write 機制

merged 層是聯集後所顯示的結果,也就是我們看得到絕對唯讀的 lower 層檔案,甚至還能對它進行修改。但這樣說又有點矛盾,因為剛才一直在提 lower 層一定是是唯讀的。

這時候就有另外一個機制叫 copy-on-write。白話就是……寫入的時候再複製。

但簡單來說,在 container 的環境裡修改檔案,理論上就只有二個情境。

  • 改到 lower 層的檔案:要修改的檔案在 upper 層沒有,它只存在 lower 層裡。這時候就會觸發 copy-on-write 的機制,也就是會把 lower 層裡的檔案複製一份到 upper 層,然後所有的檔案異動都是在 upper 層發生。這樣就可以保證 lower 層的檔案不會被異動到, upper 層的檔案也不會被其他 container 影響到。但這裡就要注意,從 lower 層複製到 upper 層,代表原本的檔案會在,upper 層也會有一個相同的檔案,所以一個檔案會放二邊。當要被異動的這個動案有點大的時候,時間跟空間的成本就會稍微高一些。

  • 改到 upper 層的檔案:要修改的檔案 upper 層裡面有(不管 lower 層有沒有),這時候就沒有什麼 copy-on-write 的機制,直接所有的異動都直接發生在 upper 層。


whiteout 機制

除了 copy-on-write,upper 層還另一個機制叫 whiteout,概念比較像是刪除註記。

在 merged 層除了剛才的修改動作外,也有機會會有刪除的動作。刪除動作基本上跟 copy-on-write 一樣,大致上就二種情境。

  • 刪除 lower 層的檔案:要刪除的檔案在 upper 層沒有,它只存在 lower 層裡。這時候就會觸發 whiteout 的機制,也就是會在 upper 層建立一個 whiteout 檔案(很像是註記一樣),這個 whiteout 檔案會把 lower 層的檔案遮起來,讓它在 merged 層時不會顯示。但實際上 lower 層的檔案還是存在(絕對唯讀),只是在 merged 層時看不到而已。

  • 刪除 upper 層的檔案:要刪除的檔案在 upper 層裡,這時候不會觸發 whiteout 機制,會實際把 upper 層的檔案直接刪除。


心得

初次研究 docker image 的內部原理,發現真的是蠻聰明的……。照著 instruction 來自己 commit 一個 image 出來,再 inspect 他的變化,也多出了不少的靈感。期待在玩 Dockerfile 的時候可以有其他更多的靈感~~


圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言