设为首页 收藏本站
查看: 1210|回复: 0

[经验分享] 15、《每天5分钟玩转Docker容器技术》学习--Single-host存储

[复制链接]

尚未签到

发表于 2019-2-22 07:25:03 | 显示全部楼层 |阅读模式
  ------------------------------------重要说明------------------------------------
  本文内容都是参考Cloudman系列进行学习,是个人学习过程记录,与原版不同!
  原版请参考cloudman《每天5分钟玩转Docker容器技术》Cloudman博客如下:
  https://blog.运维网.com/cloudman
  ------------------------------------重要说明------------------------------------
  Docker 为容器提供了两种存放数据的资源:
  1.storage driver 管理的镜像层和容器层。
  2.Data Volume
  3.storage driver 和 data volume 是容器存放数据的两种方式
1. storage driver

  容器由最上面一个可写的容器层,以及若干只读的镜像层组成,容器的数据就存放在这些层中。这样的分层结构最大的特性是 Copy-on-Write:
  1.新数据会直接存放在最上面的容器层
  2.修改现有数据会先从镜像层将数据复制到容器层,修改后的数据直接保存在容器层中,镜像层保持不变。
  3.如果多个层中有命名相同的文件,用户只能看到最上面那层中的文件。
  分层结构使镜像和容器的创建、共享以及分发变得非常高效,而这些都要归功于 Docker storage driver。正是 storage driver 实现了多层数据的堆叠并为用户提供一个单一的合并之后的统一视图。
  Docker 支持多种 storage driver,有 AUFS、Device Mapper、Btrfs、OverlayFS、VFS 和 ZFS。它们都能实现分层的架构,同时又有各自的特性。对于 Docker 用户来说,具体选择使用哪个 storage driver 是一个难题,因为:
  1.没有哪个 driver 能够适应所有的场景。
  2.driver 本身在快速发展和迭代。
  不过 Docker 官方给出了一个简单的答案:优先使用 Linux 发行版默认的 storage driver
  Docker 安装时会根据当前系统的配置选择默认的 driver。默认 driver 具有最好的稳定性,因为默认 driver 在发行版上经过了严格的测试。
  运行docker info查看 Ubuntu 的默认 driver,下图只截取了部分信息:

  Ubuntu 用的 AUFS,底层文件系统是 xfs,各层数据存放在 /var/lib/docker/aufs。
  Redhat/CentOS 的默认 driver 是 Device Mapper,SUSE 则是 Btrfs。
  对于某些容器,直接将数据放在由 storage driver 维护的层中是很好的选择,比如那些无状态的应用。无状态意味着容器没有需要持久化的数据,随时可以从镜像直接创建。
  比如 busybox,它是一个工具箱,我们启动 busybox 是为了执行诸如 wget,ping 之类的命令,不需要保存数据供以后使用,使用完直接退出,容器删除时存放在容器层中的工作数据也一起被删除,这没问题,下次再启动新容器即可。
  但对于另一类应用这种方式就不合适了,它们有持久化数据的需求,容器启动时需要加载已有的数据,容器销毁时希望保留产生的新数据,也就是说,这类容器是有状态的。
  这就要用到 Docker 的另一种存储机制:Data Volume
2. Data Volume
  Data Volume 本质上是 Docker Host 文件系统中的目录或文件,能够直接被 mount 到容器的文件系统中。Data Volume 有以下特点:
  1.Data Volume 是目录或文件,而非没有格式化的磁盘(块设备)。
  2.容器可以读写 volume 中的数据。
  3.volume 数据可以被永久的保存,即使使用它的容器已经销毁。
  好,现在我们有数据层(镜像层和容器层)和 volume 都可以用来存放数据,具体使用的时候要怎样选择呢?考虑下面几个场景:
  1.Database 软件 vs Database 数据
  2.Web 应用 vs 应用产生的日志
  3.数据分析软件 vs input/output 数据
  4.Apache Server vs 静态 HTML 文件
  相信大家会做出这样的选择:
  1.前者放在数据层中。因为这部分内容是无状态的,应该作为镜像的一部分。
  2.后者放在 Data Volume 中。这是需要持久化的数据,并且应该与镜像分开存放
  还有个大家可能会关心的问题:如何设置 voluem 的容量?
  因为 volume 实际上是 docker host 文件系统的一部分,所以 volume 的容量取决于文件系统当前未使用的空间,目前还没有方法设置 volume 的容量。
  docker 提供了两种类型的 volume:bind mountdocker managed volume
a) Bind mount
  bind mount 是将 host 上已存在的目录或文件 mount 到容器。
  例如 docker host 上有目录 $HOME/htdocs/index.html:

  通过-v 将其 mount 到 httpd 容器:

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



  可以看到本地的/root/htdocs/目录中的信息映射到了container目录当中;
b) Bind数据持久性
1) 在容器中添加内容
  进入容器当中进行对/usr/local/apache2/htdocs/当中添加信息,例如创建文件或目录,是否会在host主机端存在?
  答案:可以的,当把容器停止/删除也会永久存储

2) 在host主机中添加内容




  创建文件

  进入容器查看


3) 容器销毁看看对数据有什么影响



  可见,即使容器没有了,bind mount 也还在。这也合理,bind mount 是 host 文件系统中的数据,只是借给容器用用,哪能随便就删了啊。
4) 对映射文件的读写(默认可读可写)
  另外,bind mount 时还可以指定数据的读写权限,默认是可读可写,可指定为只读:



  1.对container文件进行读测试

  可以发现读,没有问题
  2.对container文件进行写测试

  可以发现写操作也没有问题
  3.对host中的文件写,对container中文件产生什么效果?
  l host端进行数据追加

  l Container端进行信息查看

  可以发现host端更改之后主机端信息也发生了改变。
5) 把相同目录挂载给多个container
  l 新建container【test_volume_bind_RO】并挂载/root/docker_file/,并且进行写入操作

  l 在container【test_volume_bind】中查看信息

  由此可见通过Bind方式可以将相同的信息挂载多个container中。
6) 以只读方式挂载
  docker run -it --name test_volume_bind_readonly -v /root/docker_file/:/root/docker_file/:rocentos



  通过上图结果可以看出来,无法进行写入操作。
c) Bind mount小结
  使用单一文件有一点要注意:host 中的源文件必须要存在,不然会当作一个新目录 bind mount 给容器。
  mount point 有很多应用场景,比如我们可以将源代码目录 mount 到容器中,在 host 中修改代码就能看到应用的实时效果。再比如将 mysql 容器的数据放在 bind mount 里,这样 host 可以方便地备份和迁移数据
  bind mount 的使用直观高效,易于理解,但它也有不足的地方:bind mount 需要指定 host 文件系统的特定路径,这就限制了容器的可移植性,当需要将容器迁移到其他 host,而该 host 没有要 mount 的数据或者数据不在相同的路径时,操作会失败。
d) docker managed volume
1) Docker manager volume基本用法
  docker managed volume 与 bind mount 在使用上的最大区别是不需要指定 mount 源,指明 mount point 就行了。

  当-d和-it参数同时使用时就不会exited
  通过 -v 告诉 docker 需要一个 docker manager volume,并将其 mount 到 /root/docker_file/
  进入container查看是否挂载成功

  可以看到container中有/root/docker_file目录,说明挂载是没有问题的;那另一个问题来了,挂载的docker manager volume是哪里来的呢?
  通过docker inspect命令进行对container【test_data_volume】查看

  其中有很多信息,我们查看Mounts部分

  Source项就是我们的docker manager volume的地址
  "Source": "/var/lib/docker/volumes/c2f90b8dfb7cd756f7b733fcf448911d08588a87eea52d24084a0674dfe4281f/_data",
  可见docker会在/var/lib/docker/volumes/目录下生成,那之后的c2f90b8dfb7cd756f7b733fcf448911d08588a87eea52d24084a0674dfe4281f/_data目录又是什么意思呢?在container中创建文件进行测试


  l 在host中目录查看

  可以看到数据实际是放到了/var/lib/docker/volumes/c2f90b8dfb7cd756f7b733fcf448911d08588a87eea52d24084a0674dfe4281f/_data的目录中的
  /var/lib/docker/volumes这个目录是docker所有docker manager volume存放目录
  c2f90b8dfb7cd756f7b733fcf448911d08588a87eea52d24084a0674dfe4281f是container的docker manager volume
  _data是 docker manager volume创建的,最终给container存放数据
  再通过一个实验进一步了解docker manager volume
2) Docker manager volume高级用法
  上个实验中是将docker manager volume挂载到了container中的空目录中,那如果挂载到非空目录中是什么情况?


  Container创建成功,说明挂载没有问题。
  l 进入容器查看/etc/sysconfig/目录下内容

  可以看到/etc/sysconfig/目录下有内容
  l 在host中查看信息
  通过docker inspect查看容器使用的是哪个docker manager volume
  docker inspect test_data_volume01

  5fbfbccdae98095f420ba2d62607e42a0d08a211f4004c236159da214129f74b

  可以发现container中的目录下的内容映射到了主机中
  注意:当使用docker manager volume映射给container中的目录,目录中有信息,那么会把当前目录中的信息复制到docker manager volume
e) Bing mount与docker manager volume对比

f) 数据共享
1) Host与constainer共享数据
  两种类型的 data volume,它们均可实现在容器与 host 之间共享数据,但方式有所区别。
  对于 bind mount 是非常明确的:直接将要共享的目录 mount 到容器。具体请参考前面 httpd 的例子,不再赘述。
  docker managed volume 就要麻烦点。由于 volume 位于 host 中的目录,是在容器启动时才生成,所以需要将共享数据拷贝到 volume 中。请看下面的例子:



  当前container中没有/root/docker_file/目录,所以无法复制
  在container中建立相应的目录


  在host中继续进行复制

  在container中查看

  docker cp 可以在容器和 host 之间拷贝数据,当然我们也可以直接通过 Linux 的 cp 命令复制到 /var/lib/docker/volumes/xxx。
2) 容器之间共享数据-Bind mount
  l 新建container【test_volume_bind_RO】并挂载/root/docker_file/,并且进行写入操作

  l 在container【test_volume_bind】中查看信息

  由此可见通过Bind方式可以将相同的信息挂载多个container中。
3) 容器之间共享数据-volume container
  volume container 是专门为其他容器提供 volume 的容器。它提供的卷可以是 bind mount,也可以是 docker managed volume。下面我们创建一个 volume container:

  我们将容器命名为 VC_data(VC 是 volume container 的缩写)。注意这里执行的是 docker create 命令,这是因为 volume container 的作用只是提供数据,它本身不需要处于运行状态。容器 mount 了两个 volume:
  1.bind mount,存放 web server 的静态文件。
  2.docker managed volume,存放一些实用工具(当然现在是空的,这里只是做个示例)。
  通过 docker inspect 可以查看到这两个 volume。

  其他容器可以通过 --volumes-from 使用 VC_data 这个 volume container:

  三个 httpd 容器都使用了 vc_data,看看它们现在都有哪些 volume,以 web01 为例:
  docker inspect web01

  进入容器验证bind mount与manger volume是否挂载成功

  Web01 容器使用的就是 vc_data 的 volume,而且连 mount point 都是一样的。验证一下数据共享的效果:
  l Host操作




  l Container【web01】验证

  l Container【web02】验证

  l Container【web03】验证

  l Host验证


  可见,三个容器已经成功共享了 volume container 中的 volume。
  总结:
  1.与 bind mount 相比,不必为每一个容器指定 host path,所有 path 都在 volume container 中定义好了,容器只需与 volume container 关联,实现了容器与 host 的解耦。
  2.使用 volume container 的容器其 mount point 是一致的,有利于配置的规范和标准化,但也带来一定的局限,使用时需要综合考虑。
4) 容器之间共享数据-data-packed volume container
  在上一节的例子中 volume container 的数据归根到底还是在 host 里,有没有办法将数据完全放到 volume container 中,同时又能与其他容器共享呢?
  当然可以,通常我们称这种容器为 data-packed volume container。其原理是将数据打包到镜像中,然后通过 docker managed volume 共享。
  用下面的 Dockfile 构建镜像:






  ADD 将静态文件添加到容器目录 /usr/local/apache2/htdocs。
  VOLUME 的作用与 -v 等效,用来创建 docker managed volume,mount point 为 /usr/local/apache2/htdocs,因为这个目录就是 ADD 添加的目录,所以会将已有数据拷贝到 volume 中。
  build 新镜像 datapacked:



  l 运行另一个容器进行验证



  容器能够正确读取 volume 中的数据。data-packed volume container 是自包含的,不依赖 host 提供数据,具有很强的移植性,非常适合 只使用 静态数据的场景,比如应用的配置信息、web server 的静态文件等。
  ------------------------------------重要说明------------------------------------
  本文内容都是参考Cloudman系列进行学习,是个人学习过程记录,与原版不同!
  原版请参考cloudman《每天5分钟玩转Docker容器技术》Cloudman博客如下:
  https://blog.运维网.com/cloudman
  ------------------------------------重要说明------------------------------------
  书籍:
  1.《每天5分钟玩转Kubernetes》
  https://item.jd.com/26225745440.html
  2.《每天5分钟玩转Docker容器技术》
  https://item.jd.com/16936307278.html
  3.《每天5分钟玩转OpenStack》
  https://item.jd.com/12086376.html



运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-675477-1-1.html 上篇帖子: NFS PersistentVolume 下篇帖子: docker模板创建镜像,容器管理
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表