容器刪除掉後,裡邊的資料也會跟著刪除。資料的儲存和重複可用這是最基本的要求,也就是常說的資料持久化。在寫Dockerfile的時候可以用
VOLUME
命令,指定資料持久化
VOLUME
命令設定持久化
當知道了容器中的資料不能持久化後,可以在編寫Dockerfile
時用VOLUME
命令設定持久化的目錄。
dockerfile
FROM ubuntu:21.04
VOLUME ["/app"]
RUN apt-get update && \
apt-get install vim -y
然後構建映象 docker image build -t volume-test:1
[root@iZwz9257qzx65bg8c3p88gZ docker-test]# docker image ls -a
REPOSITORY TAG IMAGE ID CREATED SIZE
volume-test 1 0526a62af1d2 16 seconds ago 180MB
....
並使用該映象啟動一個容器,引數為以命令列模式進入該容器
docker container run -it -p 3999:3999 0526a62af1d2 sh
[root@iZwz9257qzx65bg8c3p88gZ docker-test]# docker container run -it -p 3999:3999 0526a62af1d2 sh
# ls
app bin boot dev etc home lib lib32 lib64 libx32 media mnt opt proc root run sbin srv sys tmp usr var
# echo hello > app/hello.txt
# cd app
# ls
hello.txt
# cat hello.txt
hello
# exit
[root@iZwz9257qzx65bg8c3p88gZ docker-test]#
上面的操作分別是
- 進入容器,可以看到根目錄下有
app
資料夾(通過VOLUME ["/app"]
指定的與宿主機共享資料的目錄) - 然後進入
app
目錄寫入了一個hello
到app
下的hello.txt
檔案,然後退出容器的命令列
然後我們需要驗證這個檔案是不是也同步到了我們的宿主機器上,這樣才能保證完成容器資料的持久化`
docker volume
相關命令
[root@iZwz9257qzx65bg8c3p88gZ _data]# docker volume
Usage: docker volume COMMAND
Manage volumes
Commands:
create Create a volume
inspect Display detailed information on one or more volumes
ls List volumes
prune Remove all unused local volumes
rm Remove one or more volumes
Run 'docker volume COMMAND --help' for more information on a command.
首先 ls
查詢所有的volume
[root@iZwz9257qzx65bg8c3p88gZ _data]# docker volume ls
DRIVER VOLUME NAME
local 0bdf00aab64d926f21a6f90342e391d84a4c6ec14b67fe249f8c96ac4e59d91b
local 0ea958861d42b680f60053c59c5384a44069d53e7229f47118ffd64399b46926
local 01b1566780ad5af79b7228f10741b14cc38246e784f3fa5669fe7888a94bfb09
local 3cea763fa6e484560cc489b2aa9f794d370f0f34809a0a4fdd2e513a9c474a74
local 5d599f822fd7cf3f217423af17d483f14deecde3f0adaab300b5c777b3e77636
local 5f61686f8e896c94fb4e1ad2f518e9fb4e4160be75c5358be430919f7a1f5130
local 6b3f0fc9738e3402273e21b605629e6d5dfbf34c37747df4818fa5cd2b1e6059
local 7ae7a3c826c0bdf9a3f893266fedb5c6356d7067cb54bef2ca8506194483b635
local 8ad42e37588d4bb6386f4c18e8c887ffd3a20d7ec4a4742947d01b6f7514331b
local 8b24b542f0d75f7073c47e555d155c7719cd5d65c09b5b03b2a3f87dab4ba513
local 98e980c61c1b6fac75f899303f959f9ff8f788fdb6094edba8349d2dd950ce34
local 824de8cf2066827829e7ff90efc66073607956d8ad6c33e9d3811f8ba2cbc3e0
local 9759e4fb808c4674d384785b6bc746122d0284cafb2c94623d900c7f3508931e
local 40334acb4196bae68de3232bacb4dad775cc63b9cb96f4d9940c99acc3a491ce
local c69dc1de5d77b32eae6ccb7654921bbd63a07c4cf39b7b86ed818e79b211d480
local d5c0e014d7499a3a08642700f8ca8208f2d32a2d06fded94a621a82ccbf3cfe5
local e38488f4bd0dc6f910bee270bd1e1bd5ac9816d6f2e581f9406e7feab444cc45
然後找到我們剛剛建立的那個(這裡我是一個一個找的…下面可以知道如何給volume
命名~)
[root@iZwz9257qzx65bg8c3p88gZ _data]# docker volume inspect 8ad42e37588d4bb6386f4c18e8c887ffd3a20d7ec4a4742947d01b6f7514331b
[
{
"CreatedAt": "2021-11-28T16:06:46+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/8ad42e37588d4bb6386f4c18e8c887ffd3a20d7ec4a4742947d01b6f7514331b/_data",
"Name": "8ad42e37588d4bb6386f4c18e8c887ffd3a20d7ec4a4742947d01b6f7514331b",
"Options": null,
"Scope": "local"
}
]
Mountpoint
對應的路徑就是宿主機持久化資料的路徑
[root@iZwz9257qzx65bg8c3p88gZ _data]# cd /var/lib/docker/volumes/8ad42e37588d4bb6386f4c18e8c887ffd3a20d7ec4a4742947d01b6f7514331b/_data
[root@iZwz9257qzx65bg8c3p88gZ _data]# ls
hello.txt
[root@iZwz9257qzx65bg8c3p88gZ _data]# cat hello.txt
hello
經過驗證發現資料的確從容器同步到了宿主機,完成了容器資料的持久化~
設定啟動容器volume
的名字
和上面不同的地方在於我們使用映象啟動容器的時候使用
-v
命令
docker container run -d -v VolumeName:DockerfileVOLUMEPath image
我們這裡的命令就變成了
docker container run -it -p 3999:3999 -v my-data:/app 0526a62af1d2 sh
[root@iZwz9257qzx65bg8c3p88gZ _data]# docker container run -it -p 3999:3999 -v my-data:/app 0526a62af1d2 sh
# ls
app bin boot dev etc home lib lib32 lib64 libx32 media mnt opt proc root run sbin srv sys tmp usr var
# cd app
# ls
# echo "hello my data" > hello.txt
# ls
hello.txt
# cat hello.txt
hello my data
# exit
重複檔案的操作
然後退出,來到宿主機,檢視宿主機docker
的volume
[root@iZwz9257qzx65bg8c3p88gZ _data]# docker volume ls
DRIVER VOLUME NAME
local 0bdf00aab64d926f21a6f90342e391d84a4c6ec14b67fe249f8c96ac4e59d91b
local 0ea958861d42b680f60053c59c5384a44069d53e7229f47118ffd64399b46926
local 01b1566780ad5af79b7228f10741b14cc38246e784f3fa5669fe7888a94bfb09
local 3cea763fa6e484560cc489b2aa9f794d370f0f34809a0a4fdd2e513a9c474a74
local 5d599f822fd7cf3f217423af17d483f14deecde3f0adaab300b5c777b3e77636
local 5f61686f8e896c94fb4e1ad2f518e9fb4e4160be75c5358be430919f7a1f5130
local 6b3f0fc9738e3402273e21b605629e6d5dfbf34c37747df4818fa5cd2b1e6059
local 7ae7a3c826c0bdf9a3f893266fedb5c6356d7067cb54bef2ca8506194483b635
local 8ad42e37588d4bb6386f4c18e8c887ffd3a20d7ec4a4742947d01b6f7514331b
local 8b24b542f0d75f7073c47e555d155c7719cd5d65c09b5b03b2a3f87dab4ba513
local 98e980c61c1b6fac75f899303f959f9ff8f788fdb6094edba8349d2dd950ce34
local 824de8cf2066827829e7ff90efc66073607956d8ad6c33e9d3811f8ba2cbc3e0
local 9759e4fb808c4674d384785b6bc746122d0284cafb2c94623d900c7f3508931e
local 40334acb4196bae68de3232bacb4dad775cc63b9cb96f4d9940c99acc3a491ce
local c69dc1de5d77b32eae6ccb7654921bbd63a07c4cf39b7b86ed818e79b211d480
local d5c0e014d7499a3a08642700f8ca8208f2d32a2d06fded94a621a82ccbf3cfe5
local e9b25fe9c662b3d06d2914878b3d1ec498532fa8bf936de61ec1b6076d0fa360
local e38488f4bd0dc6f910bee270bd1e1bd5ac9816d6f2e581f9406e7feab444cc45
local my-data
這個時候,你就可以發現其中一條volume
是我們自定義的名稱,檢視詳細的資訊也的確是我們剛剛生成的
[root@iZwz9257qzx65bg8c3p88gZ _data]# docker volume inspect my-data
[
{
"CreatedAt": "2021-11-28T16:24:42+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/my-data/_data",
"Name": "my-data",
"Options": null,
"Scope": "local"
}
]
驗證資料是否同步到了宿主機✅
[root@iZwz9257qzx65bg8c3p88gZ _data]# cd /var/lib/docker/volumes/my-data/_data
[root@iZwz9257qzx65bg8c3p88gZ _data]# ls
hello.txt
[root@iZwz9257qzx65bg8c3p88gZ _data]# cat hello.txt
hello my data
新容器使用宿主機的資料
已經會把容器(
container
)中的資料和檔案,儲存在作業系統上了。現在的需求是,再建立一個容器,新容器如何用我們之前用volume
儲存下來的的持久化資料?
現在我們本地已經有了之前的容器同步持久化下來的資料了,那麼如果我們重新起了一個容器,如果去使用這一塊資料呢~其實很簡單和指定volume
名稱的命令是一樣的
[root@iZwz9257qzx65bg8c3p88gZ docker-test]# docker container run -it -p 3002:3002 -v my-data:/app --name datafromlocal volume-test sh
# ls
app bin boot dev etc home lib lib32 lib64 libx32 media mnt opt proc root run sbin srv sys tmp usr var
# cd app
# ls
hello.txt
# cat hello.txt
hello my data
# exit
Bind Mount
實現資料持久化
資料持久化除了
Data Volume
外,還有一種叫做Bind Mount
,從中文翻譯來講,就是掛載繫結
。簡單講就是把容器中持久化的資料,繫結到本機的一個自定義位置
Data Volume
,在WIndows/Mac環境中很難使用,因為路徑是虛擬機器的路徑,不容易找到(mac都不太好找到的,下圖的問題還未有解決方法,mac下找不到~哈哈)
相較於Data Volume
來說 Bind Mount
設定更簡單,可以和開發環境更好的融合
[root@iZwz9257qzx65bg8c3p88gZ docker-test]# docker container run -it -p 3002:3002 -v ~/docker-test:/app --name datafromlocal volume-test sh
# ls
app bin boot dev etc home lib lib32 lib64 libx32 media mnt opt proc root run sbin srv sys tmp usr var
# cd app
# ls
dockerfile
# cat dockerfile
FROM ubuntu:21.04
VOLUME ["/app"]
RUN apt-get update && \
apt-get install vim -y
# ls
dockerfile
# exit
這種用法其實就是自定義了一個宿主機的目錄同容器內的某個目錄做繫結掛在,而不是像volume幫你管理在某個規定好的位置
[root@iZwz9257qzx65bg8c3p88gZ docker-test]# ls
dockerfile
[root@iZwz9257qzx65bg8c3p88gZ docker-test]# docker container run -it -p 3002:3002 -v ~/docker-test:/app --name datafromlocal volume-test sh
# cd app
# ls
dockerfile
# vim newFile.txt
# exit
[root@iZwz9257qzx65bg8c3p88gZ docker-test]# ls
dockerfile newFile.txt
完成了宿主機和容器的資料共享持久化!
- 容器內建立了一個
newFile.txt
- 退出容器回到宿主機通過
ls
命令,發現已經從容器中同步過來,完成了容器資料的持久化
本作品採用《CC 協議》,轉載必須註明作者和本文連結