1、什么是数据卷
容器是基于镜像创建的,进入容器之后的,如果有文件和数据写入,都会保存在容器内。一旦容器删除,数据和文件都将不会存在。除非我们把这些数据事先拷贝下来或者基于当前容器制作新的镜像。那么如何持久化保存数据呢?
如果需要在宿主机频繁修改文件内容,并且再通过 docker cp 命令复制到容器内,也是很不方便;
如果多个容器需要共享数据文件,一个个复制到对应的容器内,也是很不方便。
如果容器被误删,文件数据被误删,也需要有容灾的方案。
所以数据卷是一个很好的选择,数据卷存在在宿主机上,然后挂载到各个容器,即使容器销毁,数据卷还是存在于宿主机器上。同一个数据卷可共享挂载到多个容器上。
查看数据卷
[root@ centos]# docker volume --help
Usage: docker volume COMMAND
Manage volumes
Commands:
create Create a volume
inspect Display detailed information on one or more volumes
ls List volumes
prune Remove all unused local volumes
rm Remove one or more volumes
Run 'docker volume COMMAND --help' for more information on a command.
# 列出当前机器上的所有数据卷
[root@ centos]# docker volume ls
DRIVER VOLUME NAME
local 7319fd1f7df530f90925fea0b81308f03829e4b297390018e5b3b29aadd4ba51
local d2ec25d98838db66c333856a83dffba9e0d78b8f4da979432c9e8cc93f05f4c9
# 审查数据卷相关信息
[root@ centos]# docker volume inspect 7319fd1f7df530f90925fea0b81308f03829e4b297390018e5b3b29aadd4ba51
[
{
"CreatedAt": "2020-12-04T10:40:47+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/7319fd1f7df530f90925fea0b81308f03829e4b297390018e5b3b29aadd4ba51/_data",
"Name": "7319fd1f7df530f90925fea0b81308f03829e4b297390018e5b3b29aadd4ba51",
"Options": null,
"Scope": "local"
}
]
2、挂载点
[root@ centos]# docker run -itd -v /docker/volumes/centos/project:/home/project centos /bin/bash
# docker run -v 宿主机目录:容器内目录
其中的 -v 标记,在容器中设置了一个挂载点 /home/project(就是容器中的一个目录),并将主机上的 /docker/volumes/centos/project 目录中的内容关联到 /home/project下。
这样在容器中对 /home/project目录下的操作,还是在主机上对/docker/volumes/centos/project的操作,都是完全实时同步的,因为这两个目录实际都是指向主机目录。
假设没有绑定宿主机
[root@ centos]# docker run -itd --name centos-test -v /home/project centos /bin/bash
[root@ centos]# docker inspect centos-test | grep "Mounts" -A8
"Mounts": [
{
"Type": "volume",
"Name": "81571578dfd46b845752a476d2ea974a3c6f65530de0c12a09677d80c115464e",
"Source": "/var/lib/docker/volumes/81571578dfd46b845752a476d2ea974a3c6f65530de0c12a09677d80c115464e/_data",
"Destination": "/home/project",
"Driver": "local",
"Mode": "",
"RW": true,
上面-v的标记只设置了容器的挂载点,并没有指定关联的主机目录。这时docker会自动绑定主机上的一个目录;
上面 Mounts下的每条信息记录了容器上一个挂载点的信息,Destination 值是容器的挂载点,Source值是对应的主机目录。
可以看出这种方式对应的主机目录是自动创建的,其目的不是让在主机上修改,而是让多个容器共享。
进入主机目录,新增文件,并测试容器内是否同步
[root@ centos]# cd /var/lib/docker/volumes/81571578dfd46b845752a476d2ea974a3c6f65530de0c12a09677d80c115464e/_data
[root@ _data]# ll
总用量 0
[root@ _data]# echo "test" > test.txt
[root@ _data]# ll
总用量 4
-rw-r--r-- 1 root root 5 12月 15 15:34 test.txt
# 进入容器
[root@ centos]# docker exec -it centos-test /bin/bash
[root@0d8c9d2904d8 /]# ls /home/project/
test.txt
由此看出同步依然正常。
3、Dockfile创建共享数据卷
基于ubuntu镜像创建。
Dockerfile
# volume container
from ubuntu
MAINTAINER Alex
VOLUME ["/volumes"]
生成镜像
[root@ /build]# docker build -t myvolume .
# 运行容器
[root@ /build]# docker run -itd --name volume-test -v /docker/volumes:/volumes myvolume /bin/bash
# 进入容器
[root@ /build]# docker exec -it volume-test /bin/bash
root@42adea7beae7:/# ll volumes
total 0
drwxr-xr-x 6 root root 59 Dec 15 07:54 ./
drwxr-xr-x 1 root root 33 Dec 15 08:08 ../
drwxr-xr-x 2 root root 72 Dec 15 08:08 build/
drwxr-xr-x 4 root root 35 Dec 15 06:16 centos/
drwxr-xr-x 4 root root 30 Dec 4 08:49 mysql/
drwxr-xr-x 6 root root 53 Dec 15 06:16 nginx/
退出容器后
[root@ build]# docker inspect volume-test | grep "Mounts" -A8
"Mounts": [
{
"Type": "bind",
"Source": "/docker/volumes",
"Destination": "/volumes",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
可以看到挂载点的信息
目前我们已经有了一个数据卷容器,在 docker run中使用 --volumes-from标记,可以让其他容器共享当前共享卷volume-test的/volumes;
[root@ build]# docker run --name nginx-test -d -p 9999:80 --volumes-from volume-test -v /docker/volumes/nginx/conf/nginx.conf:/etc/nginx/nginx.conf -v /docker/volumes/nginx/html:/usr/share/nginx/html -v /docker/volumes/nginx/logs:/var/log/nginx nginx
# 进入容器
[root@ centos]# docker exec -it nginx-test /bin/bash
root@1168a85a4bf3:/# ll volumes/
total 0
drwxr-xr-x 2 root root 72 Dec 15 08:08 build
drwxr-xr-x 4 root root 35 Dec 15 06:16 centos
drwxr-xr-x 4 root root 30 Dec 4 08:49 mysql
drwxr-xr-x 6 root root 53 Dec 15 06:16 nginx
目录中内容是共享的,任何一个容器修改了内容,别的容器都能获取到。