数据卷
讲起docker,数据的持久化一直是需要我们关注的问题,数据卷是一个可供一个或多个容器使用的特殊目录,它绕过UFS,它提供了很多有用的特性:
- 数据卷可以在容器之间共享和重用
- 对数据卷的修改立马生效
- 对数据卷的更新,不会影响镜像
- 数据卷默认会一直存在,即使容器被删除 注意:数据卷的使用,类似于Linux下对目录或文件进行mount,镜像中的被指定为挂载点的目录中的文件会掩藏掉,能显示的是挂载的数据卷。
创建数据卷
在用docker run命令的时候,使用-v标记来创建一个数据卷并挂载到容器中,在一次run中可以挂载多个数据卷。
1 | docker run -d --name nginx -v /wwwroot nginx:latest |
该命令为指定容器中的/wwwroot创建匿名数据卷,我们可以在/var/lib/docker/volumes中看见我们挂载的匿名卷的数据。
可以通过docker inspect来查看相关的数据:
1 | ~]# docker inspect 0ee6c6eb7d3e |
2 | ... |
3 | "Mounts": [ |
4 | { |
5 | "Name": "2cbd85381f632c267c4f482ae46ca6694700f78e0c316959ac847f118e3f896f", |
6 | "Source": "/var/lib/docker/volumes/2cbd85381f632c267c4f482ae46ca6694700f78e0c316959ac847f118e3f896f/_data", |
7 | "Destination": "/wwwroot", |
8 | "Driver": "local", |
9 | "Mode": "", |
10 | "RW": true, |
11 | "Propagation": "" |
12 | } |
13 | |
14 | ... |
注意:如果我们在Dockerfile中使用了VOLUME指令匿名卷,默认为指定目录创建匿名卷,我们可以使用-v覆盖掉这个指定目录。
1 | docker run -d --name nginx -v /wwwroot:/wwwroot nginx:latest |
这样的指定宿主机的目录挂载至容器指定目录,这个指定的宿主机目录会覆盖掉容器中的目录,即原本容器构建过程生成文件将会被宿主机的指定目录覆盖。
我们在docker inspect中可见我们挂载的目录是可读写的,在这个挂载的过程中我们可以设置权限。
1 | docker run -d --name nginx -v /wwwroot:/wwwroot:ro nginx:latest |
这样我们就把挂载上的目录改成了只读。
删除数据卷
数据卷的出现就是为了解决数据持久化,它的生命周期独立于容器运行,但是如果我们在容器删除的时候,所持有的数据卷也无用的情况下,我们可以使用一下命令来删除容器和数据卷:
1 | docker rm -v nginx |
注意:-v指令需慎重,此过程不可逆。
数据卷容器
如果有一些持续更新的数据需要在容器间共享,做好创建数据卷容器卷,数据卷首先是一个容器,专门用来提供数据卷其他容器挂载使用。
首先创建一个名为data的数据卷容器:
1 | docker run -itd -v /data:/data --name data -h data centos:latest /bin/bash |
然后在其他容器中使用–volumes-from来挂载data容器的数据卷。
1 | docker run -itd --volumes-from data --name db1 -h db1 centos:latest /bin/bash |
2 | docker run -itd --volumes-from data --name db2 -h db2 centos:latest /bin/bash |
我们看下docker inspect的数据卷信息:
1 | ~]# docker inspect data |
2 | ... |
3 | "Mounts": [ |
4 | { |
5 | "Source": "/data", |
6 | "Destination": "/data", |
7 | "Mode": "", |
8 | "RW": true, |
9 | "Propagation": "rprivate" |
10 | } |
11 | ], |
12 | ... |
13 | |
14 | ~]# docker inspect db1 |
15 | ... |
16 | "Mounts": [ |
17 | { |
18 | "Source": "/data", |
19 | "Destination": "/data", |
20 | "Mode": "", |
21 | "RW": true, |
22 | "Propagation": "rprivate" |
23 | } |
24 | ], |
25 | ... |
26 | |
27 | ~]# docker inspect db2 |
28 | ... |
29 | |
30 | "Mounts": [ |
31 | { |
32 | "Source": "/data", |
33 | "Destination": "/data", |
34 | "Mode": "", |
35 | "RW": true, |
36 | "Propagation": "rprivate" |
37 | } |
38 | ], |
39 | ... |
我们可以看到数据卷的信息,都是相同的挂载信息,所以我们只要在数据卷中修改内容,所有的容器内容都会更改。
当然我们这样的数据卷也是可以构建级联挂载数据卷。
1 | docker run -itd --volumes-from db1 --name db3 -h db3 centos:latest /bin/bash |
注意:使用 –volumes-from 参数所挂载数据卷的容器自己并不需要保持在运行状态。
就算删除全部的挂载数据卷的容器,该数据卷也不会被删除。
利用数据卷容器来备份、恢复、迁移数据卷
备份
1 | docker run --volumes-from data -v /backup:/backup centos tar -czvf /backup/backup.tar.gz /data |
通过挂载数据/backup卷的方式,备份/data的数据。
恢复
1 | docker run --volumes-from data -v /backup:/backup centos tar -xzvf /backup/backup.tar.gz -C /data |