默認情況下,在容器內創建的所有文件都存儲在可寫容器層中。這意味着:
- 當該容器不再存在時,數據不會持久存在,並且如果另一個進程需要,則可能很難從容器中獲取數據。
- 容器的可寫層緊密耦合到運行容器的主機。您無法輕松地將數據移動到其他位置。
- 寫入容器的可寫層需要 存儲驅動程序來管理文件系統。存儲驅動程序使用Linux內核提供聯合文件系統。與使用直接寫入主機文件系統的數據卷相比,這種額外的抽象降低了性能 。
Docker有三種方式可以在宿主機中持久化存儲文件:
-
卷存儲(Volume)在由Docker(
/var/lib/docker/volumes/
在Linux上)管理的主機文件系統的一部分中。非Docker進程不應修改文件系統的這一部分。卷是在Docker中保留數據的最佳方式。 -
綁定掛載(bind mount)可以存儲在主機系統的任何位置。它們甚至可能是重要的系統文件或目錄。Docker主機或Docker容器上的非Docker進程可以隨時修改它們。
-
tmpfs mount
僅存儲在主機系統的內存中,永遠不會寫入主機系統的文件系統。
使用數據卷
1. 創建卷
docker volume create my-vol
2. 查看卷
docker volume list
3. 查看卷的詳細信息
docker inspect my-vol [ { "CreatedAt": "2019-03-14T17:10:04+08:00", "Driver": "local", "Labels": {}, "Mountpoint": "/var/lib/docker/volumes/my-vol/_data", "Name": "my-vol", "Options": {}, "Scope": "local" } ]
4. 刪除卷
docker volume rm my-vol
5. 啟動一個含有卷的容器
如果卷myvol2不存在,則會自動創建,並且掛載在容器的/app目錄下
$ docker run -d \ --name devtest \ --mount source=myvol2,target=/app \ nginx:latest
也可以簡寫成
$ docker run -d \ --name devtest \ -v myvol2:/app \ nginx:latest
刪除容器中含的卷
$ docker container stop devtest $ docker container rm devtest $ docker volume rm myvol2
6. 啟動一個包含卷的服務
$ docker service create -d \ --replicas=4 \ --name devtest-service \ --mount source=myvol2,target=/app \ nginx:latest
7. 創建一個只讀卷
$ docker run -d \ --name=nginxtest \ -v nginx-vol:/usr/share/nginx/html:ro \ nginx:latest
8. 在遠程機器上創建卷,並掛載
在Docker主機上,安裝vieux/sshfs
插件:
$ docker plugin install --grant-all-permissions vieux/sshfs
使用驅動程序創建卷
docker volume create --driver vieux/sshfs \ -o sshcmd=root@192.168.0.10:/tmp/test \ -o password=mypassword \ sshvolume
在容器中掛載卷
$ docker run -d \ --name sshfs-container \ --volume-driver vieux/sshfs \ --mount src=sshvolume,target=/app,volume-opt=sshcmd=root@192.168.0.10:/tmp/test,volume-opt=password=mypassword \
nginx:latest
備份,遷移,恢復數據卷
備份
1. 創建一個名為dbvolume的數據卷並掛載在名為dbstore容器的/dbdate目錄下。
docker run -d --name dbstore -v dbvolume:/dbdata alpine sh
2. 在dbvolume卷中寫入數據
[root@node2 ~]# docker exec -it dbstore sh / # echo hello > /dbdata/test.txt / # exit
3. 備份容器中的數據卷
[root@node2 ~]# docker run --rm --volumes-from dbstore -v $(pwd):/backup alpine tar cvf /backup/backup.tar /dbdata tar: removing leading '/' from member names dbdata/ dbdata/test.txt
--volumes-from 掛載dbstore容器中的數據卷到新建的容器中,注意掛載的目錄和容器dbstore位置相同,都為/dbdata
-v $(pwd):/backup 將宿主機的當前目錄掛載到新建容器的/backup目錄下
tar cvf /backup/backup.tar /dbdata 在新建的容器中將目錄/dbdata打包到/backup目錄下,因為backup目錄映射為宿主機的當前目錄,所以本地目錄生成備份。
恢復
1. 創建一個新容器dbstore2,並掛載一個名為volume_restore的卷
docker run -v volume_restore:/dbdata --name dbstore2 alpine sh
2.從容器dbstore2中掛載卷
docker run --rm --volumes-from dbstore2 -v $(pwd):/backup alpine sh -c "cd /dbdata && tar xvf /backup/backup.tar --strip 1"
數據卷容器
如果容器之間需要共享一些持續更新的數據,最簡單的方式就是是用戶數據卷容器,數據卷容器就是一種普通容器,專門提供數據卷供其它容器掛載使用。
創建數據卷容器dbdata
[root@wls12c /]$ docker run -it -v dbdata:/dbdata --name dbdata centos
[root@07e4ad5587e1 /]
創建db1和db2兩個容器,並使用--volumes-from掛載dbdata容器中的數據卷
[root@wls12c /]$ docker run -it --volumes-from dbdata --name db1 centos
[root@wls12c /]$ docker run -it --volumes-from dbdata --name db2 centos
這樣三個容器任何一個容器在該目錄下寫入,其它容器都能看見。
創建自動刪除匿名卷的容器
掛載在/foo目錄下的匿名卷將會被自動刪除,awesome卻不會
docker run --rm -v /foo -v awesome:/bar busybox top
刪除所有未被使用的卷
docker volume prune
使用綁定數據卷(bind mount)
使用-v可以掛載一個本地的目錄到容器中作為數據卷。如果將bind-mount綁定到容器上的非空目錄中,則會隱藏目錄的現有內容。
下面將宿主機的當前目錄下的target目錄掛載到容器的/app目錄下
docker run -d \ -it \ --name devtest \ -v "$(pwd)"/target:/app \ nginx:latest
也可以使用--mount參數掛載
-v $ docker run -d \ -it \ --name devtest \ --mount type=bind,source="$(pwd)"/target,target=/app \ nginx:latest