数据共享是volume的关键特性,今天我们来看一下通过volume实现容器与host、容器与容器之间共享数据。
一、容器与host共享数据
在上一篇中介绍到的bind mount和docker manage volume,它们都可以实现容器与host之间共享数据,只是方式有所区别,bind mount在容器启动前便指定了volume所在host数据目录,并挂载到容器中了,容器启动后,我们向此目录写入数据,容器也能使用这些数据,而对于docker manage volume,有所不同,它在容器启动时才能确定volume所在host的目录,所以这里就需要用到docker cp 命令,它可以在容器和host之间复制数据。
$ sudo docker run -d -p 80:80 -v /usr/local/apache2/htdocs httpd0320b31996408b61a1bc363f999509f3bfdc17ca292dd08bd5f7496edb7c8947$ sudo docker cp ~/htdocs/index.html 0320b31996:/usr/local/apache2/htdocs$ curl http://127.0.0.1:80<h1>update page</h1>
二、容器之间共享数据
1、bind mount
第一种方式还是bind mount,将要共享的数据通过bind mount挂载到多个容器上,例如,我们启动三个httpd容器,并让它们挂载相同的htdocs。
$ sudo docker run --name web1 -d -p 80 -v ~/htdocs:/usr/local/apache2/htdocs httpdf5a911434445f431d511b5292112fe0f9b9b44b868f98561feba895107e0cb40$ sudo docker run --name web2 -d -p 80 -v ~/htdocs:/usr/local/apache2/htdocs httpd61e43e584c33efdab7ef5c1a72a5a4e9a0d40731d860e5fd9fb23de0a7c767df$ sudo docker run --name web3 -d -p 80 -v ~/htdocs:/usr/local/apache2/htdocs httpd6494f68481a0f1971fdc33c13b969706c69b8ecaedc39aa707b6d35d32b6fba0$ sudo docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES6494f68481a0 httpd "httpd-foreground" 11 seconds ago Up 9 seconds 0.0.0.0:49155->80/tcp, :::49155->80/tcp web361e43e584c33 httpd "httpd-foreground" 19 seconds ago Up 17 seconds 0.0.0.0:49154->80/tcp, :::49154->80/tcp web2f5a911434445 httpd "httpd-foreground" 28 seconds ago Up 27 seconds 0.0.0.0:49153->80/tcp, :::49153->80/tcp web1$ curl http://127.0.0.1:49155<h1>hello docker</h1>$ curl http://127.0.0.1:49154<h1>hello docker</h1>$ curl http://127.0.0.1:49153<h1>hello docker</h1>
2、volume container
volume container是专门为其他容器提供volume的容器,它提供的volume可以是bind mount也可以是docker manage volume,我们首先创建一个volume container:
$ sudo docker create --name vc_data -v ~/htdocs:/usr/local/apache2/htdocs -v /other/useful/tools busybox178dd66f492dbe0485816a9f6f9ecde97c03e322841e6b38f4a2c7c439c6f020
我们挂载了两个volume,一个是使用bind mount挂载web静态页面,另一个使用docker manage volume挂载常用工具。注意我们使用docker create命令,这是因为volume container的作用只是提供数据,它本身不需要处于运行状态。
通过docker inspect可以看到这两个volume:
$ sudo docker inspect vc_data[..."Mounts": [{"Type": "bind","Source": "/home/yangye/htdocs","Destination": "/usr/local/apache2/htdocs","Mode": "","RW": true,"Propagation": "rprivate"},{"Type": "volume","Name": "e3ba7240ef18694660ed3da4e6976fa35bb5c2d3c26f91593ea30d26289e0fd6","Source": "/var/lib/docker/volumes/e3ba7240ef18694660ed3da4e6976fa35bb5c2d3c26f91593ea30d26289e0fd6/_data","Destination": "/other/useful/tools","Driver": "local","Mode": "","RW": true,"Propagation": ""}...]
接着我们在启动容器时通过--volumes_from使用刚创建的vc_data:
$ sudo docker run --name web1 -d -p 80 --volumes-from vc_data httpd14131cc7057528ac892b2661ed46e543bb30b65af789d83f0770dab4ebb06a33$ sudo docker run --name web2 -d -p 80 --volumes-from vc_data httpd320a11bcb64ee032c65b65ee744a7afd6ebc7a24330e68c688a4b9c4b5e5eb22$ sudo docker run --name web3 -d -p 80 --volumes-from vc_data httpdf4c4bed873f3ad76b37136fc93dd915c6e4915897e7628f3b1ca1d5fc30e920a
我们以web1为例看看它的volume是否正确:
$ sudo docker inspect web1[..."Mounts": [{"Type": "bind","Source": "/home/yangye/htdocs","Destination": "/usr/local/apache2/htdocs","Mode": "","RW": true,"Propagation": "rprivate"},{"Type": "volume","Name": "e3ba7240ef18694660ed3da4e6976fa35bb5c2d3c26f91593ea30d26289e0fd6","Source": "/var/lib/docker/volumes/e3ba7240ef18694660ed3da4e6976fa35bb5c2d3c26f91593ea30d26289e0fd6/_data","Destination": "/other/useful/tools","Driver": "local","Mode": "","RW": true,"Propagation": ""}...
可见,web1使用的就是vc_data的volume,我再来验证下数据共享的效果:
$ sudo docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMESf4c4bed873f3 httpd "httpd-foreground" 10 minutes ago Up 10 minutes 0.0.0.0:49158->80/tcp, :::49158->80/tcp web3320a11bcb64e httpd "httpd-foreground" 10 minutes ago Up 10 minutes 0.0.0.0:49157->80/tcp, :::49157->80/tcp web214131cc70575 httpd "httpd-foreground" 10 minutes ago Up 10 minutes 0.0.0.0:49156->80/tcp, :::49156->80/tcp web1$ curl http://127.0.0.1:49158<h1>hello docker</h1>$ curl http://127.0.0.1:49157<h1>hello docker</h1>$ curl http://127.0.0.1:49156<h1>hello docker</h1>
三个容器都共享了volume_container中的volume,相比于bind mount,我们发现volume container具备以下特点:
1)不必为每一个容器指定host path,所有path都在volume container中定义好了,容器只需和volume container关联,实现了容器与host的解耦;
2)使用volume container的容器,其mount point都是一致的,有利于配置的规范和标准化,当然这样也存在一定的局限使用时需要综合考虑。




