容器与 host 共享数据

  1. bind mount:直接将要共享的目录 mount 到容器。
  2. docker managed volume:由于volume位于host中的目录,是在容器启动时才生成,所以需要将共享数据复制到volume中。
  3. docker cp ~/htdocs/index.html [containerID]:/usr/local/apache2/htdocs
  4. #改命令可以在 host 和容器之间复制数据,也可以通过 Linux 的 cp 命令复制到 /var/docker/volumes/xxx 中。

容器之间数据共享

bind mount

将共享数据放在 bind mount 中,然后将其 mount 到多个容器。举例:创建由三个 httpd 容器组成的 Web server 集群,它们使用相同的 html 文件,操作如下:

  1. root@Wangying:~/htdocs# docker run --name web1 -d -p 80 -v ~/htdocs:/usr/local/apache2/htdocs httpd
  2. a6e0e3358e3d34329a6ab5e7484673ec13a271e9055318195d8803d8f149b4d1
  3. root@Wangying:~/htdocs# docker run --name web2 -d -p 80 -v ~/htdocs:/usr/local/apache2/htdocs httpd
  4. 42fcf1f217d0c9ac30b4c7f27a3c500818498579ffc014de08e8594d171adbc0
  5. root@Wangying:~/htdocs# docker run --name web3 -d -p 80 -v ~/htdocs:/usr/local/apache2/htdocs httpd
  6. add8c14869a096363621dc68a6d3fd1c7e68fa7c3e0928aa83478a54ecf186f0
  7. root@Wangying:~/htdocs# docker ps
  8. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  9. add8c14869a0 httpd "httpd-foreground" 10 seconds ago Up 8 seconds 0.0.0.0:61503->80/tcp web3
  10. 42fcf1f217d0 httpd "httpd-foreground" 20 seconds ago Up 18 seconds 0.0.0.0:61498->80/tcp web2
  11. a6e0e3358e3d httpd "httpd-foreground" 32 seconds ago Up 30 seconds 0.0.0.0:61493->80/tcp web1
  12. root@Wangying:~/htdocs# curl 127.0.0.1:61503
  13. shiahdiudabibfwd
  14. root@Wangying:~/htdocs# curl 127.0.0.1:61498
  15. shiahdiudabibfwd
  16. root@Wangying:~/htdocs# curl 127.0.0.1:61493
  17. shiahdiudabibfwd
  18. root@Wangying:~/htdocs# echo "This is a new index page for web cluster" > ~/htdocs/index.html
  19. root@Wangying:~/htdocs# curl 127.0.0.1:61493
  20. This is a new index page for web cluster
  21. root@Wangying:~/htdocs# curl 127.0.0.1:61493
  22. This is a new index page for web cluster
  23. root@Wangying:~/htdocs# curl 127.0.0.1:61498
  24. This is a new index page for web cluster

首先将 ~/htdocs mount 到三个 httpd 容器,查看主页内容,可见三个容器的端口,访问三个容器,拿到相同的数据,修改 volume 文件,再次查看,发现三个容器数据都发生变化。

volume container

volume container 是专门为其他容器提供 volume 的容器。它提供的卷可以是 bind mount,也可以是 docker managedvolume 。

  1. root@Wangying:~# docker create --name vc_data \
  2. > -v ~/htdocs:/usr/local/apache2/htdocs \
  3. > -v /other/useful/tools \
  4. > busybox
  5. 将容器命名为 vc_datavcvolume container的缩写)。注意这里执行的是 docker create 命令,这是因为 volume container 的作用只是提供数据,它本身不需要处于运行状态。容器 mount 了两个 volumebind volume 存放 Web Server 静态文件,docker managed volume 存放一些实用工具。
  6. root@Wangying:~# docker run --name web1 -d -p 80 --volumes-from vc_data httpd
  7. e0d6a6d8449c462c1b255a2e86c70549b24b2c5c55ad242f03de78493c79f465
  8. root@Wangying:~# docker run --name web2 -d -p 80 --volumes-from vc_data httpd
  9. 78a064901f6ef84602cf017cde5325433da505ca797ae16f442c25d8d3d2a400
  10. root@Wangying:~# docker run --name web3 -d -p 80 --volumes-from vc_data httpd
  11. 5af0659a88cc65138392c32a97d36b6b2b38ee8fda92d493b5656403690ded5d
  12. docker inspect vc_data
  13. "Mounts": [
  14. {
  15. "Type": "bind",
  16. "Source": "/root/htdocs",
  17. "Destination": "/usr/local/apache2/htdocs",
  18. "Mode": "",
  19. "RW": true,
  20. "Propagation": "rprivate"
  21. },
  22. {
  23. "Type": "volume",
  24. "Name": "03df0d0a2161f568d93ebec93f6923ca1c996ae2339f2cabfbf00a7a9538ec49",
  25. "Source": "/var/lib/docker/volumes/03df0d0a2161f568d93ebec93f6923ca1c996ae2339f2cabfbf00a7a9538ec49/_data",
  26. "Destination": "/other/useful/tools",
  27. "Driver": "local",
  28. "Mode": "",
  29. "RW": true,
  30. "Propagation": ""
  31. }
  32. ],
  33. docker ps
  34. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  35. 5af0659a88cc httpd "httpd-foreground" About a minute ago Up About a minute 0.0.0.0:62064->80/tcp web3
  36. 78a064901f6e httpd "httpd-foreground" About a minute ago Up About a minute 0.0.0.0:62062->80/tcp web2
  37. e0d6a6d8449c httpd "httpd-foreground" About a minute ago Up About a minute 0.0.0.0:62058->80/tcp web1
  38. root@Wangying:~# echo "This is a new index page from a volume container" > ~/htdocs/index.html
  39. root@Wangying:~# curl 127.0.0.1:62064
  40. This is a new index page from a volume container
  41. root@Wangying:~# curl 127.0.0.1:62062
  42. This is a new index page from a volume container
  43. root@Wangying:~# curl 127.0.0.1:62058
  44. This is a new index page from a volume container
  1. 特点:(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 的静态文件等。