docker快速入门5-存储卷

docker快速入门5-存储卷

Docker镜像由多个只读层叠加而成,启动容器时,Docker会加载只读镜像层并在镜像栈顶部添加一个读写层。

如果运行中的容器修改了现有的一个已经存在的文件,那该文件将会从读写下面的只读层复制到读写层,该文件的只读版本依然存在,只是已经被读写层中该文件的副本所隐藏,即写时复制(COW)机制。

卷为docker提供了独立于容器的数据管理机制:

  • 可以把镜像想像成静态文件,例如程序,把卷类比为动态内容,例如数据,于是,镜像可以重用,而卷可以共享
  • 卷实现了程序(镜像)数据(卷)分离,以及程序(镜像)制作镜像的主机分离,用户制作镜像时无须再考虑镜像运行的容器所在的主机环境。

存储卷分类

Docker的存储卷有两种类型:

  1. Bind mount volume,即绑定挂载卷,简单说来就是宿主机上的一个文件路径与容器内的一个文件路径建立绑定关系。
  2. Docker managed volume,即Docker管理卷,简单说来是容器内的一个文件路径与宿主机上的文件路径的绑定关系不是用户操作,而是交给dockerd来管理,默认是宿主机上的/var/lib/docker/volumes/<volume ID>

docker container run 命令使用-v选项即可使用volume。

Bind moutn volume创建方式

root@node01:~# docker container run -i -t --rm --name bbox01 -v /data/pub/html:/data/html busybox:latest
/ # ls /data/html/
/ #

-v /data/pub/html:/data/html 分号前表示宿主机上的绑定目录,分号后表示容器内的绑定目录,目录如果不存在会自动创建。

如果要绑定多个目录关系,-v选项可以使用多次。

到宿主机上查看是否有/data/pub/html目录

root@node01:~# ls /data/pub/html/
root@node01:~# echo "hello..." > /data/pub/html/index.html
root@node01:~# ls /data/pub/html/
index.html

目录被自动创建,并且增加了一个文件,再回到容器内查看,也能查看到相应的文件

root@node01:~# docker container run -i -t --rm --name bbox01 -v /data/pub/html:/data/html busybox:latest
/ # ls /data/html/
/ # ls /data/html/
index.html

查看容器的详细信息可以看到mount的详细信息

root@node01:~# docker inspect bbox01
...
"Mounts": [
            {
                "Type": "bind",
                "Source": "/data/pub/html",
                "Destination": "/data/html",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],
 ...

Docker mananged volume创建方式

root@node01:~# docker container run -i -t --rm --name bbox01 -v /data/html busybox:latest
/ # ls /data/html/
/ # echo "hello word." > /data/html/index.html
/ #

-v /data/html 只有一个路径时表示的是容器内部的目录。

可以探测下存储卷在宿主机上的位置

root@node01:~# docker inspect  bbox01
...
 "Mounts": [
            {
                "Type": "volume",
                "Name": "8c1be16f1b119faba6006b98b7763ce141f8fe2243cc2b970660aac0f33416a4",
                "Source": "/var/lib/docker/volumes/8c1be16f1b119faba6006b98b7763ce141f8fe2243cc2b970660aac0f33416a4/_data",
                "Destination": "/data/html",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ]
 ...
root@node01:~# docker inspect -f {{.Mounts}} bbox01 # 使用go模板语法进行过滤
[{volume 8c1be16f1b119faba6006b98b7763ce141f8fe2243cc2b970660aac0f33416a4 /var/lib/docker/volumes/8c1be16f1b119faba6006b98b7763ce141f8fe2243cc2b970660aac0f33416a4/_data /data/html local  true }]

root@node01:~# cat /var/lib/docker/volumes/8c1be16f1b119faba6006b98b7763ce141f8fe2243cc2b970660aac0f33416a4/_data/index.html
hello word.

存储卷复制

宿主机上的一个目录可以绑定给多个容器,即多个容器就可以通过这个存储卷进行数据共享,只需要在启动容器时通过-v选项进行绑定即可。如果需要共享存储卷的容器较多时,每一个容器都需要-v HOST_DIR:CONTAINER_DIR指定绑定关系,docker为了简化,在运行容器时可以复制其他容器的存储卷绑定关系来达到挂载与之相同的存储卷。

要想复制其他容器的存储卷绑定关系,使用--volumes-from选项

先启动一个容器

root@node01:~# docker container run -i -t --rm --name bbox01 -v /data/pub/html:/data/html busybox:latest
/ # ls /data/html/
index.html
/ # cat /data/html/index.html
hello...
/ #

再启动另一个容器,使用--volumes-from选项复制bbox01的存储卷信息

root@node01:~# docker container run -i -t --rm --name bbox02 --volumes-from bbox01 busybox:latest
/ # ls /data/html/
index.html
/ # cat /data/html/index.html
hello...

同样可以使用docker inspect命令查看两个容器存储卷的挂载信息。bbox02bbox01容器实现了挂载相同的存储卷。

联盟网络与存储卷复制

结合联盟式网络和存储卷复制的特性,可以实现这样一个架构,nginx + tomcat + mysql,nginx反代到tomcat,tomcat与mysql进行交互,他们各自运行在一个容器中,通过联盟式网络让三者共享网络名称空间,外部请求nginx的容器地址,nginx与tomcat通信走lo接口,tomcat与mysql通信也走lo接口,网页存放与mysql的数据存放都通过存储卷绑定到宿主机上。

这种架构的实现,一般先制作一个基础架构容器,该容器可以不处理于运行状态,只要创建好即可,它提供网络名称空间存储卷等基础配置,nginxtomcatmysql三个容器在启动时加入到基础架构容器的网络名称空间,并复制它的存储卷信息。

这样灵活运用联盟网络和存储卷的复制特性可以演变出一些有趣的架构。

猜你喜欢

转载自blog.51cto.com/zhaochj/2536685