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
挂载的卷数据在/var/lib/docker/volumes/卷名/_data
下面
推荐使用具名挂载, 这样能更加方便查看卷信息
数据卷权限
-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
发现"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 run -it --name mycentos alex/centos
启动后, 在容器根目录下可以发现挂载的两个目录
在其中volume01下新建文件container.py, 看看主机对应的目录是否会同步新增该文件夹
查看主机挂载路径
docker inspect mycentos
查看mount键值对, 可以找到主机对应的路径
进入volume01对应的主机路径, 可以看到确实同步了container.py文件
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 inspect mycentos02
也就是说其实两个容器内的数据卷都和主机同一个路径绑定了, 主机路径就像一个桥梁一样把两个容器连接起来了
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和之前创建的容器并没有数据关联
经过上述实验可以发现:
即使是多级挂载, 所有的容器内目录依然与主机的同一个目录进行了关联, 那么这些容器的挂载目录文件和主机都是相互共享的.
若两个容器间对应的主机目录不相同, 则说明这两个容器不共享