2023 iT邦鐵人賽 Day 14 - 容器的資料儲存-約定掛載

前言

前幾天,我們不斷地在說明容器,對容器的熟悉度應該就像認識三十年的朋友一樣熟悉了。但這樣還是不夠的,我們必須要知道,你朋友的錢存在哪裡 (咦!?)。

今天我們就來談談朋友的錢存在哪(容器裡應用程式產生的資料存在哪)吧。

檔案系統

每個容器都有屬於自己的檔案系統,而最基本的檔案系統是由映像檔的共享層與容器內的可寫層所構成。

可寫層

映像檔本身是多個層 ( Layer ) 所組成,就像一份漢堡的組成一樣,一層又一層。

當容器建立並啟動時,容器的檔案系統除了有映像檔的各層以外,docker 會自動加入可寫層,以供容器有個暫時儲存資料與檔案的地方。

因此,可寫層是跟隨著容器的生命週期,可寫層會在容器被刪除後,也跟著消失,所以:

1
容器裡產生的資料 ---> 可寫層 ---> 容器被刪除 ---> 可寫層被刪除 ---> 資料消失

但這不是我們想要遇到的問題,在前一篇可知,容器的汰舊換新是常態。

除了前一篇提到的更替狀況,還有一種情況是,部署新版 (新的功能或是修復已知 bug) 的專案時,這時我們會一定是部署新的容器上去,並把舊的刪掉。敏感的你,是不是察覺不對勁?

Production 的資料是不是就啪一聲的不見了….?

我們當然不能因為更新就讓會員資料全部都消失殆盡,所以 docker 有提供了永續性的資料儲存方式: 約定掛載Volume

約定掛載 / 綁定掛載

說文解字。約定,即雙方意思合意,你心甘、我情願,因此在雙方認定的範圍內,互通有無; 掛載,也就是將元件、資料等與其他元件跟資料或系統連結。

在 docker 裡,就是透過設定 (約定),將本機資料與容器連結在一起 (掛載):

  • 將本機的資料夾掛載到容器內,使資料雙向綁定。
  • 當掛載的目標資料夾已存在檔案時,而使用約定掛載時,會被本機的資料夾所覆蓋,此時容器的資料只會有本機資料夾內的資料。
  • 若在約定掛載時,掛載來源為單一檔案,此時會與容器內的資料互相合併。

指令

--mount type=bind,source="容器內資料儲存的目錄",target="本機資料夾目錄"

沒錯,你沒看錯,這一整串就是在做約定掛載,我們需要指定資料流通的兩端( source, target )。

type、source、target 之間必須要有逗號,且逗號間不能有空格。

什麼?好麻煩?OK, Docker 聽到你的心聲了,那就用 -v 容器內資料儲存的目錄:本機資料夾目錄

範例

  1. 在目錄 /Users/mike/Desktop/bind 裡建立 index.html 檔案
  2. body tag 裡面輸入任何你想要的畫面設計,這裡為了簡單示範,我在我的 index.html 只輸入 <h1>**This is new data</h1>**
  3. 輸入以下約定指令:
1
2
3
4
5
docker container run --mount type=bind,source="/Users/mike/Desktop/bind",target="/usr/local/apache2/htdocs/" -p 8001:80 -d httpd



docker container run -v /Users/mike/Desktop/bind:/usr/local/apache2/htdocs/ -d httpd
  1. 進入 http://localhost:8001/

原本在 http://localhost:8001/ 應該會出現 It Works! ,現在變成**This is new data 。**

這代表,目前已經將我綁定的本機目錄與容器連上了,資料雙向流通。

那為什麼原本是 It Works! ,現在變了。那是因為在容器裡, /usr/local/apache2/htdocs/ 底下,原本有 index.html 檔案,現在經過約定掛載後,將原本容器內的資料給覆蓋過去。如上面說明的第三點。

補充

大家可以嘗試建立一個無掛載的 httpd 跟有掛載的 httpd,並使用 inspect 看一下兩者容器內的 Mounts

總結

今天的東西可能會比較難一點,我們來做個總結吧。

現在我們知道,容器的資料可以存放在暫時性的可寫層,但可寫層會跟容器一起被刪掉,導致資料無法長存於世,這對 production 來說,不堪使用。

於是我們有掛載的方法,將資料長期存放。透過約定掛載,我們可以將容器的資料存放在本機的資料夾 (目錄) 中,同時我們也可以更改本機裡的資料。

因為內容有點龐大,用一篇寫完後發現,東西實在太多了 (汗),為了減輕讀者負擔,所以今天先只說明檔案系統跟約定掛載,明天我們會來講解另一個神秘空間 volume。

關於「層」,我們會在之後特別寫一篇文章為大家解釋。今天我們先暫時為了可寫層,間單對映像檔做個基本介紹。