Docker跨服务器通信Overlay解决方案(上) Consul单实例
场景
公司微服务快上线了,微服务都是用Docker容器进行部署的,在同一台主机下,把服务都部署上,注册到Nacos的IP与PORT都是内网的IP与Dockerfile中定义的端口号,看起来好像也没什么问题,通过网关去调用也是可以调通的,请注意这有一个大前提:
必须把所有服务容器部署在同一台主机上时才可以!
当服务实例没有部署在同一主机上,比如网关服务在A服务器,服务a在B服务器上,同样注册到Nacos (或其它注册中心) ,此时上报上来的都是内网的IP,那么当外部有请求进来的时候,网关通过Nacos的服务列表,找到了对应的服务a的内网IP,一调用发现调用不通
ps:内网怎么会通……
任务
微服务容器可以不在同一台服务器上,互相调用
想法
- 既然上报的是内网的IP,我直接让他上报宿主机的IP和端口呗
- 使用Docker的host网络模式
- 修改部署脚本,通过shell部署容器时,获取宿主机IP与设置的映射端口号
- 让Docker的网络互通
分析
以下分别按上边的“想法”部分来进行说明下问题
- 翻遍官方文档与Github,得出的方案又有两个:
- 固定IP端口,把宿主机IP与端口写死在配置文件中:看起来是解决了,但是问题是无法水平扩展了 ——勉强能用
- 固定网卡,防止因多网卡环境上报错误IP端口:没有用的,进入容器中
ifconfig发现内部网卡只有两个,分别是eth0与lo,对应网卡的IP就是内网IP ——还是没用
- 使用Docker的Host网络模式,你会发现IP这回上报的的确是宿主机IP,但是端口号不对啊……如果自己去通过shell使用Java参数传入待映射的端口号的话,这种情况理论上是可行的,唯一缺点是
docker ps再也直接看不到端口号了,需要额外去docker inspect——可以用 - 映射端口号可以获取,但是主机的网卡名称不同,写死后不灵活,如果有的是
eth0,有的是ens33呢?还有更多不可测的情况! ——或许可用 - 通过一些成熟的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单实例的更多相关文章
- Docker跨服务器通信Overlay解决方案(下) Consul集群
承接上文 本文基于上篇文章,详细的场景说明与分析在前篇随笔中业已记录,有兴趣可以移步 Docker跨服务器通信Overlay解决方案(上) Consul单实例 本文主旨 本文为Docker使用Cons ...
- docker跨主机通信-overlay
使用consul 1,让两个网络环境下的容器互通,那么必然涉及到网络信息的同步,所以需要先配置一下consul. 直接运行下面命令.启动consul. docker run -d -p 8500:85 ...
- Docker跨主机网络——overlay
前言 在Docker网络--单host网络一文中,我为大家总结了Docker的单机网络相关知识和操作,单机网络比较容易.本文我为大家总结Docker跨主机通信相关知识.同样本文大部分内容以CloudM ...
- 通信服务器群集——跨服务器通信Demo(源码)
对于一些基于TCP Socket的大型C/S应用来说,能进行跨服务器通信可能是一个绕不开的功能性需求.出现这种需求的场景类似于下面描述的这种情况. 假设,我们一台TCP应用服务器能同时承载10000人 ...
- 跨域通信的解决方案JSONP
在web2.0时代,熟练的使用ajax是每个前端攻城师必备的技能.然而由于受到浏览器的限制,ajax不允许跨域通信. JSONP就是就是目前主流的实现跨域通信的解决方案. 虽然在在jquery中,我们 ...
- Docker容器跨主机通信--overlay网络
一.Docker主机间容器通信的解决方案 Docker网络驱动 Overlay: 基于VXLAN封装实现Docker原生Overlay网络 Macvlan: Docker主机网卡接口逻辑上分为多个子接 ...
- Docker跨主机通信(九)--技术流ken
容器网络 在前面的博客中已经详细讲解了几种网络方案: none, host, bridge,user-defined.但是他们只是解决了单个主机间的容器的通信问题,并不能实现多个主机容器之间的通信.本 ...
- Docker 跨主机网络 overlay(十六)
目录 一.跨主机网络概述 二.准备 overlay 环境 1.环境描述 2.创建 consul 3.修改 docker 配置文件 4.准备就绪 三.创建 overlay 网络 1.在 host1 中创 ...
- Docker跨主机通信(九)
容器网络 在前面的博客中已经详细讲解了几种网络方案: none, host, bridge,user-defined.但是他们只是解决了单个主机间的容器的通信问题,并不能实现多个主机容器之间的通信.本 ...
随机推荐
- 哈夫曼编码与解码的C++实现:建立哈夫曼树、进行哈夫曼编码与解码
最近完成了数据结构课程设计,被分到的题目是<哈夫曼编码和解码>,现在在这篇博文里分享一下自己的成果. 我在设计时,在网上参考了很多老师和前辈的算法和代码,向他们表示感谢!他们的成果给了我很 ...
- TCP概述\三次握手四次挥手\报文首部,常用熟知端口号
06.26自我总结 1.TCP概述 TCP把连接作为最基本的对象,每一条TCP连接都有两个端点,这种端点我们叫作套接字(socket),它的定义为端口号拼接到IP地址即构成了套接字,例如,若IP地址为 ...
- Storm 实时读取本地文件操作(模拟分析网络日志)
WebLogProduct 产生日志类 package top.wintp.weblog; import java.io.FileNotFoundException; import java.io.F ...
- 【MySQL】(三)文件
本篇文章分析构成MySQL数据库和InnoDB存储引擎表的各种累类型文件.这些文件有以下这些. 参数文件:告诉MySQL实例启动时在哪里可以找到数据库文件,并且指定某些初始化参数,这些参数定义了某种内 ...
- vmware虚拟机三种网卡
vmware虚拟机三种网卡 vmware为我们提供了三种网络工作模式,它们分别是:Bridged(桥接模式).NAT(网络地址转换模式).Host-Only(仅主机模式). 打开vmware虚拟机 ...
- Unity3D热更新之LuaFramework篇[08]--热更新原理及热更服务器搭建
前言 前面铺垫了这么久,终于要开始写热更新了. Unity游戏热更新包含两个方面,一个是资源的更新,一个是脚本的更新. 资源更新是Unity本来就支持的,在各大平台也都能用.而脚本的热更新在iOS平台 ...
- 【Android Studio】E/memtrack: Couldn't load memtrack module (No such file or directory)【待解决】
Android Studio 又遇到了问题--如下: 06-21 07:27:57.855 3232-3232/? E/memtrack: Couldn't load memtrack module ...
- React进阶之路书籍笔记
React进阶之路: "于复合类型的变量,变量名不指向数据,而是指向数据所在的地址.const命令只是保证变量名指向的地址不变,并不保证该地址的数据不变,所以将一个对象声明为常量必须非常小心 ...
- 01-Spring Security框架学习
目录 01-Spring Security框架学习 简介 Spring Security 是什么 Spring Security 解决那些问题 Spring Security 的优点 历史背景 Spr ...
- java基本数据类型和包装类之间的区别
1.声明方式不同,基本类型不适用new关键字,而包装类型需要使用new关键字来在堆中分配存储空间: 2.存储方式及位置不同,基本类型是直接将变量值存储在堆栈中,而包装类型是将对象放在堆中,然后通过引用 ...