容器与 host 共享数据
bind mount:直接将要共享的目录 mount 到容器。
docker managed volume:由于volume位于host中的目录,是在容器启动时才生成,所以需要将共享数据复制到volume中。
docker cp ~/htdocs/index.html [containerID]:/usr/local/apache2/htdocs
#改命令可以在 host 和容器之间复制数据,也可以通过 Linux 的 cp 命令复制到 /var/docker/volumes/xxx 中。
容器之间数据共享
bind mount
将共享数据放在 bind mount 中,然后将其 mount 到多个容器。举例:创建由三个 httpd 容器组成的 Web server 集群,它们使用相同的 html 文件,操作如下:
root@Wangying:~/htdocs# docker run --name web1 -d -p 80 -v ~/htdocs:/usr/local/apache2/htdocs httpd
a6e0e3358e3d34329a6ab5e7484673ec13a271e9055318195d8803d8f149b4d1
root@Wangying:~/htdocs# docker run --name web2 -d -p 80 -v ~/htdocs:/usr/local/apache2/htdocs httpd
42fcf1f217d0c9ac30b4c7f27a3c500818498579ffc014de08e8594d171adbc0
root@Wangying:~/htdocs# docker run --name web3 -d -p 80 -v ~/htdocs:/usr/local/apache2/htdocs httpd
add8c14869a096363621dc68a6d3fd1c7e68fa7c3e0928aa83478a54ecf186f0
root@Wangying:~/htdocs# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
add8c14869a0 httpd "httpd-foreground" 10 seconds ago Up 8 seconds 0.0.0.0:61503->80/tcp web3
42fcf1f217d0 httpd "httpd-foreground" 20 seconds ago Up 18 seconds 0.0.0.0:61498->80/tcp web2
a6e0e3358e3d httpd "httpd-foreground" 32 seconds ago Up 30 seconds 0.0.0.0:61493->80/tcp web1
root@Wangying:~/htdocs# curl 127.0.0.1:61503
shiahdiudabibfwd
root@Wangying:~/htdocs# curl 127.0.0.1:61498
shiahdiudabibfwd
root@Wangying:~/htdocs# curl 127.0.0.1:61493
shiahdiudabibfwd
root@Wangying:~/htdocs# echo "This is a new index page for web cluster" > ~/htdocs/index.html
root@Wangying:~/htdocs# curl 127.0.0.1:61493
This is a new index page for web cluster
root@Wangying:~/htdocs# curl 127.0.0.1:61493
This is a new index page for web cluster
root@Wangying:~/htdocs# curl 127.0.0.1:61498
This is a new index page for web cluster
首先将 ~/htdocs mount 到三个 httpd 容器,查看主页内容,可见三个容器的端口,访问三个容器,拿到相同的数据,修改 volume 文件,再次查看,发现三个容器数据都发生变化。
volume container
volume container 是专门为其他容器提供 volume 的容器。它提供的卷可以是 bind mount,也可以是 docker managedvolume 。
root@Wangying:~# docker create --name vc_data \
> -v ~/htdocs:/usr/local/apache2/htdocs \
> -v /other/useful/tools \
> busybox
将容器命名为 vc_data(vc是volume container的缩写)。注意这里执行的是 docker create 命令,这是因为 volume container 的作用只是提供数据,它本身不需要处于运行状态。容器 mount 了两个 volume:bind volume 存放 Web Server 静态文件,docker managed volume 存放一些实用工具。
root@Wangying:~# docker run --name web1 -d -p 80 --volumes-from vc_data httpd
e0d6a6d8449c462c1b255a2e86c70549b24b2c5c55ad242f03de78493c79f465
root@Wangying:~# docker run --name web2 -d -p 80 --volumes-from vc_data httpd
78a064901f6ef84602cf017cde5325433da505ca797ae16f442c25d8d3d2a400
root@Wangying:~# docker run --name web3 -d -p 80 --volumes-from vc_data httpd
5af0659a88cc65138392c32a97d36b6b2b38ee8fda92d493b5656403690ded5d
docker inspect vc_data
"Mounts": [
{
"Type": "bind",
"Source": "/root/htdocs",
"Destination": "/usr/local/apache2/htdocs",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
},
{
"Type": "volume",
"Name": "03df0d0a2161f568d93ebec93f6923ca1c996ae2339f2cabfbf00a7a9538ec49",
"Source": "/var/lib/docker/volumes/03df0d0a2161f568d93ebec93f6923ca1c996ae2339f2cabfbf00a7a9538ec49/_data",
"Destination": "/other/useful/tools",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5af0659a88cc httpd "httpd-foreground" About a minute ago Up About a minute 0.0.0.0:62064->80/tcp web3
78a064901f6e httpd "httpd-foreground" About a minute ago Up About a minute 0.0.0.0:62062->80/tcp web2
e0d6a6d8449c httpd "httpd-foreground" About a minute ago Up About a minute 0.0.0.0:62058->80/tcp web1
root@Wangying:~# echo "This is a new index page from a volume container" > ~/htdocs/index.html
root@Wangying:~# curl 127.0.0.1:62064
This is a new index page from a volume container
root@Wangying:~# curl 127.0.0.1:62062
This is a new index page from a volume container
root@Wangying:~# curl 127.0.0.1:62058
This is a new index page from a volume container
特点:(1)与 bind mount 相比,不必为每一个容器指定 hostpath,所有 path 都在 volume container 中定义好了,容器只需与 volume container 关联,实现了容器与 host 的解耦。(2)使用 volume container 的容器,其 mount point 是一致的,有利于配置的规范和标准化,但也带来一定的局限,使用时需要综合考虑。
data-packed volume container
上述多种方式最后数据还是都在容器中,这里介绍一种方式将数据完全放到 volume container 中,同时能够与其他容器共享。
这种容器被称作:data-packed volume container。其原理就是将数据打包到镜像中,然后通过 docker managed volume 共享。
#首先使用 DOckerfile 构建镜像
FROM busybox:latest
ADD htdocs /usr/local/apache2/htdocs
VOLUME /usr/local/apache2/htdocs
#VOLUME 的作用与 -v 等效,用来创建 docker managed volume, mount point为 /usr/local/apache2/htdocs,因为这个目录就是 ADD 添加的目录,所以会将已有数据复制到 volume 中。
#build 创建新的镜像
docker build -t datapackaged .
docker create --name vc_datap datapackaged
docker run -d -p 80:80 --volumes-from vc_datap httpd
#因为在 Dockerfile 中已经使用了 VOLUME 指令,这里就不需要指定 volume 的 mount point 了。启动 httpd 容器并使用 data-packed volume container
容器能够正确读取 volume 中的数据。data-packed volumecontainer 是自包含的,不依赖 host 提供数据,具有很强的移植性,非常适合只使用静态数据的场景,比如应用的配置信息、Web server 的静态文件等。