- 創建數據卷
- 掛載Host目錄作爲數據卷
- 掛載Host的文件作爲數據卷
- 數據卷容器
- 數據卷的備份和恢復
Docker容器一旦被刪除,容器本身對應的rootfs文件系統就會被刪除,容器中的所有數據也將隨之消失。
Docker提供了數據卷的方式來持久化容器產生的數據,通過數據卷,還可以在容器之間共享數據。
創建容器時,通過-v參數可以數據卷,-v參數的格式爲
[host-dir]:[container-dir]:[rw|ro]
其中
- host-dir表示Host機器上的目錄或文件,如果目錄不存在Docker會自動在Host上創建
- container-dir表示容器內部與host-dir對應的目錄或文件,如果不存在Docker同樣會自動創建
- rw|ro用於控制數據卷的讀寫權限,默認rw(可讀寫)
創建數據卷
如果不指定host-dir,Docker也會在容器內部創建目錄
$ docker run -it --rm -v /volume1 --name testbox busybox
在另一個終端執行inspect命令可以看到這種方式下,Docker會在Host的/var/lib/docker/volumes/目錄生成一個隨機的目錄來掛載/volume1。
$ docker inspect -f {{.Mounts}} busybox
"Mounts": [
{
"Type": "volume",
"Name": "112e8ff579fcda26cd933ea37946bf7a9b53b0f2bf87382184731884990e2746",
"Source": "/var/lib/docker/volumes/112e8ff579fcda26cd933ea37946bf7a9b53b0f2bf87382184731884990e2746/_data",
"Destination": "/volume1",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
掛載Host目錄作爲數據卷
也可以掛載Host目錄作爲容器的數據卷
docker run -it --rm -v /home/dotnet2/:/volume1 --name testbox busybox
這時會將host的/home/dotnet2/目錄掛載,對應容器的/volume1目錄,在目錄下執行ls可以看到同樣的內容。而且在不管在Host還是容器內修改這個目錄中的內容,兩邊都可以生效。
在Host修改
$ echo "hello v124"> testzzx.txt
在容器查看
# cat testzzx.txt
# hello v124
掛載時通過ro變量,還可以設置目錄爲只讀
docker run -it --rm -v /home/dotnet2/:/volume1:ro --name testbox busybox
此時如果在容器內嘗試修改這個目錄中的內容會失敗,但在Host還是可以修改的。
# echo "hello v125"> testzzx.txt
sh: can't create testzzx.txt: Read-only file system
掛載Host的文件作爲數據卷
docker run -it --rm -v /home/dotnet2/testzzx.txt:/volume1 --name testbox busybox
此時容器內的volume1實際上是文件,內容與testzzx.txt一樣。而如果這樣
docker run -it --rm -v /home/dotnet2/testzzx.txt:/volume1/testzzx.txt --name testbox busybox
Docker纔會在容器內部創建volume1目錄並在這個目錄下掛載testzzx.txt。
同掛載目錄一樣,也可以設置只讀
docker run -it --rm -v /home/dotnet2/testzzx.txt:/volume1/testzzx.txt:ro --name testbox busybox
這種掛載Host文件的方式可用來在Host與容器之間共享配置文件,這樣只需在Host修改配置,所有掛載的容器都會生效。
數據卷容器
數據卷容器提供了一種在容器間共享數據的更強大的方式。
首先創建一個命名的數據卷容器供其他容器掛載。
$ docker run -it --rm -v /volume1 --name testbox busybox
掛載容器使用–volumes-from參數
$ docker run -it --rm --volumes-from testbox --name testboxvf1 busybox
這個容器啓動後也可以看到volume1目錄,而且在數據卷容器的volume1進行的操作在testboxvf1容器可以即時生效。
可以同時使用多個–volumes-from參數,從多個容器掛載多個數據卷。
此外還可以從其他已經掛載容器卷的容器(如testboxvf1)掛載數據卷:
$ docker run -it --rm --volumes-from testboxvf1 --name testboxvf2 busybox
在容器testboxvf2內部也出現了volume1目錄,如果之前在數據卷容器或者testboxvf1新建了文件,在這裏可以讀取、修改
如果刪除掛載了數據卷的容器(包括初始的testbox容器和其他的容器testboxvf1、testboxvf2),數據卷並不會被刪除。如果想刪除該數據卷,需要在刪除最後一個引用該數據卷的時候調用docker rm -v顯式刪除數據卷。
數據卷的備份和恢復
除了Docker容器數據的持久化,在使用數據卷容器時,還會面對數據的備份和恢復的問題。
備份
備份數據卷可以通過這樣的方式:
$ docker run --volumes-from testbox -v $(pwd):/backup --name testboxbak busybox tar cvf /backup/backup.tar /volume1
這條命令會掛載數據卷容器,並將Host當前目錄掛載爲容器的backup目錄,然後使用tar命令將數據卷容器的volume1目錄壓縮放置到backup目錄下,這樣回到Host後,就可以在當前目錄拿到backup.tar了。
恢復
恢復時可以直接恢復到原有容器或者其他任何容器。假設想把backup.tar的數據恢復到一個新的數據卷容器testbox2,首先啓動testbox2:
$ docker run -it --rm -v /volume1 --name testbox2 busybox
然後開始恢復,下面這條命令會掛載數據卷容器,並將Host當前目錄掛載爲容器的volume2目錄,因爲backup.tar在Host的當前目錄,所以在容器中執行解壓操作時的路徑爲/volume2/backup.tar,這樣就把解壓後的volume1目錄放在了在容器的根目錄,volume1也是數據卷容器的共享目錄,於是恢復完成。
$ docker run -it --rm --volumes-from testbox2 -v $(pwd):/volume2 --name testboxbak1 busybox tar xvf /volume2/backup.tar
參考資料
李金榜 尹燁 劉天斯 陳純 著 《循序漸進學Docker》