继上篇文章:[Kubernetes]浅谈容器网络,自己给自己挖的坑,这篇文章来谈谈容器跨主机网络.

要理解容器"跨主通信"的原理,就要来谈谈 Flannel 这个项目.

Flannel 项目是 CoreOS 公司主推的容器网络方案.提供容器网络功能的,分别是: VXLAN , host-gw , UDP .

这三种不同的实现,代表了三种容器跨主机网络的主流实现方法.这里主要讲 VXLAN 和 UDP 模式.

先从 UDP 模式讲起.

  • 假设,我有两台宿主机:
    • 宿主机 Node 1 上有一个容器 container-1 ,它的 IP 地址是 100.96.1.2 ,对应的 docker0 网桥的地址是: 100.96.1.1/24
    • 宿主机 Node 2 上有一个 container-2 , 它的 IP 地址是 100.96.2.3 ,对应的 docker0 网桥的地址是: 100.96.2.1/24
  • 我们现在的任务,就是让 container-1 访问 container-2 .

    这种情况下, container-1 容器里的进程发起的 IP 包,其源地址就是 100.96.1.2 , 目的地址就是 100.96.2.3 .由于目的地址 100.96.2.3 并不在 Node 1 的 docker0 网桥的网段里,所以这个 IP 包会被交给默认路由规则,通过容器的网关进入 docker0 网桥,从而出现在宿主机上.

    这时候,这个 IP 包的下一个目的地,就取决于宿主机上的路由规则了.此时, Flannel 已经在宿主机上创建出一系列的路由规则,以 Node1 为例,来看一下:

    # 在 Node 1 上
    $ ip route
    default via 10.168.0.1 dev eth0
    100.96.0.0/16 dev flannel0 proto kernel scope link src 100.96.1.0
    100.96.1.0/24 dev docker0 proto kernel scope link src 100.96.1.1
    10.168.0.0/24 dev eth0 proto kernel scope link src 10.168.0.2

    我们能够看到,由于 IP 包的目的地址是 100.96.2.3 ,它现在匹配不到本机 docker0 网桥对应的 100.96.1.0/24 网段,只能匹配到第二条,也就是 100.96.0.0/16 对应的这条路由规则,从而进入到一个叫作 flannel0 的设备中.这个 flannel0 设备是一个 TUN 设备( Tunnel 设备)

    在 Linux 中, TUN 设备是一种工作在三层( Network Layer )的虚拟网络设备. TUN 设备的功能非常简单,就是:在操作系统内核和用户应用程序之间传递 IP 包.

    此时, IP 包根据路由表进入 flannel0 设备后,宿主机上的 flanneld进程,就会收到这个 IP 包,然后根据目的地址将它发送给 Node2 宿主机.

    那么, flanneld 是如何知道这个 IP 地址对应的容器,是运行在 Node2 上面的呢?

    在由 Flannel 管理的容器网络中,一台宿主机上的所有容器,都属于该宿主机被分配的一个"子网",在上面举的例子中, Node1 的子网是 100.96.1.0/24 , container-1 的 IP 地址是 100.96.1.2 . Node2 的子网是 100.96.2.0/24 , container-2 的 IP 地址是 100.96.2.3

    而这些子网与宿主机的对应关系,保存在 Etcd 中.所以, flanneld 进程在处理 IP 包时,可以根据目的 IP 的地址,匹配到对应的子网,在 Etcd 中找到这个子网对应的宿主机的 IP 地址即可.

    当然,这个请求得以完成的原因是,每台宿主机上的 flanneld ,都监听着一个 8285 端口,所以 flanneld 只要把 UDP 包发往 Node2 的 8285 端口即可.接下来就是 flanneld 会直接把这个 IP 包发送给它所管理的 TUN 设备,即 flannel0 设备.,此时 Linux 内核网络栈就会负责处理这个 IP 包,根据相关规则,把这个 IP 包转发给 docker0 网桥.接下来的流程大家就清楚了(如果忘记了,可以再回去看看:[Kubernetes]浅谈容器网络), docker0 网桥会扮演二层交换机的角色,将数据包发送给正确的端口,进而通过 Veth Pair 设备到 container-2 的 Network Namespace 中.

    以上就是大概的一个流程.

    来一张图,看看会不会理解的更好一些:



    我们能够看到, Flannel UDP 模式提供的其实是一个三层的 Overlay 网络,即:它首先对发出端的 IP 包进行 UDP 封装,然后在接收端进行解封装拿到原始的 IP 包,进而把这个 IP 包转发给目标容器.

    但是UDP模式有严重的性能问题,相比于两台宿主机之间的直接通信,基于 Flannel UDP 模式的容器通信多了一个额外的步骤,即 flanneld 的处理过程.因为这个过程中,由于使用到了 flannel0 这个 TUN 设备,所以仅仅在发出 IP 包的这个过程中,就需要经过用户态与内核态之间的数据拷贝,具体如下所示:



    但是我们在进行系统级编程时,有一个非常重要的优化原则,就是要减少用户态到内核态的切换次数,并且把核心的处理逻辑都放在内核态进行.

    基于这个问题,咱们来看看 VXLAN 模式.

    VXLAN(即 Virtual Extensible LAN 虚拟可扩展局域网),是 Linux 内核本身就支持的一种网络虚拟化技术,因此 VXLAN 完全可以在内核态上实现上述封装和解封装的工作,从而通过与前面类似的"隧道"机制,构建出覆盖网络( Overlay Network ).

    VXLAN 的覆盖网络的设计思想是:在现有的三层网络上,“覆盖"一层虚拟的,由内核 VXLAN 模块负责维护的二级网络,使得连接在这个 VXLAN 二层网络上的"主机”(虚拟机或者容器都可以)之间,可以像在同一个局域网( LAN )里那样自由通信,当然,实际上这些"主机"可能分布在不同的宿主机上,甚至是分布在不同的物理机房里.而为了能够在二层网络上打通"隧道", VXLAN 会在宿主机上设置一个特殊的网络设备作为"隧道"的两端,这个设备就叫作 VTEP(即: VXLAN Tunnel End Point 虚拟隧道端点). VTEP 设备的作用,和 flanneld 进程非常相似,只是它进行封装和解封装的对象,是二层数据帧,并且这个工作的执行流程,是在内核中完成的.来看一下示意图:



    图中每台宿主机上名叫 flannel.1 的设备,就是 VXLAN 所需的 VTEP 设备,它既有 IP 地址,也有 MAC 地址.而接下来 Flannel VXLAN 模式的具体工作方式,就和实际网络中工作的方式差不多了.

    VXLAN 模式组建的覆盖网络,其实就是一个由不同宿主机上的 VTEP 设备,也就是 flannel.1 设备组成的虚拟二层网络,对于 VTEP 设备来说,它发出的"内部数据帧"就仿佛是一直在这个虚拟的二层网络上流动一样,而这也正是「覆盖网络」的含义.

    以上内容来自我学习<深入剖析Kubernetes>专栏文章之后的一些见解,有偏颇之处,还望指出.

    感谢您的阅读~

    [Kubernetes]谈谈容器跨主机网络的更多相关文章

    1. centos7下安装docker(15.5容器跨主机网络--flanneld)

      flannel是由CoreOS研究的一种覆盖网络(overlay network)网络工具,目的是帮助每一个host主机有一个完整的子网: 功能是:让集群中不同节点的主机创建的容器都有一个唯一的虚拟I ...

    2. docker容器跨主机网络overlay

      前提:已部署好docker服务服务预计部署情况如下10.0.0.134 Consul服务10.0.0.135 host1  主机名mcw510.0.0.134 host2  主机名mcw6host1与 ...

    3. centos7下安装docker(15.7容器跨主机网络---calico)

      Calico是一个纯三层的虚拟网络方案,Calico为每个容器分配一个IP,每个host都是router,把不同host的容器连接起来.与vxlan不同的是:calico不对数据包进行封装,不需要NA ...

    4. 跨主机网络概述 - 每天5分钟玩转 Docker 容器技术(48)

      前面已经学习了 Docker 的几种网络方案:none.host.bridge 和 joined 容器,它们解决了单个 Docker Host 内容器通信的问题.本章的重点则是讨论跨主机容器间通信的方 ...

    5. 安装docker跨主机网络flannel

      一.实验环境 机器 操作系统 安装服务 172.16.4.36 centos7 docker etcd flannel 172.16.4.37 centos7 docker etcd flanne ( ...

    6. Docker跨主机网络——overlay

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

    7. Docker 网络管理及容器跨主机通信

      1.网络模式 docker支持四种网络模式,使用--net选项指定: host,--net=host,如果指定此模式,容器将不会获得一个独立的network namespace,而是和宿主机共用一个. ...

    8. centos7下安装docker(15.2跨主机网络-overlay)

      为支持容器跨主机通信,Docker提供了overlay driver,使用户可以创建基于VxLAN的overlay网络.VxLAN可将二层数据封装到UDP进行传输,VxLAN提供与VLAN相同的以太网 ...

    9. overlay实现容器跨主机通信

      本节内容: Docker容器跨主机通信方案 环境信息 升级内核 安装docker 防火墙设置和开启内核转发 安装启动consul 启动Docker 创建overlay network 创建容器 测试容 ...

    随机推荐

    1. 单列集合类的根接口Collection

      Collection接口 Collection是所有单列集合的父接口,因此在Collection中定义了单列集合(List和Set)通用的一些方法,这些方法可用于操作所有的单列集合.JDK 不提供此接 ...

    2. nginx配置默认首页(index.htnl index.htm)全流程(包含遇到问题的解决)

      需求: 自己有个域名,原来直接扔在了服务器的文件夹里(根据客服人员指导),自己玩了一遍nginx的安装部署等操作之后,域名的指向发生了改变,到了nginx成功的界面. 自己抱着极大的好奇心来配置ngi ...

    3. 工具(1): 极简Word排版示例(Example by Word2013)

      文档标题 第一行写下文档的名字,居中,微软雅黑字体,三号 章节标题 每一章的标题单独一行,光标选中这行,设置为标题1 每一节的标题单独一行,光标选中这行,设置为标题2 全部章节标题设置完毕后,下一步 ...

    4. 转:SVN 版本服务器搭配全过程详解(含服务端、客户端)

      1.为什么要用VisualSVN Server,而不用Subversion? 回答: 因为如果直接使用Subversion,那么在Windows 系统上,要想让它随系统启动,就要封装SVN Serve ...

    5. Windows下的命令神器Cmder

      1. 下载地址: https://cmder.net/ 建议安装完整版本 2.设置与基本使用 1)将cmder添加到环境变量中PATH 2)添加到右键 Cmder.exe /REGISTER ALL ...

    6. nginx的概念与几种负载均衡算法

      Nginx的背景 Nginx和Apache一样都是一种WEB服务器.基于REST架构风格,以URI(Uniform Resources Identifier,统一资源描述符)或URL(Uniform ...

    7. 2018年NGINX最新版高级视频教程

      2018年NGINX最新版高级视频教程,想要的联系我,QQ:1844912514

    8. 数组中的reduce 函数理解

      第一次见到reduce 是在js 的高级程序设计中,它的意思是把一个数组减少为一个数,举的例子是数组中元素的求和.它接受一个函数作为参数,函数又有两个参数,一个是prev, 前一个值,一个是next, ...

    9. python 学习三

      list循环删除下标会出错 L = [1,1,1,2,3,4,5]#list是根据下标来取值 #下标0,1,2,3,4,5,6 循环后下标错位 输出的结果是[1,2,4],把1也取到了 #l2 = [ ...

    10. 简单记录一次getshell到进服务器的过程

      通过st2命令执行上次木马进行getshell 查看whoami,发现权限是administrator,直接net user xxx xxx123.. /add,发现拒绝访问 通过命令tasklist ...