2023 iT邦鐵人賽 Day 15 - 容器的資料儲存-Volume 掛載

前言

昨天我們講解了容器如何儲放資料,關於掛載的部分,只講了約定掛載,今天我們來講講有別於儲放在本機的 volume 掛載。

Volume 掛載

volume 是 docker 裡的一個儲存元件,有別於掛載,volume 是從 docker 內切出一塊獨立空間出來,提供容器使用,讓容器可以儲放資料。因此,容器被刪除,也不會影響到 volume。那這個被另外切出來的空間,也是要透過掛載,讓 volume 跟容器彼此連結。

建立 volume

既然如此,那代表 volume 也是要另外創造:

1
2
> docker volume create --name iThome_volume
iThome_volume

查看 volume 清單

然後我們可以查看 volume 的清單:

1
2
3
> docker volume ls                                                                                              ✔  3.1.3   16:28:48
DRIVER VOLUME NAME
local iThome_volume

查看 volume 細部資料

也可透過 inspect 查看 volume 的詳細資料:

1
2
3
4
5
6
7
8
9
10
11
12
> docker volume inspect iThome_volume                                                                           ✔  3.1.3   16:29:06
[
{
"CreatedAt": "2023-09-10T08:27:43Z",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/iThome_volume/_data",
"Name": "iThome_volume",
"Options": null,
"Scope": "local"
}
]

volume 的起源

嘗試再建立另外一個 volume ,並看兩者的 Mountpoint :

1
2
3
4
5
iThome_volume:
"Mountpoint": "/var/lib/docker/volumes/iThome_volume/_data"

another_volume:
"Mountpoint": "/var/lib/docker/volumes/another_volume/_data"

由此可知, volume 是從 docker 裡去另外製造出來的。

與容器連結

這裡也是使用 --mount-v ,但要注意的是 --mounttypevolume ,而不是 bind :

1
2
3
4
5
docker container run --name iThome --mount type=volume,source=iThome_volume,target="/usr/local/apache2/htdocs/" -p 8001:80 -d httpd



docker container run -v iThome_volume:/usr/local/apache2/htdocs/ -d httpd

然後我們 inspect 容器,可以看到容器 Mountssource 就是剛剛我們 inspect volume 時的 Mountpoint

Volume 相關指令

除了上述的建立 volumecreate 以外,還有很多常用的指令,像是 ls 查看 volume 清單, inspect 查看特定 volume, rm 刪除 volume。用法跟容器的一樣。只是把 container 改成 volume

那我們來試著刪除剛剛 iThome 容器的 volume iThome_volume ,這時會發現他不給刪:

1
2
3
> docker volume rm iThome_volume

Error response from daemon: remove iThome_volume: volume is in use - [4671d716df2040b93ff740f8466bd80909af55196b33e8a407a93299b45b18a9]

錯誤訊息很明顯告訴我們, volume 使用中。這是一個很正常的機制。

如果想要刪除掉 volume ,就必須確保沒有容器在使用 volume 後才能刪除。

所謂的沒有容器在使用是指,使用該 volume 的容器,必須都被刪除了,已經沒有這些使用它的容器了,如果只是把容器 stop 或 kill,那仍然還是在使用著 volume ,一樣刪不掉 volume

volume 使用的具體實例

講了這麼多,到底誰會用到 volume 呢? 只要是會產生資料的容器,就需要 volume 嗎? 其實未必。

Rails 舉例, Rails 專案的容器會有 Rails app 本身的容器,另外還會有與 Rails 串接的資料庫容器,兩種容器 ( 這裡只談簡配、不談 sidekiq, redis )。這裡會需要 volume 的只有資料庫容器,因為資料庫容器是負責資料儲放的容器。透過 Rails 產生的資料,會經過容器間的通訊,將資料傳遞給資料庫容器,所以需要將儲放資料的容器進行掛載,讓資料得以被保存。

總結

讓我們來簡單整理一下今天的 Volume

  • 另外創建的儲存元件,可比喻為隨身碟。
  • 不會因為容器的刪除而跟著被刪除,獨立於容器的生命週期。
  • 若仍有容器使用著 volume ,就無法刪除 volume

那容器就介紹到這邊,接下來我們要進入到也是很重要的映像檔 image 的世界了。