Docker-基础003-容器数据卷

学习内容总结来自B站UP主"遇见狂神说"的Docker教学视频: https://www.bilibili.com/video/BV1og4y1q7M4

容器数据卷

作用: 能够实现容器的数据持久化以及数据共享同步(包括容器间和容器与主机间)

效果: 同步后, 能够直接在本机修改容器的配置文件等, 不需要进入容器

1. 使用命令来挂载 -v

docker run -it -v 主机的目录:容器中的目录
# 测试
docker run -dit -v /home/test:/home/dc_test --name mytomcat02 mytomcat
  • 可以发现主机和容器都分别自动新建了test和dc_test文件夹
  • 在主机的文件夹test中新增一个test.py的文件, 去容器的终端查看对应的dc_test文件夹, 发现里面也同步增加了一个test.py文件, 说明是挂载成功了的
  • 还可以通过 docker inspect 容器ID 来查看是否挂载成功
docker inspect mytomcat02
# 查看结果, 找到mount键值对, 则挂载成功
"Mounts": [
    {
        "Type": "bind", # 绑定成功
        "Source": "/home/test",  # 主机目录
        "Destination": "/home/dc_test",  # 容器目录
        "Mode": "",
        "RW": true,  # 读写都为True
        "Propagation": "rprivate"
    }
],
  • 停止容器mytomcat02后, 更新主机的test.py文件, 然后再启动mytomcat02, 进入到容器目录后发现其中的test.py文件依然同步更新了, 说明挂载后, 即使容器处于关闭状态, 也会同步文件

具名挂载和匿名挂载

# 指定路径挂载
-v 主机目录:容器内目录

# 匿名挂载, 只写容器内路径
-v 容器内路径
	# 如 
	docker run -d -p 8000:80 --name nginx01 -v /etc/nginx nginx
	# docker volume ls 查看卷信息, 发现卷名为一个长串字符
	DRIVER      VOLUME NAME
	local       host-nginx
	
# 具名挂载, 在主机目录的位置用一个有名的变量代替
-v some_name:容器内目录
	# 如
	docker run -d -p 8001:80 --name nginx02 -v host-nginx:/etc/nginx nginx
	# docker volume ls 查看卷信息, 发现卷名为一个长串字符
	DRIVER      VOLUME NAME
	local       7cbeb2b6422569a9ca98cd000b1630836c108acde428fc5145723fc93126329e

查看卷信息

docker volume COMMAND

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
# 如: docker volume ls
# 如: docker volume inspect host-nginx 查看某个卷的信息
[
    {
        "CreatedAt": "2020-07-27T22:46:41+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/host-nginx/_data",
        "Name": "host-nginx",
        "Options": null,
        "Scope": "local"
    }
]

所有的docker数据默认情况下都在

/var/lib/docker

Docker-基础003-容器数据卷

挂载的卷数据在/var/lib/docker/volumes/卷名/_data下面

Docker-基础003-容器数据卷

Docker-基础003-容器数据卷

推荐使用具名挂载, 这样能更加方便查看卷信息

数据卷权限

-v some_name:容器内路径:ro(rw)
# 如 docker run -d -p 8000:80 --name nginx03 -v nginx03:/etc/nginx:ro nginx
# ro 表示read-only, 设置了之后, 容器内不就没有权限修改, 只能主机修改
# rw 表示read-write, 默认为rw, 容器和主机都能改

查看容器的信息中的挂载信息

docker inspect nginx03

Docker-基础003-容器数据卷

发现"Mode"为"ro", "RW"为false, 说明模式为只读

2. 创建简单dockerfile实现挂载

dockerfile就是用来构建docker镜像的构建文件, 实质为一段命令脚本.

通过这段脚本可以生成镜像, 镜像是一层一层的, 原因是脚本也是一个一个的命令, 每运行一个命令, 镜像就增加一层

新建编辑dockerfile01

# 继承标准的centos镜像
FROM centos
# 挂载卷(只写了容器内的路径, 为匿名挂载)
VOLUME ["volume01","volume02"]
# 完成后打印输出成功
CMD echo "---------sucess-------"
# 进入容器后使用
CMD /bin/bash

build构建dockerfile的镜像

# -f dockerfile文件
# -t tag, 自定义镜像的名字
# 注意最后有一个点.
docker build -f dockerfile01 -t alex/centos .

Docker-基础003-容器数据卷

用自定义的镜像启动容器

docker run -it --name mycentos alex/centos

启动后, 在容器根目录下可以发现挂载的两个目录

Docker-基础003-容器数据卷

在其中volume01下新建文件container.py, 看看主机对应的目录是否会同步新增该文件夹

查看主机挂载路径

docker inspect mycentos

查看mount键值对, 可以找到主机对应的路径

Docker-基础003-容器数据卷

进入volume01对应的主机路径, 可以看到确实同步了container.py文件

Docker-基础003-容器数据卷

3. 容器间共享数据卷(--volumes-from)

测试: 多个centos容器间同步数据

3.1 用上面自定的镜像, 启动两个centos容器, mycentos01/mycentos02, 其中01作为主容器卷
# 启动第一个
docker run -dit --name mycentos01 alex/centos
# 启动第二个
docker run -dit --name mycentos01 --volumes-from  alex/centos

可以看到两个容器的inspect信息中的挂载信息, 对应的主机路径都是一样的

docker inspect mycentos01

Docker-基础003-容器数据卷

docker inspect mycentos02

Docker-基础003-容器数据卷

也就是说其实两个容器内的数据卷都和主机同一个路径绑定了, 主机路径就像一个桥梁一样把两个容器连接起来了

3.2 在01容器中的volume01下, 新建container01.py文件

来到主机对应挂载目录和02容器的volume01下, 发现都新建了container01.py文件

同理, 在02容器下的volume01或volume02中增删改文件, 主机和02容器也会同步修改

3.3 再次创建一个容器, mycentos03 , 同样挂载于01容器mycentos01
docker run -dit --name mycentos03 --volumes-from mycentos01  alex/centos

在01容器中增删改文件, 发现主机/02/03都会同步修改

在03容器中增删改文件, 发现主机/01/02也都会同步修改

所以这三个容器和主机之间都是同步的

3.4 再次创建一个容器, mycentos04 , 这次挂载于02容器mycentos02
docker run -dit --name mycentos04 --volumes-from mycentos02  alex/centos

在01容器中增删改文件, 发现主机/02/03/04都会同步修改

在04容器中增删改文件, 发现主机/01/02/03也都会同步修改

所以这四个容器和主机之间都是同步的

3.5 最后创建一个容器, mycentos05, 这次不挂载与上述任何一个容器
docker run -dit --name mycentos05 alex/centos

查看inspect的mount信息, 发现对应的主机目录与上述容器对应的主机目录不是同一个, 说明这新容器05和之前创建的容器并没有数据关联

经过上述实验可以发现:

即使是多级挂载, 所有的容器内目录依然与主机的同一个目录进行了关联, 那么这些容器的挂载目录文件和主机都是相互共享的.

若两个容器间对应的主机目录不相同, 则说明这两个容器不共享

相关推荐