前言

本讲是从Docker系列讲解课程,单独抽离出来的一个小节,带你一起 深入了解在编排工具出现前,跨宿主机通信的两大得力干将overlay、macvlay,这也会后期学好K8s做好基本功铺垫,打下一个坚实的基础。

一、overlay

Overlay网络模式相比于桥接模式的特别之处在于,它可以自定多个--subnet子网网段,只有同一网络/段中的容器才可以相互交换信息(相互通信)。

需要注意的是如果设置了多个--subnet,也需要同步设定对应个数的--gateway网关,需要确保各子网网段不重叠。

如何查看容器的子网网段,docker insect contain_name即可,当然在docker run 容器时,也可以通过--subnet 指定子网网段 。

示例(了解范畴):

docker network create -d overlay\
--subnet 192.168.0.0./16\
--subnet 192.170.0.0./16\--gateway = 192.168.0.100\
--gateway = 192.170.0.100\--ip-range=192.168.1.0/24\--aux-address="my-router=192.168.1.5" --aux-adress="my-switch=192.168.1.16" \
--aux-address="my-router=192.170.1.5" --aux-adress="my-switch=192.170.1.16" \
myoverlaynet

预告

通过对本知识点的学习,你将掌握,通过docker create 自定义网络-d自定义网络指定为overlay 网络模式,从而实现跨宿主机通信,同时可以了解一下consul镜像的使用。

注: Consul是一个分布式、高可用性和多数据中心感知工具,用于服务发现、配置和编排。Consul 支持大规模快速部署、配置和维护面向服务的架构。欲了解更多信息,请参阅 Consul架构指南。

1.docker pull 拉取consul镜像,并运行容器

docker pull consul  #拉取镜像
docker images
docker run -d -p 8500:8500 --name consul consul:latest  #启动sonsul容器
netstat -nalpt  #查看端口占用情况

2.修改主/从节点的daemon.json,并重启docker和consul服务

1)修改主节点CentOS7.9

vim /etc/docker/daemon.json

注:在修改之前,你本地的这个文件可能只有一行,大概应该是仅配了(阿里)镜像加速。可参考如下配置,前两行可以不配置,使用默认的就可以。最后三行是要配的。

{
"graph":"/var/lib/docker",
"storage-driver":"overlay",
"registry-mirrors": ["https://2jdmaxpc.mirror.aliyuncs.com"],
"cluster-store":"consul://192.168.31.100:8500",
"cluster-advertise":"192.168.31.100:2375",
"live-restore":true
}

注意:修改的时候,注意引号要是英文的,除最后一行外,前面的每行尾部都有一个英文逗号(否则docker服务将无法正常启动!!)。

首行的graph是配置docker数据(镜像、容器等)默认存储位置,可以据需修改,默认位置就是/var/lib/docker,(有人习惯修改为/data/docker)。
第二行的storage-driver,是驱动模式指定为overlay。
第三行是配置的阿里云镜像仓库地址
第四行cluster-store,是配置sonsul集群的访问地址
第五行cluster-advertise,是广播通信地址和端口。

"live-restore":true 和  –restart=always用法和意义各不相同。

配置前者的意义在于即使docker的daemon守护进程关闭,其里面的容器依然保持运行,后者是指容器在docker run 启动时,佩带了该参数,则在出现故障(内存泄露等)时,自动重启容器。

systemctl daemon-reload  #使daemon.json重新生效
systemctl restart docker #重启docker
docker ps -a   #可以看到consul的状态是Exited
docker start consul  #再次手动启动consul容器

http://192.168.31.100:8500 访问consul(这个IP地址是在上面的/etc/docker/daemon.json中配置的)

2)修改从节点CentOS8.4

vim /etc/docker/daemon.json

有了上面配置的基础,从节点配置简单一点,其他配使用默认就可以。仅配置下面的三行。需要注意的是集群广播监听的地址cluster-advertise,要配置为从节点自己的IP。

"cluster-store":"consul://192.168.31.100:8500",
"cluster-advertise":"192.168.31.130:2375",
"live-restore":true

切记:除最后一行外,每行配置末尾都有英文逗号!!!

cluster-store是集群中主节点访问地址;

cluster-advertise是当前节点的IP和广播端口,别误写成主节点的IP了,否则docker无法重启 ,错误如下: "systemctl status network.service" and "journalctl -xe" for details。

systemctl daemon-reload  #使daemon.json重新生效
systemctl restart docker #重启docker

3.在主节点创建overlay网络后,分别在主、从节点查看

1)创建前自定义网络前,分别查看主从节点的已有网络(便于对比效果)

docker network ls  #分别在主从节点执行该查代码

2)在master主节点CentOS7.9上创建自定义网络mynet

#在主节点创建自定义网络:分别指定网络模式、子网网段、网关、网卡最大传输单元 ,更详细参数见:docker network create --help
docker network create --driver overlay --ingress --subnet=172.31.0.0/16 --gateway=172.31.0.2  --opt com.docker.network.driver.mtu=1200  mynet
#docker network ls

注: com.docker.network.driver.mtu 等价于--mtu,用来设置容器网卡最大传输单元

可以看到自定义网络mynet创建成功,创建时指定网络模式为overlay

提示:如果创建时错误提示Error response from daemon: error getting pools config from store: could not get pools config from store,docker start consul 重新启动容器服务即可。

3)切回从节点CentOS8.4,查看在CentOS7.9主节点创建的网络

发现,从节点CentOS8.4上,可以看到主节点创建的mynet自定义网络,而本身并没有创建这个网络,原理就是通过/etc/docker/daemon.json中的配置集群信息的集群地址cluster-store和广播cluster-advertise来实现主从共享网络的。

4.在主节点使用自定义的overlay网络模式启动nginx,并查看其IP

docker images
docker run -d --network mynet --name nginx nginx:alpine   #主节点使用自定义网络启动
docker inspect nginx #查看网络详细信息

   主节点nginx的虚拟IP地址:172.31.0.1

5.在从节点上使用自定义的overlay网络模式开启tomcat,尝试和nginx互通

docker images
docker ps -a
docker run -d --name tomcat --network mynet -p 8080:8080 tomcat:alpine #和主节点指定同一个网络
ping -w 3 172.31.0.1  #尝试在从节点上去ping主节点的nginx的虚拟ip

发现,通过该方式(在/etc/docker/daemon.json中配置)是可以实现跨宿主机通信的。

注:该方式,在容器内部不能使用容器别名相互识别,也就是说A容器内部,不识别B容器的别名,尽管他们都共同链接一个网络mynet,但是仅能够通过各自的虚拟IP互通。如要实现容器内部互认别名,点进入点击进入。

6.在从节点上不使用自定义的overlay网络模式开启tomcat,尝试和nginx互通

exit
docker rm -f tomcat
docker run -it --name tomcat  -p 8080:8080 tomcat:alpine  /bin/bash
ping -w 3 172.31.0.1

发现从节点,在启动tomcat时不指定network为(主节点)自定义的mynet网络,也是可以ping通nginx的虚拟IP,从而实现跨宿主机通信。

7.扩展

上例配置的是overlay,实验结果表明,只要在daemon.json中配置了集群的主节点和广播节点,无论子节点容器启动时,是否用--network ,从节点都可以正常访问访问主节点,从而实现了跨宿主机通信。

但是,在跟随老师的课程学习中,老师的主节点、从节点的daemon.json中配置的网络模式是overlay2(见下图),老师的实验结果和我的实验结果是有出入的,也就是,当从节点的容器启动时不用--network mynet来指定和主节点同一个网络,那么在从节点中就无法实现跨宿主机通信(不能在从节点ping通主节点)。

奇葩的是,按老师的配置overlay2,经过反复实验,关键的几个步骤入下:

1.docker rm -f $(docker ps -qa)   #在主从节点都执行,清空容器

2.vim /etc/docker/daemon.json  #把里面的overlay修改为overlay

3.docker network rm mynet

4.systemctl daemon-reload

5.systemctl restart docker

...其他步骤和上面都一致,重新创建mynet报错时,docker ps -a 看一下consul启动没,没有启动的话,启动一下。

最终无法得到老师的答案,无论配置overlay2还是overlay,都可以实现跨宿主机通信,而不是老师的,只要从节点不用--network指定和主节点同一个网络,就不能实现跨宿主机通信。

如果你的时间和精力允许,并且对这个点比较好奇,自己可以尝试一下,看一下我们实验结果是否一致。

注:在反复实验过程中,偶尔有一次,不带--network,在从节点的容器内部不能ping通主节点nginx的虚拟ip,奇怪的是,反复,多次实验,这个仅有1次的ping不通,竟然还原不了,每次又都能ping通了。

8.小结

overlay网络模式,核心三步:

1.修改主、从节点的daemon.json,使主从节点通过ip 集群信息关联;

2.在master节点创建自定义网络mynet并指定网络模式为overlay;

3.让主、从节点的容器启动时,都指定该自定义网络mynet。

好处:在主节点创建overlay网络,从节点自动可以通过daemon.json获取主节点创建的自定义网络。

最终,只要在daemon.json中配置好了集群信息,主节点的容器启动时,指定自定义网络mynet(创建时用-d指定为overlay或者overlay2)主从节点就可以愉快的实现跨宿主机通信。

二、macvlan

该模式现在用的比较少,作为了解内容可以拓展一下知识面。

它本身不创建网络,使用的是物理机的网卡,它会导致物理机物理网卡失效,借此会创建虚拟网卡,给虚拟网卡分配网络资源,IP等。

macvlan这种技术能将一块物理网卡虚拟成多块虚拟网卡 ,相当于物理网卡施展了多重影分身之术 ,由一个变多个。

弊端:可能会耗尽物理IP地址,网段内接入的物理机越多,广播的效率/性能就会下降。

该模式,对linux系统的内核版本是有要求的,支持的版本有 v3.9-3.19 和 4.0+,比较稳定的版本推荐 4.0+。它一般是以内核模块的形式存在,我们可以通过以下方法判断当前系统是否支持:

modprobe macvlan  #如果没有返回任何信息,代表支持
lsmod | grep macvlan  #如果返回如下信息,代表支持
macvlan                19239  0 

1.据需清理掉上面的实验数据,并还原daemon.json实验前的默认配置

#如果是实验数据,可以清除,清除前请确保你明白下面命令的含义,否则不要这么清除
docker rm -f $(docker ps -qa)  #清除所有的容器
docker rmi $(docker images -qa) #清除掉所有镜像
docker network rm mynet  #在主节点清除掉自定义的网络
systemctl daemon-reload  #重启配置
systemctl restart docker  #重启docker服务

提示,我的本地daemon.json里,只有一行,是配置阿里云加速镜像时创建的。

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json .......

2.分别在主从节点上,开启网卡混合模式,开启前先ip a查看网卡信息

ip a
ip link set ens33 promisc on  #特别注意,你的物理虚拟网卡名称可能是eth0(可以在network-script里修改)
ip a

开启混合模式前,先查看一下网卡信息

分别给主从节点,开启混合网卡模式

3.分别在主从节点上,通过docker create -d 创建macvlan网络

分别在主、从节点上创建macvlan,并通过 parent指定其真身爸爸是物理网卡ens33。

#部分主机的虚拟物理网卡不是ens33,部分名称是eth0 ,(我自定义名称是myMaclan,不是myMacvlan,叫什么随意)
docker network create -d macvlan --subnet 172.30.0.0/16 --gateway 172.30.0.2 -o parent=ens33 myMaclan  docker network ls

 

注:对该命令的参数不了解的小伙伴,可以通过docker network create  --help来获悉更多的参数。细心的小伙伴发现,第一个案例该命令创建overlay网络时,使用的是--opt,此处使用的是-o,它们两个是一个命令,-o等价于--opt,使用场景主要是用于多个参数时,放到对应参数前面。它是一个map[]集合,也就是说,每个参数的前面都添加-o,则这些参数同属于一个-o的集合。

4.在主节点CentOS7.9上使用macvlan网络模式,启动nginx并指定IP

docker run -d --name nginx --network myMaclan --ip 172.30.0.3 nginx:alpine
docker ps

注意:这里自定义nginx容器的ip是172.30.0.3,下个步骤在从节点tomcat容器内会用到。

5.在从节点CentOS8.4上,启动tomcat容器时,分别暂不/指定网络模式为macvlan,ping主节点的nginx

docker images #查看镜像列表(什么镜像不重要,重要的是在容器内部,是可以实现跨宿主机通信)
docker run -it tomcat:alpine bash  #第一次进入从节点容器内部,不指定--network
ping -w 3 172.30.0.3   #尝试去ping主节点容器内的nginx的ip,发现不能ping通
exitdocker run -it --network myMaclan tomcat:alpine bash  #第二次进入从节点容器内部,指定--network
ping -w 3 172.30.0.3   #尝试去ping主节点容器内的nginx的ip,发现可以ping通
exit

注:如果你对尾部的bash感兴趣,点击进入(从文章尾部开始向上看)

6.收尾工作,关闭虚拟网卡混合模式,清除容器

docker rm -f $(docker ps -qa)   #清除容器
docker network ls
docker network rm myMaclan      #清除自定义网卡
ip link set ens33 promisc off   #取消网卡的混合模式
ip a  #验证是否已取消

7.小节

该模式的小实验比较简单,3个核心步骤:

1、主、从节点分别创建macvlan网络

2、主节点启动容器(nginx)时,指定网络模式为自定义的网络

3、从节点启动容器(tomcat)时,分别先不指定/指定自定义网络后,进入(tomcat)容器,去尝试ping主节点容器(nginx)IP。

该方式,一样可以实现跨节点通信,但只是昙花一现,满足了特定时期需求。

弊端:主从节点上都需要创建macvlan的自定义网络,容器启动时也都需要指定网络模式为macvlan,不难但是比较low稍显繁琐。

macvlan的通信原理,主从节点都需要创建完全相同的自定义网络,都通过-d或者--driver指定为macvlan,同时指定--subnet子网网段和--gateway网关,当然如果创建自定义网络时你不指定,在docker run命令时,你依然可以指定。

但是,需要注意的是,主从节点各自定义的macvan的网关和子网网段要相同,从而造成两个不同的宿主机的自定义网卡都处于同一个网段,给人的错觉就是他们就是1个小的局域网,在主从节点中的容器在docker run时,都通过--network指定这个自定义的网络。

这样,就自然而然的实现了跨宿主机通信。

总结

尽管overlay(overlay2)和macvlan都可以实现跨宿主机通信,但是相对的前者更为便捷一些,但是随着新容器编排技术的不断涌现,这些当时时髦的技术也终将被替代。就连docker官网自己推出的Docker-compose[官网](它是一个单机多容器部署工具,不支持多机)编排工具,也正在被k8s(支持多容器、多机部署)替代,后续将陆续对这些编排工具做具体介绍。

不过这些不重要,长江后浪推前浪,k8s终究是配置太多,强大的同时也太繁琐,终将会被更强大的其他替代,万变不离其宗,了解了这些底层些的知识,再学习其他编排工具时,也更加是游刃有余。

尾言

历经艰难万险(电脑不断蓝屏,重装系统),坚持善始善终,精心完成此文,一方面是为了加深自己对该知识点的理解,提升自己,另一方面也希望能够帮助后来人,在此汇总分享给大家,水平拙劣,不到之处多多指点。

本文是从 Docker入门到进阶系列里面抽离出来的内容,因为该系列是一个庞大的知识体系,一篇文章难以讲述清楚,采取分而治之的策略,也为了让原文更加层次分明。

如果你觉文章还不错,阔以点赞、留言、分享,让更多的小伙伴了解一下吧,~~(*^__^*) 嘻嘻……

附注

1、Docker容器 | Dockerfile优化

2、Docker容器的生命周期 | kill和stop | pause 和 unpause

3、 Docker容器五种(3+2)网络模式 | bridge模式 | host模式 | none模式 | container 模式 | 自定义网络模式详解

4、Docker外部浏览器访问容器 | 容器访问容器 | 访问容器的常用5种方式 | -p -P 详解

5、Docker容器之间单/双向通信 |--link /自定义网络实现互认容器别名

6、Docker容器间数据挂载与共享 | 远程共享&挂载数据卷

Docker学习:跨宿主机通信 | overlay和macvlay(理论+实战篇)相关推荐

  1. docker实现跨宿主机的容器之间网络互联

    背景:最近闲来无事,想到之前开发提出的问题不用k8s那套网络插件如何实现跨宿主机的容器之间网络互联,顺便复习下iptables知识点. docker实现跨宿主机的容器之间网络互联 一. 环境介绍 二. ...

  2. DOCKER容器与宿主机同网段互相通信

    相关阅读: Docker容器时间与宿主机同步 使用Docker搭建WordPress博客 Docker私有仓库搭建及镜像删除 Docker镜像的导入和导出 在Docker上部署Ambari 博主最近在 ...

  3. docker容器的网络配置,允许docker可以被宿主机以外的其它主机访问以及局域网内可以直接访问docker容器ip

    自从Docker容器出现以来,容器的网络通信就一直是被关注的焦点,也是生产环境的迫切需求.容器的网络通信又可以分为两大方面:单主机容器上的相互通信,和跨主机的容器相互通信. 一.端口映射(局域网,外网 ...

  4. Doker : Docker 容器与宿主机共享文件

    1.美图 2.概述 docker run-it -v /宿主机绝对路径目录:/容器内目录 镜像名 这样的话,你无论在哪个地方创建文件,都能在对方目录下看到数据 绑定成功的标志

  5. Docker 容器与宿主机网段冲突导致网络无法 ping 通的解决方案

    Docker 容器与宿主机网段冲突导致网络无法 ping 通的解决方案 参考文章: (1)Docker 容器与宿主机网段冲突导致网络无法 ping 通的解决方案 (2)https://www.cnbl ...

  6. docker如何查看宿主机到容器端口映射

    docker/Docker如何查看宿主机到容器端口映射关系 背景 前些天的时候, 在定位问题时发现docker emqx 连接websocket (8083)端口出现异常. 经过很长时间定位, 才发现 ...

  7. CentOS安装etcd和flannel实现Docker跨物理机通信

    1.安装etcd yum install etcdsystemctl stop etcd systemctl start etcd systemctl status etcd 查看etcd是否启动成功 ...

  8. 利用 Docker 在不同宿主机做 CentOS 系统容器 | 原力计划

    作者 | 于先森2017 责编 | 伍杏玲 出品 | CSDN博客 最近公司新接到一个项目,惯例是通过技术架构.业务需求.用户量还有以往的经验大概评估出一份资源配置表格提供给客户,让客户参考采购的服务 ...

  9. docker容器和宿主机的主机名映射失败

    一.为什么将 Oracle 部署在 docker容器中 我们首先通过 docker 安装了 oracle11g 版本的 Oracle 数据库--不要问我为什么通过 docker 安装数据库,正确做法或 ...

最新文章

  1. 一个fork短码的扩展版本
  2. java.lang.SecurityException Permission Denial opening provider ngyb.createdatabase.AccountProvider
  3. Linux下批量kill掉进程
  4. 【模型解读】network in network中的1*1卷积,你懂了吗
  5. TypeScript API Reflect.getMetadata 返回 undefined 的解决办法
  6. CSS3实现Loading动画特效
  7. sealer背后实现整个集群一键交付的奥秘 | 龙蜥技术
  8. 6内置数据结构_set
  9. 校园表白墙-带后台源码
  10. Linux系统CentOS 7配置Spring Boot运行环境
  11. Android进阶--android自动化测试python+uiautomator
  12. PHP经常用到的方法,[PHP]经常用到的实用函数集合第1/2页
  13. 驱动该如何入门 关于file_operations和Linux设备模型
  14. 微信小程序——事件绑定
  15. NiCad克隆检测工具
  16. logback MDC线上问题快速定位神器
  17. Internet时间自动同步后,计算机系统时间比北京时间不能同步一致
  18. 微信支付的服务器配置url超时,微信H5支付商家存在未配置的参数,请联系商家解决的...
  19. 计算机简历800字,我的简历作文800字
  20. 微信小程序 - 婚礼邀请函

热门文章

  1. python的格式化控制符_python格式化输出,基本运算符,流程控制主if
  2. 【深度强化学习】《强化学习》Monte-Carlo 算法代码实现
  3. 2015年蓝桥杯C/C++组B组第三题:三羊献瑞
  4. 装备系统的合成-算法题
  5. 【MBTI】INFJ人格报告书
  6. React中的定时器-js
  7. Unity ~2D精灵动画制作
  8. 计算各种图形的周长 python java
  9. mupdf添加图片水印_如何在图片上加上水印
  10. 菱角图形输出c语言,CDR将多边形/图形的角度变圆?CDR制作圆角图形的三种方法