Docker Certified Associate(DCA)認證考試學習- VOLUME Docker Certified Associate(DCA)認證相關資源、VOLUME

Published on Sunday, February 26, 2023

Dockerfile VOLUME

在此篇文章中: Docker Certified Associate(DCA)認證考試學習-Docker可讀寫層
我們知道 Docker 在建立 container 的時候會在 image layer 上再多加一層可讀寫層
但是有一個問題是此如果將 container 刪除,那麼在我們剛剛在可讀寫層所作的變更會一起被刪除掉
所以像是讀寫資料庫這種需求,如果資料沒辦法持久保存那顯然是會造成很大的問題
這時最簡易的作法可以在 Dockerfile 之內使用 VOLUME 指令

首先先看看Volume文檔,Docker提供了兩種資料持久化的方法 VolumesBind mounts

mounts-volume mounts-bind

Volumes 將檔案放在 Host 的 FileSystem 內部的 Docker 存放區, Volumes 完全由 Docker 管理 Bind mount 將檔案放在 Host 的 FileSystem 所設定的目錄上,需要自行管理

今天主要討論Volumes,首先先建立測試環境
這邊新設定了一個 volume newvolume

#Dockerfile
FROM alpine

VOLUME /newvolume
docker build -t volumetest .
docker run -dit volumetest

使用此命令可以列出指定 container 的所有 Volumes

docker inspect -f '{{ json .Mounts }}' containerid

目前此 container 有掛載一個 volume

[node1] (local) root@192.168.0.18 ~/volume
$ docker inspect -f '{{ json .Mounts }}' 4e63
[{"Type":"volume","Name":"72a7c18e11d0e7e5563a2c6c19be26d2aef0a6412d4ba47730c026f24d591946","Source":"/var/lib/docker/volumes/72a7c18e11d0e7e5563a2c6c19be26d2aef0a6412d4ba47730c026f24d591946/_data","Destination":"/newvolume","Driver":"local","Mode":"","RW":true,"Propagation":""}]

這邊因為 Volumes 是由 Docker 統一管理的所以名稱跟路徑是由 Docker 產生的,所以會看起來想亂數產生的,比較重要的有以下幾個

  • Name : "72a7c18e11d0e7e5563a2c6c19be26d2aef0a6412d4ba47730c026f24d591946"
  • Source : "/var/lib/docker/volumes/72a7c18e11d0e7e5563a2c6c19be26d2aef0a6412d4ba47730c026f24d591946/_data"
  • Destination : "/newvolume"

使用此命令可以列出 Docker 中所有 Volume

docker volume ls

這邊列出來的結果中的 VOLUME NAME ,這個值跟我們之前查看掛載在 container 上 Volume 的 Name 值一樣

[node1] (local) root@192.168.0.18 ~/volume
$ docker volume ls
DRIVER    VOLUME NAME
local     72a7c18e11d0e7e5563a2c6c19be26d2aef0a6412d4ba47730c026f24d591946

接下來看看 Source 這個值中的地址,因為我們知道為了要持久化,所以 Docker 會將檔案保存到 Host 的 FileSystem 內部的 Docker 存放區
也就是我們看到的這個 Source 地址,也就是說此地址內部的內容會即時顯示在 Container 內部
我們可以在這邊寫個檔案試試看

cd /var/lib/docker/volumes/72a7c18e11d0e7e5563a2c6c19be26d2aef0a6412d4ba47730c026f24d591946/_data
touch Hello

之後進入到 container 內部,注意到清單之內有一個 newvolume 資料夾,也就是之前查詢的 Destination, 代表這個資料夾其實背後是跟 /var/lib/docker/volumes/72a7c18e11d0e7e5563a2c6c19be26d2aef0a6412d4ba47730c026f24d591946/_data 這個 Host 路徑連動的

docker attach 4e63
/ # ls -l
total 8
drwxr-xr-x    2 root     root          4096 Feb 10 16:45 bin
drwxr-xr-x    5 root     root           360 Feb 26 14:07 dev
drwxr-xr-x    1 root     root            66 Feb 26 14:07 etc
drwxr-xr-x    2 root     root             6 Feb 10 16:45 home
drwxr-xr-x    7 root     root           243 Feb 10 16:45 lib
drwxr-xr-x    5 root     root            44 Feb 10 16:45 media
drwxr-xr-x    2 root     root             6 Feb 10 16:45 mnt
drwxr-xr-x    2 root     root            19 Feb 26 14:41 newvolume
drwxr-xr-x    2 root     root             6 Feb 10 16:45 opt
dr-xr-xr-x 1231 root     root             0 Feb 26 14:07 proc
drwx------    1 root     root            26 Feb 26 14:42 root
drwxr-xr-x    2 root     root             6 Feb 10 16:45 run
drwxr-xr-x    2 root     root          4096 Feb 10 16:45 sbin
drwxr-xr-x    2 root     root             6 Feb 10 16:45 srv
dr-xr-xr-x   13 root     root             0 Feb 24 21:32 sys
drwxrwxrwt    2 root     root             6 Feb 10 16:45 tmp
drwxr-xr-x    7 root     root            66 Feb 10 16:45 usr
drwxr-xr-x   12 root     root           137 Feb 10 16:45 var

測試後確實兩邊是連動的,因為有出現我們剛剛建立的 Hello 檔案

/ # cd newvolume/
/newvolume # ls
Hello

Volume 的的生命週期是與 container 分開的,代表當我們 container 停止後,我們的 Volume 是還能繼續運行的,我們可以來做個小實驗
這裡運行了一個 alpine container 並使用了令一個方法來掛載 Volume

docker run -dit -v fb13248a2219ac6aaeaf2d066f7f12cb5c44070640975ec445e9ab8718e4d807:/newvolume alpine 

進入到 container 內部後,也還是可以看到相同的檔案

docker attach 596f
/ # cd newvolume/
/newvolume # ls
hello

Summary

今天學習了怎麼掛載外部的資料夾以避免資料遺失的問題,這次使用了 Volume 基本上背後比較雜的問題都交給 Docker 處理了
而且很方便的是可以同時啟動許多個 container 掛載同一個 Volume,可以做到共享設定這類的功能