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的网络互通

分析

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

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的主机都不能同hostname,可以使用

$ sudo hostnamectl set-hostname your-new-hostname

同hostname会导致同名的主机docker无法互相通信

动手做

准备Consul使用镜像在133服务器上启动,所以可以先配置下Docker daemon的启动参数指向133服务器

分别修改133、139两台服务器的docker.service

$ ifconfig
#已经去除干扰网卡,记录网卡名为ens33
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.87.133  netmask 255.255.255.0  broadcast 192.168.87.255
        inet6 fe80::20c:29ff:fe02:e00a  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:02:e0:0a  txqueuelen 1000  (Ethernet)
        RX packets 156739  bytes 233182466 (233.1 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 45173  bytes 2809606 (2.8 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

$ vim /etc/docker/daemon.json

保存退出.

  • cluster-store:配置的Consul的leader地址,单体直接写,其它软件注意协议
  • cluster-advertise: 指定监听的网卡和端口,也可以指定接收订阅消息的IP:PORT

还有一种是直接修改docker.service的,参考如下:

$ cd /etc/systemd/system/multi-user.target.wants
$ sudo vim docker.service

找到ExecStart= 字眼,在此行末尾添加如下代码

--cluster-store=consul://192.168.87.133:8500 --cluster-advertise=ens33:2375

效果如下:

操作效果与以上方法保持一致

接着执行命令,重启docker服务,另一台服务器操作方式相同,注意网卡名称

$ sudo systemctl daemon-reload && sudo systemctl restart docker

在133服务器启动Consul服务

docker run -d --network host -h consul --name=consul --restart=always -e CONSUL_BIND_INTERFACE=ens33 consul:1.5.2

用主机模式的原因是防止有些端口没有映射出来,还有就是想让Consul识别外部网卡的方式只能host模式,下面给个非host的方式

$ docker run -di  -h consul -p 8500:8500 --name=consul consul:1.5.2

创建Docker overlay共享网络

$ docker network create -d overlay my_overlay

这里与普通创建网络不同在于指定了overlay模式的网络,-d也可以写为--driver

访问Consul的页面,如我的是192.168.87.133:8500

我们的配置在Key/Value处,

点击docker -> nodes

出现上边的两个节点,分别是两个docker daemon (守护进程) 注册的值

测试

新建两个centos的容器分别在两台服务器上,使用overlay 我们刚才创建的网络

133服务器

$ docker run -di --network my_overlay --name mycentos1 centos:7

139服务器

$ docker run -di --network my_overlay --name mycentos2 centos:7

--net全拼为--network--开头的可不加=

查看133服务器mycentos1容器的IP

$ docker inspect -f "{{ .NetworkSettings.Networks.my_overlay.IPAddress}}" mycentos1
10.0.1.2

查看139服务器mycentos2容器的IP

$ docker inspect -f "{{ .NetworkSettings.Networks.my_overlay.IPAddress}}" mycentos2
10.0.1.3

分别从133服务器ping 139服务器的mycentos2的内网IP

反过来ping也是一样的,但是并不是让我们通过外部去访问的,通过同一overlay网络的容器就可以,不信我们作如下尝试

133服务器

$ docker exec -it mycentos1 bash
# ping 10.0.1.3

访问得通,没有丢包,反过来也是一样的,篇幅有限就不试验了

这起码说明,现在的服务的确已经网络互通了,下篇文章我们来搞下生产用的集群方式

引文

技术漫谈 | docker overlay网络实现

Docker容器之overlay网络

Docker跨主机网络——overlay

Day22:介紹 Docker 的 Network (三)

Consul KV

Docker Hub Consul

Github docker-library/docs

Github docker-consul

本文系Hellxz学习与实践文章,禁止布布扣、码迷等第三方爬虫网站爬取

到此这篇关于Docker跨服务器通信Overlay解决方案(上)之 Consul单实例的文章就介绍到这了,更多相关Docker Overlay网络内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 对docker中的overlay式网络详解

    翻译自docker官方文档,原文:https://docs.docker.com/network/overlay/ overlay(覆盖)式网络会在多个docker守护进程所在的主机之间创建一个分布式的网络.这个网络会覆盖宿主机特有的网络,并允许容器连接它(包括集群服务中的容器)来安全通信.显然,docker会处理docker守护进程源容器和目标容器之间的数据报的路由. 当你初始化一个集群(swarm)或把一个docker宿主机加入一个已经存在的集群时,宿主机上会新建两个网络: 一个叫ingre

  • Docker跨主机网络(overlay)的实现

    一.Docker 跨主机通信 Docker跨主机网络方案包括: docker 原生的 overlay 和 macvlan. 第三方方案:常用的包括 flannel.weave 和 calico. docker 通过 libnetwork 以及 CNM 将上述各种方案与docker集成在一起. libnetwork 是 docker 容器网络库,最核心的内容是其定义的 Container Network Model (CNM),这个模型对容器网络进行了抽象,由以下三类组件组成: 1.1 Sandb

  • docker中搭建overlay 网络实验环境

    为支持容器跨主机通信,Docker 提供了 overlay driver,使用户可以创建基于 VxLAN 的 overlay 网络.VxLAN 可将二层数据封装到 UDP 进行传输,VxLAN 提供与 VLAN 相同的以太网二层服务,但是拥有更强的扩展性和灵活性.有关 VxLAN 更详细的内容可参考 CloudMan 在<每天5分钟玩转 OpenStack>中的相关章节. Docerk overlay 网络需要一个 key-value 数据库用于保存网络状态信息,包括 Network.Endp

  • Docker overlay 网络搭建的方法

    Overlay网络是指通过在现有网络上叠加一个软件定义的逻辑网络,最大程度的保留原有网络,通过定义其上的逻辑网络,实现业务逻辑,解决原有数据中心的网络问题. 快速开始 Docker跨主机网络方案 docker 原生 overlay macvlan 第三方方案 flannel weave calico 之前介绍了Consul搭建集群,所以在此直接选用docker自带的overlay方案来做,和Consul完美结合. 环境准备 参考之前的一篇<Consul 搭建集群>准备三台虚机. ip n1 1

  • Docker跨服务器通信Overlay解决方案(上)之 Consul单实例

    目录 场景 任务 想法 分析 概念与选型 小试身手 环境说明 注意事项 动手做 测试 引文 场景 公司微服务快上线了,微服务都是用Docker容器进行部署的,在同一台主机下,把服务都部署上,注册到Nacos的IP与PORT都是内网的IP与Dockerfile中定义的端口号,看起来好像也没什么问题,通过网关去调用也是可以调通的,请注意这有一个大前提: 必须把所有服务容器部署在同一台主机上时才可以! 当服务实例没有部署在同一主机上,比如网关服务在A服务器,服务a在B服务器上,同样注册到Nacos (

  • Docker容器跨主机通信overlay网络的解决方案

    目录 一.Docker主机间容器通信的解决方案 二.Docker Overlay Network 三.使用键值存储搭建Docker主机集群 4.1 系统环境 4.2 安装Consul 4.3 节点配置Dockre守护进程连接Consul 4.4 查看consul 中的节点信息 4.5 创建overlay网络 4.6 使用overlay网络启动容器 一.Docker主机间容器通信的解决方案 Docker网络驱动 Overlay: 基于VXLAN封装实现Docker原生Overlay网络 Macvl

  • Docker跨主机容器通信overlay实现过程详解

    同样是两台服务器: 准备工作: 设置容器的主机名 consul:kv类型的存储数据库(key:value) docker01.02上: vim /etc/docker/daemon.json { "hosts":["tcp://0.0.0.0:2376","unix:///var/run/docker.sock"], 这行改了要修改自己的docker配置文件 "cluster-store": "consul://10

  • 详解Docker容器跨主机通信的方法

    默认情况下Docker容器需要跨主机通信两个主机节点都需要在同一个网段下,这时只要两个Docker容器的宿主机能相互通信并且该容器使用net网络模式,改实现方式为网桥模式通信: 除此之外我们还可以通过使用第三方工具为不同主机间创建一个覆盖网络,使之能够 跨节点通信 ,这里将使用Flanneld实现: 安装etcd 创建 cat /etc/etcd/etcd.conf文件 # [member] ETCD_NAME=infra1 ETCD_DATA_DIR="/var/lib/etcd"

  • Docker容器跨主机通信中直接路由方式详解

    概述 就目前Docker自身默认的网络来说,单台主机上的不同Docker容器可以借助docker0网桥直接通信,这没毛病,而不同主机上的Docker容器之间只能通过在主机上用映射端口的方法来进行通信,有时这种方式会很不方便,甚至达不到我们的要求,因此位于不同物理机上的Docker容器之间直接使用本身的IP地址进行通信很有必要.再者说,如果将Docker容器起在不同的物理主机上,我们不可避免的会遭遇到Docker容器的跨主机通信问题.本文就来尝试一下. 方案原理分析 由于使用容器的IP进行路由,就

  • 聊聊docker跨主机之间容器通信问题

    目录 一.环境信息 二.具体实践 1.在testa主机上创建docker桥接网络 2.在testb主机上创建docker桥接网络 3.在testa主机中你自定义的网段选取任意IP地址作为你要启动容器IP testb主机中你自定义的网段选取任意IP地址作为你要启动容器IP 4.进入testa主机中的docker 进入testb主机中的docker 5. 配置路由表 添加路由规则 6测试跨主机容器互ping 一.环境信息  主机名 宿主机IP 容器分配网段 启动容器的IP testa 192.168

  • springmvc实现跨服务器文件上传功能

    本文实例为大家分享了springmvc实现跨服务器文件上传功能的具体代码,供大家参考,具体内容如下 1.创建一个新的maven工程并且部署tomcat,用于做图片服务器并且在webapp下创建uploads文件 2.在应用服务器上的pom.xml导入坐标 <!--跨服务器上传文件--> <dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-core</artifa

  • springMVC+jersey实现跨服务器文件上传

    本文实例为大家分享了springMVC+jersey实现跨服务器文件上传的具体代码,供大家参考,具体内容如下 1.首先添加所需要的jar包 2.在springMVC的配置文件中添加文件上传解析器 <!-- 文件上传的解析器 --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> &l

  • SpringMVC图片文件跨服务器上传

    图片文件跨服务器上传(我使用的公司云桌面作为上传服务器,自己的笔记本作为存储服务器测试的) 一.上传服务器: 1.pom文件(使用jersey插件) <!-- 上传组件包 --> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.1</version&g

随机推荐