当您将多台服务器节点组成一个Docker集群时,需要对集群网络进行设置,否则默认情况下,无法跨主机容器互联,接下来我们首先分析一下原因。

跨主机容器互联

下图描述了一个简单的集群网络,在该集群内,有两台服务器甲和乙,每台服务器上都有两张网卡,分别连接公网和私网,两台服务器可以通过私网互联,在两个服务器节点上分别安装了Docker,并且运行了A/B/C/D 4个容器。

每台服务器节点上都有一个 docker0 网桥,这是docker启动后初始化的虚拟设备,每个容器都与docker0网桥连接,并且,容器的IP由docker自动分配。

但是这个默认情况下的网络设置不支持跨主机的容器互联,原因有两方面。

一,跨主机访问容器,没有有效路由

比如,容器A要访问容器D,请求的地址为 192.168.1.4 ,但是主机甲并不知道该将这个IP发送到那个网络设备上,主机甲也不知道主机乙内部有个容器D。

二,多个节点上的容器网段冲突

默认情况下,docker启动后初始化 docker0 网桥时,会随机分配一个IP段,那么,如果不加以协调,多个节点内的容器网络有可能会冲突,比如上图中两个网络都采用了 192.168.1.1/24 网段,在这种情况下,就会导致容器IP冲突,比如 B 和 C。

那么,只需要解决这两个问题,我们就可以实现跨主机的容器互联。

脉冲云集群网络设置

使用脉冲云可以非常轻易地完成集群网络设置。在增加集群时,只需要将集群的网络类型设置为Flannel即可。

Flannel 是一个专门用于容器网络互联的软件,脉冲云会自动地在您的服务器节点上部署Flannel实现容器互联。

设置Flannel时,可以指定容器局域网段和子网掩码,如上图所示,如果选择局域网段为 172.16.0.0/12 子网掩码为 255.255.240.0 那么,在整个集群网络中,就可以分配256个子网,IP段分别为 172.16.0.0/20172.16.16.0/20172.16.32.0/20 等等,每个子网中可以再分配 4096 个IP。每个节点的 docker0 网桥使用一个子网,每个容器使用一个子网内的IP,那么我们就可以组成下图中所示网络。

图中,主机甲的docker被分配到了 172.16.0.1/20 子网,主机已的docker被分配到了172.16.16.1/20 子网,两个子网都处在一个由Flannel管理的虚拟网络 172.16.0.0/12 中,图中以虚线代表。

到此,在Flannel的协调下,各个主机上的Docker子网IP就不会再冲突了,另外,Flannel会维护容器网络的路由规则,容器A就可以通过172.16.16.3访问容器D了,也就实现了跨主机容器互联。

Flannel维护的容器网络是一个虚拟网络,在图中的虚线也是为了抽象理解,如果你对Flannel的实现方式感兴趣,可以继续查阅Flannel的官方文档。

一些说明

· 上文中为了简化方便理解,网桥IP和子网IP段没有分开说明,在上图中,主机甲所分配的子网网段是 172.16.0.0/20 ,网段中的第一个IP 172.16.0.1 ,用作网桥设备的IP。
· 由于一个网段中第一个IP用作网桥设备IP,最后一个IP用作广播IP,所以在一个子网中,理论上可以分配 4096 个IP,但是实际上只有4094 个IP可用。
· 在设置脉冲云集群网络时,选择的集群网段请勿与已经存在的网络冲突,比如目标集群已经存在了 10.0.0.0/8网络,那么请选择 172.16.0.0/12192.168.0.0/16 作为容器网络。

组网IP

在上文Flannel网络的示意图中,有三个网络,公网 0.0.0.0/0 ,私网 10.0.0.0/8 和虚拟的容器网络172.16.0.0/12 ,强调容器网络是虚拟网络 原因是,这个网络上的数据必须以其他网络为载体,这个网络是一个二级网络。

比如,主机甲上的容器A给主机乙上的容器D发送数据,数据会被路由到 docker0 网桥上,然后数据会被Flannel通过主机甲的真实网卡,发送到主机乙的网卡上,主机乙上运行的Flannel,继续将数据转发到主机乙的docker0 网桥上,最后到达容器D。

那么如果主机有多张网卡,就像图中那样,有两张网卡分别连接公网和私网,那么我们需要为Flannel指定一个网卡/IP用以发送数据,这个IP,我们称为 组网IP。即告诉主机甲上运行的Flannel,使用哪个网卡/IP 去寻找主机乙。

使用脉冲云组建的集群,会默认使用节点的公网IP作为组网IP。那么,多个节点之间的数据通信会被发送到公网之上,除非是跨机房互联,一般情况下,我们希望节点间通过内网传输数据,以提高性能,或降低费用。

将主机添加到集群后,在主机设置页面,选择组网IP即可指定各个主机节点分别使用的组网IP

NAT设备后的集群

NAT,即网络地址转换,常用的路由器就是NAT设备,在有NAT设备的网络拓扑中,局域网内的主机只有内网IP,没有公网IP,网络如下所示:

在这种网络模型下,各个服务器节点主机都通过路由器 8.8.8.8 连接脉冲云,所以脉冲云只能获取到各个服务器的公网IP为 8.8.8.8 ,按上文所述,脉冲云会默认使用公网IP 8.8.8.8 作为Flannel的组网IP,在这种情况下,会导致Flannel组网失败,甚至Flannel会无法启动,因为主机上并不存在一个IP为 8.8.8.8 的网卡。

为解决这种问题,只需要手动设置每一个节点的组网IP即可。

某些云服务商的主机也是在NAT设备之后的,比如阿里云服务器,如果使用了阿里云的VPC网络,即使给服务器绑定了公网IP 8.8.8.8,但是从主机上看,并没有绑定公网IP的网卡设备,只有一个内网网卡,原因就是有NAT设备存在。这种情况下,也需要指定内网IP为组网IP。

如何使用Flannel搭建跨主机互联的容器网络的更多相关文章

  1. flannel无法跨主机ping通容器的解决方式

    前几天,出现了无法跨主机ping通容器的情况,导致一个node机网络中断,无法访问,排查过程如下. 首先确认,宿主机node2是可以ping通容器 [root@node2 ~]# ping 10.1. ...

  2. 实现Docker跨主机间的容器网络联通

    Server1(Server) 192.168.81.58 内核版本 3.10.0-123.el7.x86_64 Docker版本 1.12.6Server2(Agent)  192.168.81.5 ...

  3. Docker容器利用weave实现跨主机互联

    Docker容器利用weave实现跨主机互联 环境: 实现目的:实现主机A中容器1与主机B中容器1的网络互联 主机A步骤: ①下载复制weave二进制执行文件(需要internet)[root@192 ...

  4. docker跨主机通信扁平化网络的设计与实现

    端口映射.ovs. fannel,weave 1.使用网桥实现跨主机容器连接 使用Open vSwitch实现跨主机容器连接

  5. docker跨主机互联

    以下内容只是命令,原理自行百度,google或者官方查阅! 方案一.overlay Consul 三台主机为例(都要安装docker): 192.168.20.20(consul服务) 192.168 ...

  6. 用flannel实现跨主机container通信

    最近在看kubernetes,看到了网络部分,这部分是集群设计的难点,也是我比较感兴趣的部分.书上提到不同node的container之间通信主要使用flannel,openvswitch等技术,这些 ...

  7. Docker实现跨主机互联

    首先修改一台docker的默认网络段 修改配置文件/usr/lib/systemd/system/docker.service 设置生效(重载配置文件并且重启) systemctl daemon-re ...

  8. 两台主机间docker容器网络互通

    服务器1: 网络172.30.0.0/16 服务器2: 网络172.31.0.0/16 服务器1和服务器2上的docker容器网络之间是无法互通的,如果需要互通,需要做以下配置: 服务器1上执行: i ...

  9. 使用weave实现跨主机docker容器互联

    关于weave的原理不做细致的说明,如果想了解weave可以登陆官网:https://www.weave.works/ In this post,使用阿里云3台ECS服务器进行weave搭建,并测试搭 ...

随机推荐

  1. kNN(k近邻)算法代码实现

    目标:预测未知数据(或测试数据)X的分类y 批量kNN算法 1.输入一个待预测的X(一维或多维)给训练数据集,计算出训练集X_train中的每一个样本与其的距离 2.找到前k个距离该数据最近的样本-- ...

  2. python3中collections模块(转)

    https://www.cnblogs.com/zhangxinqi/p/7921941.html

  3. 微服务从代码到k8s部署应有尽有系列(十二、链路追踪)

    我们用一个系列来讲解从需求到上线.从代码到k8s部署.从日志到监控等各个方面的微服务完整实践. 整个项目使用了go-zero开发的微服务,基本包含了go-zero以及相关go-zero作者开发的一些中 ...

  4. mysql命令flush privileges命令

    修改一个用户的密码,命令如下 mysql> update user set password=password('新密码') where user='用户名'; 执行后报错: ERROR 105 ...

  5. source tree的使用

    参看博客: https://blog.csdn.net/syq8023/article/details/89844030 http://jingyan.baidu.com/album/59703552 ...

  6. laravel 公共类json库封装

    封装常用的接口响应: 创建 response.php 在app下创建如下文件下(目录及文件名可以自己设置) app/common/response.php,在内部补充如下代码: <?php /* ...

  7. vue结合antV/g6 实现网络拓扑图

    最近很多业务场景都会需要用到拓扑图,翻找了很多资料,最后选择了antV/g6,主要原因有以下几点: 1.阿里出品,所以框架的成熟性有保障 2.业务场景契合(1.规则拓扑图:2.动画流向:每个节点会有流 ...

  8. 写博客的技巧整理——基于Markdown

    我们需要掌握各种技巧,这样才能在写博客时游刃有余,以下内容觉得不错就点个赞吧 文章目录 1.目录与目录跳转 目录一(示例用勿点) 目录二(示例用勿点) 目录三(示例用勿点) 2.文字与图片 3.引用 ...

  9. 最小生成树MST算法(Prim、Kruskal)

    最小生成树MST(Minimum Spanning Tree) (1)概念 一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边,所谓一个 ...

  10. Net中委托之一

    1.委托的用法 委托是一种特殊的类型 a. 委托可以类外定义,也可以在类里面定义 b. 委托的操作步骤 1.委托的声明 2.委托的实例化 3.委托的调用 2.委托实例 amespace MyDeleg ...