1. Docker數據卷
- Docker中的容器一旦刪除,容器本身對應的rootfs文件系統就會被刪除,容器中的所有數據也將隨之刪除。爲此,Docker提供了數據卷(data volume),數據卷除了可以持久化數據,還可以用於容器間共享數據。
- 數據卷是一個可供一個或多個容器使用的特殊目錄,它繞過聯合文件系統,被設計用來保存數據,而不管容器的生命週期。
- 數據卷可以在容器之間共享和重用。
- 當你刪除一個容器時,Docker不會自動地刪除一個數據卷。卷會一直存在,直到沒有容器使用。
Docker有兩個容器選項可以在主機中存儲文件,爲綁定掛載和docker管理卷,使用-v選項來創建或掛載一個數據卷並掛載到容器裏。
綁定掛載 | docker管理卷 | |
volume位置 | 可任意指定 |
在/var/lib/docker/volume/...下 |
對已有mount point影響 | 隱藏並替換爲volume | 原有數據複製到volume |
是否支持單個文件 | 支持 | 不支持,只能是目錄 |
權限控制 | 可設置爲只讀,默認讀寫權限 | 無控制,均爲讀寫權限 |
移植性 | 移植性若,與主機路徑綁定 | 移植性強,無需指定主機目錄 |
1.1 bind mount(綁定掛載)
- 綁定掛載是將主機上的目錄或文件掛載到容器裏。
- -v選項指定的路徑如果不存在,掛載時會自動創建。
- 格式:-v=[host-dir]:[container-dir]:[rw|ro]。
- host-dir:表示宿主機上的目錄,如果不存在,Docker會自動在宿主機上創建該目錄。
- container-dir:表示容器內部對應的目錄,如果該目錄不存在,Docker也會在容器內部創建該目錄。
- rw|ro:用於控制卷的讀寫權限。
可以掛載主機的目錄到容器,作爲容器的數據卷。
將主機上的/data目錄掛載到容器中的/volume1。通過這種方式我們可以在主機與容器間進行數據交換。即使容器被刪除,數據仍然會保存在主機上。實際上,Docker內部是通過mount --bind來實現的。
ycy@ubuntu18:~$ docker run -it --rm -v /data:/volume1 ubuntu
root@e1f6b98857fa:/# df -lh | grep volume1
/dev/sda1 49G 8.9G 38G 20% /volume1
root@e1f6b98857fa:/# ls /volume1/
index.html
root@e1f6b98857fa:/# echo 12345 > /volume1/a.txt
root@e1f6b98857fa:/# exit
exit
ycy@ubuntu18:~$ ls /data/
a.txt index.html
ycy@ubuntu18:~$ cat /data/a.txt
12345
也可以掛載主機上的文件作爲容器的數據卷。主要用於在主機與容器之間共享配置文件。一般來說,應用程序不會變,而配置文件可能會經常變化,如果對每個配置文件都做成一個鏡像,會造成鏡像版本過多、管理不便、而且不夠靈活。實際上,我們可以將配置文件放在主機上,然後掛載到容器,這樣,就可以隨時更改主機文件,容器內部看到的文件也會隨之改變。
將主機上的/etc/hosts文件掛載到容器中的/etc/hosts下。
ycy@ubuntu18:~$ docker run -it --rm -v /etc/hosts:/etc/hosts ubuntu
root@c1455429f23a:/# cat /etc/hosts
127.0.0.1 localhost
127.0.1.1 ubuntu18
root@c1455429f23a:/# echo "192.168.146.100 www.a.com" >> /etc/hosts
root@c1455429f23a:/# ycy@ubuntu18:~$
ycy@ubuntu18:~$ cat /etc/hosts
127.0.0.1 localhost
127.0.1.1 ubuntu18
192.168.146.100 www.a.com
1.2 docker managed volume(docker管理卷)
- docker管理卷不需要指定mount源,docker自動爲容器創建數據卷目錄
- 默認創建的數據卷目錄都在/var/lib/docker/volumes中。
- 如果掛載時指向容器內已有的目錄,原有數據會被複制到volume中。
ycy@ubuntu18:~$ docker run -d --name s2 -v /volumes2 ubuntu
62a3530355cf0d3f7b5e5ffd025935d8e4d259db50929602b6cf5e274ab32432
ycy@ubuntu18:~$ docker inspect -f "{{ .Mounts }}" s2
[{volume 3e2cd447ec602fe271aedd4b266345f8c049279d66ecaa718b9f22509d505b05 /var/lib/docker/volumes/3e2cd447ec602fe271aedd4b266345f8c049279d66ecaa718b9f22509d505b05/_data /volumes2 local true }]
上面默認的文件名是以數據卷名命名的,可以自定義設置,如下。
ycy@ubuntu18:~$ docker run -d --name s3 -v s3:/volumes3 ubuntu
05591a7326637839aef35603915ee5f147f0ed4eb883701e5c418c6588940425
ycy@ubuntu18:~$ docker inspect -f "{{ .Mounts }}" s3
[{volume s3 /var/lib/docker/volumes/s3/_data /volumes3 local z true }]
2. 數據卷容器
數據卷容器,是專門爲其他容器提供數據卷的容器。
創建一個命名的數據卷容器,供其他容器掛載。
ycy@ubuntu18:~$ docker run -d --name dbdata -v /dbdata ubuntu
e050b4a151c474348d35c923454352393327f386f3f86bd7f1c3b6fb86529976
使用docker inspect inspect命令驗證創建卷並安裝正確,尋找Mounts部分。
ycy@ubuntu18:~$ docker inspect -f "{{ .Mounts }}" dbdata
[{volume 4f5b5fb57ff9b662b16c748fbeb92ccb2174cd5dfa247c6b99a53be6f1aa48ee /var/lib/docker/volumes/4f5b5fb57ff9b662b16c748fbeb92ccb2174cd5dfa247c6b99a53be6f1aa48ee/_data /dbdata local true }]
在其他容器中使用--volumes-from來掛載指定容器中的數據卷。這樣,db1和db2也可以看到/dbdata數據卷的內容。
ycy@ubuntu18:~$ docker run -d --name db1 --volumes-from dbdata ubuntu
7e7697abd99adfef4039f5b7b8250b0975da884f368759271a273801921871a6
ycy@ubuntu18:~$ docker run -d --name db2 --volumes-from dbdata ubuntu
d9eccd03f32dd9c4c9e4c555fb0e08629a745bc1d9db45cae7635368ca2c29f1
還可以同時使用多個--volumes-from參數,從多個容器掛載多個數據卷。也可以從其他已經掛載數據卷容器的容器(如db1/db2)掛載數據卷。
ycy@ubuntu18:~$ docker run -d --name db3 --volumes-from db1 ubuntu
5d9cad23e45c1330def992a5fa9b34bad7ac95cafced6679649774ae8b95811c
如果刪除掛載了數據卷的容器(包括初始的databa容器和其他的db1/db2/db3容器),數據卷並不會被刪除。如果想刪除數據卷,必須在最後一個引用該數據卷的時候調用docker volume rm命令來刪除數據卷,docker volume prune刪除所有數據卷。
ycy@ubuntu18:~$ docker rm -f $(docker ps -a -q)
5d9cad23e45c
d9eccd03f32d
7e7697abd99a
e050b4a151c4
root@ubuntu18:~# ls /var/lib/docker/volumes/
4f5b5fb57ff9b662b16c748fbeb92ccb2174cd5dfa247c6b99a53be6f1aa48ee
metadata.db
s3
ycy@ubuntu18:~$ docker volume rm 4f5b5fb57ff9b662b16c748fbeb92ccb2174cd5dfa247c6b99a53be6f1aa48ee
4f5b5fb57ff9b662b16c748fbeb92ccb2174cd5dfa247c6b99a53be6f1aa48ee
3. 備份、恢復和遷移數據卷
3.1 備份數據卷
通過--volumes-from參數掛載數據卷,然後備份數據卷中的數據。
創建一個新的容器,將主機本地目錄掛載的/backup,然後將數據卷容器dbdata的數據卷(/dbdata)打包到/backup/backup.tar。然後再主機的當前目錄下就可以得到backup.tar。
ycy@ubuntu18:~$ docker run -d --name dbdata -v /dbdata ubuntu
f91c84972927905701d16110fa97d2f31cd273ce30219da93342573c1e1d07f1
ycy@ubuntu18:~$ docker run --volumes-from dbdata -v $(pwd):/backup ubuntu tar -cvf /backup/backup.tar /dbdata
/dbdata/
tar: Removing leading `/' from member names
ycy@ubuntu18:~$ ll -h backup.tar
-rw-r--r-- 1 root root 10K 9月 5 16:11 backup.tar
3.2 恢復數據卷
可以將備份的數據恢復到原有容器或者其他任何容器。比如將backup.tar的數據恢復到一個新的容器dbdata2.
ycy@ubuntu18:~$ docker run -v /dbdata --name dbdata2 ubuntu
然後創建另一個容器,掛載dbdata2的容器,並使用tar解壓備份文件到掛載的容器卷中。
ycy@ubuntu18:~$ docker run --volumes-from dbdata2 -v $(pwd):/backup ubuntu tar -xvf /backup/backup.tar
dbdata/