容器(六)Data Volume 之 bind mount【34】

(二)Data Volume 之 bind mount

​ storage driver 和 data volume 是容器存放数据的两种方式,上一节咱们学习了 storage driver,本节开始讨论 Data Volume。Data Volume 本质上是 Docker Host 文件系统中的目录或文件,可以直接被 mount 到容器的文件系统中。Data Volume 有如下特色:html

  1. Data Volume 是目录或文件,而非没有格式化的磁盘(块设备)。
  2. 容器能够读写 volume 中的数据。
  3. volume 数据能够被永久的保存,即便使用它的容器已经销毁。

如今咱们有数据层(镜像层和容器层)和 volume 均可以用来存放数据,具体使用的时候要怎样选择呢?考虑下面几个场景:mysql

  1. Database 软件 vs Database 数据
  2. Web 应用 vs 应用产生的日志
  3. 数据分析软件 vs input/output 数据
  4. Apache Server vs 静态 HTML 文件

相信你们会作出这样的选择:linux

  1. 前者放在数据层中。由于这部份内容是无状态的,应该做为镜像的一部分。
  2. 后者放在 Data Volume 中。这是须要持久化的数据,而且应该与镜像分开存放。

还有个你们可能会关心的问题:如何设置 voluem 的容量?sql

由于 volume 其实是 docker host 文件系统的一部分,因此 volume 的容量取决于文件系统当前未使用的空间,目前尚未方法设置 volume 的容量。在具体的使用上,docker 提供了两种类型的 volume:bind mount 和 docker managed volume。docker

(1)bind mount

bind mount 是将 host 上已存在的目录或文件 mount 到容器。经过 -v 将其 mount 到 httpd 容器:apache

root@cuiyongchao:~# docker run -d -p 81:80 -v /root/htdocs/://usr/local/apache2/htdocs httpd
c75e9caa7d615493f3c64e5c0c27a914c6ce9cb0d6fa97ca0d4c07cf8d0f5c74
root@cuiyongchao:~# cat /root/htdocs/index.html 
<html><body><h1>this is a file.</h1></body></html>
root@cuiyongchao:~#

-v 的格式为 <host path>:<container path>。/usr/local/apache2/htdocs 就是 apache server 存放静态文件的地方。因为 /usr/local/apache2/htdocs 已经存在,原有数据会被隐藏起来,取而代之的是 host $HOME/htdocs/ 中的数据,这与 linux mount 命令的行为是一致的。安全

root@cuiyongchao:~# curl 10.0.0.20:81
<html><body><h1>this is a file.</h1></body></html>
root@cuiyongchao:~#

curl 显示当前主页确实是 $HOME/htdocs/index.html 中的内容。更新一下,看是否能生效:bash

root@cuiyongchao:~# echo "<html><body><h1>it is changing,please waiting.</h1></body></html>" >/root/htdocs/index.html
root@cuiyongchao:~# curl 10.0.0.20:81
<html><body><h1>it is changing,please waiting.</h1></body></html>
root@cuiyongchao:~#

host 中的修改确实生效了,bind mount 可让 host 与容器共享数据。这在管理上是很是方便的。curl

下面咱们将容器销毁,看看对 bind mount 有什么影响:学习

root@cuiyongchao:~# docker stop c75e9caa7d61
c75e9caa7d61
root@cuiyongchao:~# docker rm c75e9caa7d61
c75e9caa7d61
root@cuiyongchao:~# cat /root/htdocs/index.html 
<html><body><h1>it is changing,please waiting.</h1></body></html>
root@cuiyongchao:~#

可见,即便容器没有了,bind mount 也还在。这也合理,bind mount 是 host 文件系统中的数据,只是借给容器用用,哪能随便就删了啊。

另外,bind mount 时还能够指定数据的读写权限,默认是可读可写,可指定为只读:

root@cuiyongchao:~# docker run -d -p 82:80 -v /root/htdocs/:/usr/local/apache2/htdocs:ro httpd
fbb20d680a686c9270675f9dca4c059c0f6167816e30033dca8c1e904944d3f6
root@cuiyongchao:~# 
root@cuiyongchao:~# 
root@cuiyongchao:~# docker exec -it fbb20d680a686c9270675f9dca4c059c0f6167816e30033dca8c1e904944d3f6 /bin/bash
root@fbb20d680a68:/usr/local/apache2# ls
bin  build  cgi-bin  conf  error  htdocs  icons  include  logs	modules
root@fbb20d680a68:/usr/local/apache2# cd htdocs/
root@fbb20d680a68:/usr/local/apache2/htdocs# ll
bash: ll: command not found
root@fbb20d680a68:/usr/local/apache2/htdocs# ls
index.html
root@fbb20d680a68:/usr/local/apache2/htdocs# cat index.html 
<html><body><h1>it is changing,please waiting.</h1></body></html>
root@fbb20d680a68:/usr/local/apache2/htdocs# 
root@fbb20d680a68:/usr/local/apache2/htdocs# echo "thi is ro file.">index.html 
bash: index.html: Read-only file system
root@fbb20d680a68:/usr/local/apache2/htdocs#

ro 设置了只读权限,在容器中是没法对 bind mount 数据进行修改的。只有 host 有权修改数据,提升了安全性。

除了 bind mount 目录,还能够单独指定一个文件:

root@cuiyongchao:~# docker run -d -p 83:80 -v /root/htdocs/index.html:/usr/local/apache2/htdocs/index.html httpd
44cfb081082ef03cbf9e125cf66136ebf0f95e27c732e799533f374666320260
root@cuiyongchao:~# curl 10.0.0.20:83
<html><body><h1>it is changing,please waiting.</h1></body></html>
root@cuiyongchao:~# cat /root/htdocs/index.html
<html><body><h1>it is changing,please waiting.</h1></body></html>
root@cuiyongchao:~# echo "321">/root/htdocs/index.html
root@cuiyongchao:~# curl 10.0.0.20:83
321
root@cuiyongchao:~#

使用 bind mount 单个文件的场景是:只须要向容器添加文件,不但愿覆盖整个目录。在上面的例子中,咱们将 html 文件加到 apache 中,同时也保留了容器原有的数据。

使用单一文件有一点要注意:host 中的源文件必需要存在,否则会看成一个新目录 bind mount 给容器。

mount point 有不少应用场景,好比咱们能够将源代码目录 mount 到容器中,在 host 中修改代码就能看到应用的实时效果。再好比将 mysql 容器的数据放在 bind mount 里,这样 host 能够方便地备份和迁移数据。

bind mount 的使用直观高效,易于理解,但它也有不足的地方:bind mount 须要指定 host 文件系统的特定路径,这就限制了容器的可移植性,当须要将容器迁移到其余 host,而该 host 没有要 mount 的数据或者数据不在相同的路径时,操做会失败。

移植性更好的方式是 docker managed volume,下一节咱们讨论。

相关文章
相关标签/搜索