Dockerfile VOLUME
在此篇文章中: Docker Certified Associate(DCA)認證考試學習-Docker可讀寫層
我們知道 Docker 在建立 container 的時候會在 image layer 上再多加一層可讀寫層
但是有一個問題是此如果將 container 刪除,那麼在我們剛剛在可讀寫層所作的變更會一起被刪除掉
所以像是讀寫資料庫這種需求,如果資料沒辦法持久保存那顯然是會造成很大的問題
這時最簡易的作法可以在 Dockerfile 之內使用 VOLUME 指令
首先先看看Volume文檔,Docker提供了兩種資料持久化的方法 Volumes
、 Bind mounts
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,可以做到共享設定這類的功能