Docker基礎(3) 數據卷

  • 創建數據卷
  • 掛載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》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章