场景

公司微服务快上线了,微服务都是用Docker容器进行部署的,在同一台主机下,把服务都部署上,注册到Nacos的IP与PORT都是内网的IP与Dockerfile中定义的端口号,看起来好像也没什么问题,通过网关去调用也是可以调通的,请注意这有一个大前提:

必须把所有服务容器部署在同一台主机上时才可以!

当服务实例没有部署在同一主机上,比如网关服务在A服务器,服务a在B服务器上,同样注册到Nacos (或其它注册中心) ,此时上报上来的都是内网的IP,那么当外部有请求进来的时候,网关通过Nacos的服务列表,找到了对应的服务a的内网IP,一调用发现调用不通

ps:内网怎么会通……

任务

微服务容器可以不在同一台服务器上,互相调用

想法

  1. 既然上报的是内网的IP,我直接让他上报宿主机的IP和端口呗
  2. 使用Docker的host网络模式
  3. 修改部署脚本,通过shell部署容器时,获取宿主机IP与设置的映射端口号
  4. 让Docker的网络互通

分析

以下分别按上边的“想法”部分来进行说明下问题

  1. 翻遍官方文档与Github,得出的方案又有两个:

    • 固定IP端口,把宿主机IP与端口写死在配置文件中:看起来是解决了,但是问题是无法水平扩展了 ——勉强能用
    • 固定网卡,防止因多网卡环境上报错误IP端口:没有用的,进入容器中ifconfig发现内部网卡只有两个,分别是eth0lo,对应网卡的IP就是内网IP ——还是没用
  2. 使用Docker的Host网络模式,你会发现IP这回上报的的确是宿主机IP,但是端口号不对啊……如果自己去通过shell使用Java参数传入待映射的端口号的话,这种情况理论上是可行的,唯一缺点是docker ps 再也直接看不到端口号了,需要额外去docker inspect ——可以用
  3. 映射端口号可以获取,但是主机的网卡名称不同,写死后不灵活,如果有的是eth0,有的是ens33呢?还有更多不可测的情况! ——或许可用
  4. 通过一些成熟的Docker容器网络共享,但是会有一定的性能损耗 ——完全可用

概念与选型

最稳妥的办法——使用Docker网络共享,在搜索引擎的帮助下,我决定用Overlay的方式来实现效果

以下简单说下Overlay:

容器在两个跨主机进行通信的时候,是使用overlay network这个网络模式进行通信;如果使用host也可以实现跨主机进行通信,直接使用这个物理的ip地址就可以进行通信。overlay它会虚拟出一个网络比如10.0.2.3这个ip地址。在这个overlay网络模式里面,有一个类似于服务网关的地址,然后把这个包转发到物理服务器这个地址,最终通过路由和交换,到达另一个服务器的ip地址。

想要实现Overlay网络,需要引入一个K-V数据库,来保存网络状态信息,包括 Network、Endpoint、IP 等。Consul、Etcd 和 ZooKeeper 都是 Docker 支持的K-V数据库

我们这里使用 Consul,相比其它K-V数据库,Consul提供的界面化方便管理,所以这里使用Consul实现Overlay

通过让每个服务器的Docker daemon将自己的IP注册到Consul中,来共享Docker内网,这里共享的内网是Overlay网络模式的,也只有在注册的Docker环境下使用同overlay网络的容器,才能互相通讯

ps: 创建完成后,不使用overlay网络的跨服务器容器,不能ping通

小试身手

单节点的Consul实现Overlay网络,使用Docker镜像

环境说明

服务器OS 主机IP Docker版本 网卡名
Ubuntu Server 18.04 LTS 192.168.87.133 18.09.6 ens33
Ubuntu Server 18.04 LTS 192.168.87.139 18.09.7 ens33

待使用的Consul版本为1.5.2,看Docker Hub上提示漏洞目前最小的。

本测试环境适用于Systemd管理的Linux发行版

Consul没有使用非官方的progrium/consul,主要是因为这个镜像实在太老了,四年前的如果有漏洞也没能及时修复,所以自己去<hub.docker.com>去趟了遍官方的坑!

Docker跨服务器通信Overlay解决方案(上) Consul单实例的更多相关文章

  1. Docker跨服务器通信Overlay解决方案(下) Consul集群

    承接上文 本文基于上篇文章,详细的场景说明与分析在前篇随笔中业已记录,有兴趣可以移步 Docker跨服务器通信Overlay解决方案(上) Consul单实例 本文主旨 本文为Docker使用Cons ...

  2. docker跨主机通信-overlay

    使用consul 1,让两个网络环境下的容器互通,那么必然涉及到网络信息的同步,所以需要先配置一下consul. 直接运行下面命令.启动consul. docker run -d -p 8500:85 ...

  3. Docker跨主机网络——overlay

    前言 在Docker网络--单host网络一文中,我为大家总结了Docker的单机网络相关知识和操作,单机网络比较容易.本文我为大家总结Docker跨主机通信相关知识.同样本文大部分内容以CloudM ...

  4. 通信服务器群集——跨服务器通信Demo(源码)

    对于一些基于TCP Socket的大型C/S应用来说,能进行跨服务器通信可能是一个绕不开的功能性需求.出现这种需求的场景类似于下面描述的这种情况. 假设,我们一台TCP应用服务器能同时承载10000人 ...

  5. 跨域通信的解决方案JSONP

    在web2.0时代,熟练的使用ajax是每个前端攻城师必备的技能.然而由于受到浏览器的限制,ajax不允许跨域通信. JSONP就是就是目前主流的实现跨域通信的解决方案. 虽然在在jquery中,我们 ...

  6. Docker容器跨主机通信--overlay网络

    一.Docker主机间容器通信的解决方案 Docker网络驱动 Overlay: 基于VXLAN封装实现Docker原生Overlay网络 Macvlan: Docker主机网卡接口逻辑上分为多个子接 ...

  7. Docker跨主机通信(九)--技术流ken

    容器网络 在前面的博客中已经详细讲解了几种网络方案: none, host, bridge,user-defined.但是他们只是解决了单个主机间的容器的通信问题,并不能实现多个主机容器之间的通信.本 ...

  8. Docker 跨主机网络 overlay(十六)

    目录 一.跨主机网络概述 二.准备 overlay 环境 1.环境描述 2.创建 consul 3.修改 docker 配置文件 4.准备就绪 三.创建 overlay 网络 1.在 host1 中创 ...

  9. Docker跨主机通信(九)

    容器网络 在前面的博客中已经详细讲解了几种网络方案: none, host, bridge,user-defined.但是他们只是解决了单个主机间的容器的通信问题,并不能实现多个主机容器之间的通信.本 ...

随机推荐

  1. 多个数据库 migration

    More than one DbContext was found. Specify which one to use. Use the '-Context' parameter for PowerS ...

  2. 2017day1

    http://www.cnblogs.com/alex3714/articles/5465198.html 四.Python安装 windows 1 2 3 4 5 6 7 1.下载安装包     h ...

  3. jQuery甘特图/日程图/横道图/插件

    基于JQ的一款灵活高效,支持自定义拓展的甘特图/日程图插件 支持月/周/小时等显示方式 支持拖动改变时间 展开与收起 添加/删除,刷新 节假日高亮 clicked,dblClicked,changed ...

  4. 获取Oracle中表的结构

    首先cmd登录Oracle:sqlplus user/password@host/db_name 然后输入DESC table_name 可以先按住Alt,再选中字段名(块选中快捷方式)

  5. linux初学者-数据库管理MariaDB篇

    linux初学者-数据库管理MariaDB篇 MariaDB是一种数据库管理系统,是MySQL的一个分支,但是比MySQL更加优秀,可以说是MySQL的替代品.MariaDB使用的是SQL语句.下文将 ...

  6. Python基础总结之第六天开始【认识List:列表】【认识Tuple:元组】【还有他们基本的操作】(新手可相互督促)

    早,在北京的周六,热到不行~~~ 今天更新笔记列表(List).元组(Tuple)以及它们的操作方法 在列表中会经常用到List列表,前面我们认识到的有字符串,字符串数据是不能修改当前字符串里面的任意 ...

  7. el-upload自定义上传文件,并携带其余参数,且action不报错

    用el-upload组件自定义上传按钮,并携带其余参数,且必传参数action 不报错 <template> <el-col :span="6" :mode=&q ...

  8. TypeScript入门实例

    前言 TypeScript是JavaScript的超集,微软公司开发,利用es6语法,实现对js的面向对象编程思想,写代码的时候会像强类型语言一样,指定参数类型.返回值类型,类型不对会报错,但编译后还 ...

  9. Core CLR Host 源码简单分析

    在定制 CLR Host的时候,可以通过调用如下代码,来获取当前需要被宿主的程序调用入口: hr = Host->CreateDelegate( domainId, L"Main,Ve ...

  10. Mybatis整合Spring 使用

    1.继承通用的Mapper<T>,必须指定泛型<T> 例如下面的例子: public interface UserInfoMapper extends Mapper<Us ...