VOLUME 定義匿名卷
格式為:
-
VOLUME ["<路徑1>", "<路徑2>"...]
-
VOLUME <路徑>
之前我們說過,容器運作時應該盡量保持容器存儲層不發生寫操作,對于資料庫類需要儲存動态資料的應用,其資料庫檔案應該儲存于卷(volume)中,後面的章節我們會進一步介紹 Docker 卷的概念。
為了防止運作時使用者忘記将動态檔案所儲存目錄挂載為卷,在
Dockerfile
中,我們可以事先指定某些目錄挂載為匿名卷,這樣在運作時如果使用者不指定挂載,其應用也可以正常運作,不會向容器存儲層寫入大量資料。
VOLUME /data
這裡的
/data
目錄就會在運作時自動挂載為匿名卷,任何向
/data
中寫入的資訊都不會記錄進容器存儲層,進而保證了容器存儲層的無狀态化。當然,運作時可以覆寫這個挂載設定。
比如:
docker run -d -v mydata:/data xxxx
在這行指令中,就使用了
mydata
這個命名卷挂載到了
/data
這個位置,替代了
Dockerfile
中定義的匿名卷的挂載配置。
Docker 資料管理
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsISPrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdsATOfd3bkFGazxCMx8VesATMfhHLlN3XnxCMwEzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsYTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cmbw5iZkZmYykTZ1YjM5MzM2QmNzEzYiFmM3EzYwUWOhFjN48CX1AzLchDMxIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjL0M3Lc9CX6MHc0RHaiojIsJye.png)
這一章介紹如何在 Docker 内部以及容器之間管理資料,在容器中管理資料主要有兩種方式:
- 資料卷(Volumes)
- 挂載主機目錄 (Bind mounts)
資料卷
資料卷
是一個可供一個或多個容器使用的特殊目錄,它繞過 UFS,可以提供很多有用的特性:
-
可以在容器之間共享和重用資料卷
- 對
的修改會立馬生效資料卷
-
的更新,不會影響鏡像資料卷
-
預設會一直存在,即使容器被删除資料卷
注意: 的使用,類似于 Linux 下對目錄或檔案進行 mount,鏡像中的被指定為挂載點的目錄中的檔案會隐藏掉,能顯示看的是挂載的
資料卷
。
資料卷
建立一個資料卷
$ docker volume create my-vol
檢視所有的
資料卷
$ docker volume ls
local my-vol
在主機裡使用以下指令可以檢視指定
資料卷
的資訊
$ docker volume inspect my-vol
[
{
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/my-vol/_data",
"Name": "my-vol",
"Options": {},
"Scope": "local"
}
]
啟動一個挂載資料卷的容器
在用
docker run
指令的時候,使用
--mount
标記來将
資料卷
挂載到容器裡。
在一次
docker run
中可以挂載多個
資料卷
下面建立一個名為
web
的容器,并加載一個
資料卷
到容器的
/webapp
目錄。
$ docker run -d -P \
--name web \
# -v my-vol:/wepapp \
--mount source=my-vol,target=/webapp \
training/webapp \
python app.py
檢視資料卷的具體資訊
在主機裡使用以下指令可以檢視
web
容器的資訊
$ docker inspect web
資料卷
資訊在 "Mounts" Key 下面
"Mounts": [
{
"Type": "volume",
"Name": "my-vol",
"Source": "/var/lib/docker/volumes/my-vol/_data",
"Destination": "/app",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
删除資料卷
$ docker volume rm my-vol
資料卷
是被設計用來持久化資料的,它的生命周期獨立于容器,Docker 不會在容器被删除後自動删除
資料卷
,并且也不存在垃圾回收這樣的機制來處理沒有任何容器引用的
資料卷
如果需要在删除容器的同時移除資料卷。可以在删除容器的時候使用
docker rm -v
這個指令。
無主的資料卷可能會占據很多空間,要清理請使用以下指令
$ docker volume prune
挂載一個主機目錄作為資料卷
使用
--mount
标記可以指定挂載一個本地主機的目錄到容器中去。
$ docker run -d -P \
--name web \
# -v /src/webapp:/opt/webapp \
--mount type=bind,source=/src/webapp,target=/opt/webapp \
training/webapp \
python app.py
上面的指令加載主機的
/src/webapp
目錄到容器的
/opt/webapp
目錄。
這個功能在進行測試的時候十分友善,比如使用者可以放置一些程式到本地目錄中,來檢視容器是否正常工作。本地目錄的路徑必須是絕對路徑,以前使用
-v
參數時如果本地目錄不存在 Docker 會自動為你建立一個檔案夾,現在使用
--mount
參數時如果本地目錄不存在,Docker 會報錯。
Docker 挂載主機目錄的預設權限是
讀寫
,使用者也可以通過增加
readonly
指定為
隻讀
$ docker run -d -P \
--name web \
# -v /src/webapp:/opt/webapp:ro \
--mount type=bind,source=/src/webapp,target=/opt/webapp,readonly \
training/webapp \
python app.py
加了
readonly
之後,就挂載為
隻讀
了。如果你在容器内
/opt/webapp
目錄建立檔案,會顯示如下錯誤
/opt/webapp # touch new.txt
touch: new.txt: Read-only file system
web
$ docker inspect web
挂載主機目錄
的配置資訊在 "Mounts" Key 下面
"Mounts": [
{
"Type": "bind",
"Source": "/src/webapp",
"Destination": "/opt/webapp",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],
挂載一個本地主機檔案作為資料卷
--mount
标記也可以從主機挂載單個檔案到容器中
$ docker run --rm -it \
# -v $HOME/.bash_history:/root/.bash_history \
--mount type=bind,source=$HOME/.bash_history,target=/root/.bash_history \
ubuntu:18.04 \
bash
root@2affd44b4667:/# history
1 ls
2 diskutil list
這樣就可以記錄在容器輸入過的指令了。