目录

Docker 容器互联

1  基于Docker Volum的容器互联

1.1 Docker的文件存储

1.2Docker Volume

1.3 数据容器共享解决方案(volumes-form)


Docker 容器互联

1  基于Docker Volum的容器互联

1.1 Docker的文件存储

docker的文件系统是copy on write方式的, 文件是一层层往上叠加的, 最下的一层是只读的, 要修改的时候会复制这层只读的覆盖在只读的上面作为一层可写的, 这个时候原来的只读文件依然是存在的这是看不到了

docker 中镜像的存储就是使用的上述方式,分层结构如下

上图Docker的容器就是通过只读的镜像上面覆盖的可写层, 要想把这个可写层持久化, 就要用到之前的讲的 docker commit 了

但是镜像的层次又可以共享:

镜像是分层叠加的, 顶层的镜像依赖于底层的镜像, 容器是通过镜像 Copy On Write 一个可写层, 这个可写层 Commit 就完成了持久化又成了一个新的镜像.

Docker镜像的存储位置:

docker的镜像是分层的,一个镜像往往是多个镜像分层叠加出来的, 镜像的分层信息是存储在 Docker Graph 里面

这里记录了镜像有些那些层,   每一层的父层和大小等信息

其中 GrapDB 存储的是分层结构 , Repository 里面存储是镜像的信息, 两者结合得到镜像的分层信息

但是这些里面存储都是镜像的信息, 并不是镜像的实际存储位置,

镜像的二进制文件存储位置是. /var/lib/docker/<storage-driver>

<storage-driver> 是  Docker Graph Driver , 不同的 Docker Graph Driver 会存储在不同的目录, 比如本机采用的是 overlay2

Docker Graph Driver 是Docker 使用来管理存储镜像每层内容及可读写的容器的驱动, 目前主要有 DeviceMapper、AUFS、Overlay、Overlay2、Btrfs、ZFS 等,不同的存储驱动实现方式有差异,镜像组织形式可能也稍有不同,但都采用栈式存储,并采用 Copy-on-Write策略。且存储驱动采用热插拔架构,可动态调整。

Graph Driver 就类似于Java连接数据库的 JDBC, 只不过这个驱动是用于 docker Deamon 来对镜像个容器进行读写.

选择策略:

  • 若内核支持多种存储驱动,且没有显式配置,Docker 会根据它内部设置的优先级来选择。优先级为 AUFS > Btrfs/ZFS > Overlay2 > Overlay > DeviceMapper。若使用 DeviceMapper 的话,在生产环境,一定要选择 direct-lvm, loopback-lvm 性能非常差。
  • 选择会受限于 Docker 版本、操作系统、系统版本等。例如,AUFS 只能用于 Ubuntu 或 Debian 系统,Btrfs 只能用于 SLES (SUSE Linux Enterprise Server, 仅 Docker EE 支持)。
  • 有些存储驱动依赖于后端的文件系统。例如,Btrfs 只能运行于后端文件系统 Btrfs 上。
  • 不同的存储驱动在不同的应用场景下性能不同。例如,AUFS、Overlay、Overlay2 操作在文件级别,内存使用相对更高效,但大文件读写时,容器层会变得很大;DeviceMapper、Btrfs、ZFS 操作在块级别,适合工作在写负载高的场景;容器层数多,且写小文件频繁时,Overlay 效率比 Overlay2 更高;Btrfs、ZFS 更耗内存。

1.2Docker Volume

Docker Copy on Write

和刚刚说的一样, Docker 的写操作主要分为两种, 一个是 块级别的, 一个是文件级别的,  块级别的在修改文件的时候会把修改部分所在的块 copy 到 write层用于写, 文件级别则是直接复制真个文件到 write 层,   所以块级别能够节省空间, 但是块级别 copy的操作次数多, 文件级别直接copy 文件就会是的容器变大, 但是直接copy 文件就会大大减少copy操作的次数.

以上操作对容器中中需要频繁读写的大文件就很不利,  块级别的 COW 操作太频繁,效率低, 文件级别的又会使得容器变得很大, 比如mysql数据库的数据库存储文件.

这个时候就引入了 Volume, Volme 可以将宿主机的文件映射到容器直接操作, 不必经过 COW, 常见的高频写文件有日志系统和数据存储文件.

Vloume使用是通过docker run  的 -v 参数来实现的

[docker@VM_121_116_centos ~]$ docker run -it  -p 6379:6379 -v ~/redis/date:/data  redis /bin/bash
root@b385ca73cad3:/data# ls
appendonly.aof  root  tomcat
root@b385ca73cad3:/data# mkdir testdir
root@b385ca73cad3:/data# exit
exit
[docker@VM_121_116_centos ~]$ ll
total 580364
drwxrwxr-x 2 docker docker      4096 Mar  6 22:00 dockerFile
-rw-rw-r-- 1 docker docker 594276824 Mar  6 17:31 ideaIU-191.6014.8.exe
drwxr-xr-x 3 root   root        4096 Mar 19 21:26 redis
[docker@VM_121_116_centos ~]$ cd redis/date/
[docker@VM_121_116_centos date]$ ll
total 16
-rw-r--r-- 1 polkitd ssh_keys  443 Mar 19 21:27 appendonly.aof
-rw-r--r-- 1 polkitd ssh_keys  249 Mar 19 21:27 root
drwxr-xr-x 2 root    root     4096 Mar 19 21:32 testdir
-rw-r--r-- 1 polkitd ssh_keys  259 Mar 19 21:27 tomcat
[docker@VM_121_116_centos date]$

如命令所示 使用 -v 把宿主机的  ~/redis/date 挂载到 容器的 /data , 之后在容器的 /data  建立一个  testdir 文件夹. 之后在宿主机的 ~/redis/data 里面看见了刚刚建的文件夹. 如不指定宿主机目录, 那么docker就会在docker得volume目录中创建一个目录挂载到容器内, 当容器删除的时候, 这个目录也就随之删除了.

这样容器的 /data 目录就能避免大量的 COW 操作了, 直接进行读写.

在次看看容器信息 使用 docker inspect

[docker@VM_121_116_centos date]$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                     PORTS               NAMES
b385ca73cad3        redis               "docker-entrypoint..."   8 minutes ago       Exited (0) 7 minutes ago                       sad_murdock
e8abf8c09a26        mysql:5.6           "docker-entrypoint..."   3 weeks ago         Exited (0) 2 weeks ago                         mysql5.6
[docker@VM_121_116_centos date]$ docker inspect b385ca73cad3
[{"Id": "b385ca73cad3607f78fc87214dadf23435eebeaf5ee5551a17f160a432b08264","Created": "2019-03-19T13:31:55.437267785Z","Path": "docker-entrypoint.sh","Args": ["/bin/bash"],"State": {"Status": "exited","Running": false,"Paused": false,"Restarting": false,"OOMKilled": false,"Dead": false,"Pid": 0,"ExitCode": 0,"Error": "","StartedAt": "2019-03-19T13:31:55.783433554Z","FinishedAt": "2019-03-19T13:32:42.591792526Z"},
====================省略=================================="GraphDriver": {"Name": "overlay2","Data": {"LowerDir": "/var/lib/docker/overlay2/f2806e52d83beca84bd0bb5a137a4a70974fcecdede03e5bc1b3f5c3711619c9-init/diff:/var/lib/docker/overlay2/61d911e09963bc0e77b7020b7bdbf798a5c35dbd90514c810f3aebb6875610f7/diff:/var/lib/docker/overlay2/fdddcb2b85492183f28660470d17c554e5bdb3a01cc8089e9c2112da7eefb4d5/diff:/var/lib/docker/overlay2/9476ee9fd3b0ccad81bdfa469c4188bda49230dff3598e9018cb763a0ba683c1/diff:/var/lib/docker/overlay2/65cfb70d00faeb7477439d635dc0a6f78f4f3d7bb6c5d28b29c6428744a58ee3/diff:/var/lib/docker/overlay2/55e18ec0a5caafed7907512ee5f2dd3e4db5cd701a1adfe5f4fe3bec2911e922/diff:/var/lib/docker/overlay2/ed7f62d6e611f876fb9eb55b06653b23198a915971fd1efdffbb61c33626f759/diff","MergedDir": "/var/lib/docker/overlay2/f2806e52d83beca84bd0bb5a137a4a70974fcecdede03e5bc1b3f5c3711619c9/merged","UpperDir": "/var/lib/docker/overlay2/f2806e52d83beca84bd0bb5a137a4a70974fcecdede03e5bc1b3f5c3711619c9/diff","WorkDir": "/var/lib/docker/overlay2/f2806e52d83beca84bd0bb5a137a4a70974fcecdede03e5bc1b3f5c3711619c9/work"}},"Mounts": [{"Type": "bind","Source": "/home/docker/redis/date","Destination": "/data","Mode": "","RW": true,"Propagation": "rprivate"}],
=============================省略================================}}}
]
[docker@VM_121_116_centos date]$

可以看到 将  /home/docker/redis/date 挂载到 /data

讲了这么多怎么基于 Volume 互联呢?  我们刚刚把宿主机一个指定的目录挂载到了容器内部, 那么要是我们把这个目录挂载到多个容器有什么效果呢?

我们再次创建一个容器还是挂在这个目录

[docker@VM_121_116_centos date]$ docker run -it  -p 26379:6379 -v ~/redis/date:/data --name redistwo  redis /bin/bash
root@cf0ca7e833bb:/data# ls
appendonly.aof  root  testdir  tomcat
root@cf0ca7e833bb:/data# mkdir testdirtwo
root@cf0ca7e833bb:/data# exit
exit

为了区别刚刚那个, 我们加了 --name 参数, 进入容器发现有刚刚的建的  testdir, 我们再次建一个 testdirtwo, 再次回到上个容器看看

[docker@VM_121_116_centos date]$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                      PORTS               NAMES
cf0ca7e833bb        redis               "docker-entrypoint..."   3 minutes ago       Exited (0) 2 minutes ago                        redistwo
b385ca73cad3        redis               "docker-entrypoint..."   26 minutes ago      Exited (0) 25 minutes ago                       sad_murdock
e8abf8c09a26        mysql:5.6           "docker-entrypoint..."   3 weeks ago         Exited (0) 2 weeks ago                          mysql5.6
[docker@VM_121_116_centos date]$ docker start b385ca73cad3
b385ca73cad3
[docker@VM_121_116_centos date]$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
b385ca73cad3        redis               "docker-entrypoint..."   28 minutes ago      Up 7 seconds        0.0.0.0:6379->6379/tcp   sad_murdock
[docker@VM_121_116_centos date]$ docker exec -it b385ca73cad3 /bin/bash
root@b385ca73cad3:/data# ls
appendonly.aof  root  testdir  testdirtwo  tomcat
root@b385ca73cad3:/data#

有第二个容器创建的文件夹, 这样就容器之间的互联

对于跨越宿主机的容器互联, 可是在linux采取共享目录等技术, 或者分布式文件系统

有 iscsi nfs ceph 等

1.3 数据容器共享解决方案(volumes-form)

将本地目录挂载到容器, 在 DockerFile 中是不推荐使用的, 因为这样的容器就不可移植了.

就要不指定宿主机的目录, 使用容器存储位置的目录.

如下:

[docker@VM_121_116_centos date]$ docker run -it  -p 6379:6379 -v /data --name oneredis  redis /bin/bash
root@6636fb7d293c:/data# mkdir redis
root@6636fb7d293c:/data# ls
redis
root@6636fb7d293c:/data# exit
exit
[docker@VM_121_116_centos date]$ docker inspect oneredis

查看挂载信息结果: 将 /var/lib/docker/volumes/b4fca8f9587e906919b5c2110b5e33643315dcc73d24ca177c8122072b44ef0a/_data 挂载到了 /data

我们没有实现约定好共享目录,就不能体检知道挂载的目录,  其他容器怎么从这里读取呢?

这个时候要用 --volumes-from

示例:

[docker@VM_121_116_centos date]$ docker run -it  -p 26379:6379 --volumes-from=oneredis --name tworedis  redis /bin/bash
root@bb1d9cd3a282:/data# ls
redis
root@bb1d9cd3a282:/data# exit
exit

能看到第一个容器创建的目录

再看看容器挂载

和第一个一模一样

这样就解决的移植性的问题

一般的解决方案就是 建议一个 数据共享的管理容器, 其他业务容器 volumes-from 数据管理容器, 这样实现业务容器互联

5. Docker容器互联1--Docker存储原理和基于Docker Volum的容器互联相关推荐

  1. docker容器 eureka 集成_微服务:基于 Docker 的微服务架构之分布式企业级实践参考...

    编者按:本文分享自CSDN技术博客,作者为 FlyWine,所有权归原著者.若有不妥,联系本头条号以做必要处理. 目录 Microservice 和 Docker 服务发现模式 客户端发现模式 Net ...

  2. docker 镜像修改的配置文件自动还原_基于Docker搭建Redis一主两从三哨兵

    作者丨oscarwin来源:https://juejin.im/post/5d26b03de51d454fa33b1960 这段时间正在学习Redis和容器相关的内容,因此想通过docker搭建一套r ...

  3. RRDTool 存储原理简介——基于时间序列的环型数据库

    转自:http://www.jianshu.com/p/b925b1584ab2 RRDTool 是一套监测工具,可用于存储和展示被监测对象随时间的变化情况.比如,我们在 Windows 电脑上常见的 ...

  4. docker springboot读取配置文件_Docker从入门到掉坑(三):容器太多,操作好麻烦

    前边的两篇文章里面,我们讲解了基于docker来部署基础的SpringBoot容器,如果阅读本文之前没有相关基础的话,可以回看之前的教程. Docker 从入门到掉坑​mp.weixin.qq.com ...

  5. 个推基于Docker和Kubernetes的微服务实践

    2019独角兽企业重金招聘Python工程师标准>>> 2016年伊始Docker无比兴盛,如今Kubernetes万人瞩目.在这个无比需要创新与速度的时代,由容器.微服务.DevO ...

  6. QCon技术干货:个推基于Docker和Kubernetes的微服务实践

    2019独角兽企业重金招聘Python工程师标准>>> 2016年伊始,Docker无比兴盛,如今Kubernetes万人瞩目.在这个无比需要创新与速度的时代,由容器.微服务.Dev ...

  7. 试图将驱动程序添加到存储区_基于容器的块存储使用

    什么是块存储? 分布式存储系统,为业务与数据在集群内漂移提供了自由保障,满足企业对于不受约束的系统环境要求.同时,平台仅保存迁移被改动的数据,而非整体增加数据量,实现增量备份. 魔方云块存储的功能: ...

  8. 阿里云高性能AI服务 -- 基于Docker和EGS一键创建高性能Tensorflow分布式训练

    一. 概述 Tensorflow是目前使用最为广泛的深度学习框架之一,但是目前搭建分布式多机多卡训练比较困难,而且Tensorflow原生的分布式的性能很差,特别在云计算虚拟化环境下并行的挑战更大. ...

  9. Docker+Jenkins持续集成环境(2)使用docker+jenkins构建nodejs前端项目

    Docker+Jenkins持续集成环境(2)使用docker+jenkins构建nodejs前端项目 前文使用Docker搭建Jenkins+Docker持续集成环境我们已经搭建了基于docker+ ...

最新文章

  1. javascript检测浏览器精简版
  2. android同步服务启动,Android Service的基本用法(startService启动方式生命周期)
  3. JAVA实现概率计算(数字不同范围按照不同几率产生随机数)
  4. python爱心代码制作_Python之——爱心代码参与情人节
  5. 题目2 : 回文字符序列(区间DP)
  6. oracle11g的tnstimeout,redhat下oracle11g 配置listener.ora
  7. 频率计的交流耦合和直流耦合的区别_直流电源与交流电源是什么?直流与交流之间的区别公司新闻...
  8. 错失双节福利?这12本新书投送了解一下
  9. python学习笔记15-执行环境
  10. Kubernetes 是什么?为什么也称为 K8S?| 科普
  11. 计算机复试不机试的学校,计算机考研复试:计算机考研复试不考机试的高校
  12. 2019最新黑马视频教程分享给大家十次方乐优商城项目下载
  13. 二维数组循环赋值c语言,C/C++ 定义并赋值二维数组
  14. java+redis 实现搜索附近人功能
  15. matlab内置函数subs使用方法
  16. 数据分析入门系列教程-SVM实战
  17. Spring运行时值注入分析
  18. JAVA之bootstrap01
  19. 微信小程序图片/视频直传阿里云服务器OSS
  20. 如何设置服务器固定ip

热门文章

  1. python学习基础篇Day02(P11~~23)
  2. iOS各类马甲包被拒解决方案,iOS过包技巧
  3. 基于nodejs+vue的平面设计课程管理系统vscode
  4. M2固态硬盘断电后无法识别问题
  5. 计算机没鼠标怎么,计算机中没有鼠标如何进行拖拽
  6. 三个闭环负反馈PID调节系统:电流环、速度环和位置环的关系
  7. pmsm simulink foc 仿真_汽车雷达场景仿真方法的研究
  8. html css 鼠标手,CSS cursor 和 opacity 属性
  9. 2019年的个人总结和2020年的一些展望
  10. 淘宝价格监控erp选品,API接口数据可高并发