继上篇文章:[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. 一文说透容器跨主机网络

    文章目录 一.Flannel 1.UDP 2.VXLAN (1)VXLAN核心流程总结 (2)VTEP隧道通信流程详解 [1]封装 inner Ethernet header(依据VTEP IP查MA ...

  2. 跨主机网络-UDP解析

    容器跨主机网络-UDP解析 1. 容器跨主机网络的问题 上一节描述了同一宿主机下容器访问宿主机或其他容器的方式,默认docker配置下,不同宿主机之间的容器网络没有任何关联,所以无法做到跨主通信.要解 ...

  3. Docker 网络模型/overlay 跨主机网络

    之前说了overylay fs,但是运行一个容器进程还需要最后一步,就是它的网络配置. docker本身在创建之初就有自己的网络驱动器,叫container network manager,CNM,本 ...

  4. docker跨主机网络——overlay与macvlan

    docker的跨主机网络 前言 这篇文件分两种方式介绍docker跨主机通信,overlay和macvlan,macvlan的方式给大家做个参考,生产环境下不推荐大家使用这种方式

  5. K8S探索之Service+Flannel本机及跨主机网络访问原理详解

    简介 在上篇中,我们部署了我们的应用,但我们访问是直接在应用所在的容器,使用IP+Port的方式直接访问的,style不够k8s,本篇文章我们将使用service和跨主机访问 内容概览 目前我们的应用 ...

  6. Docker 跨主机网络方案分析

    PS:文章首发公众号,欢迎大家关注我的公众号:aCloudDeveloper,专注技术分享,努力打造干货分享平台,二维码在文末可以扫,谢谢大家. 上篇文章介绍了容器网络的单主机网络,本文将进一步介绍多 ...

  7. Docker网络——实现容器间通信、容器与外网通信以及容器的跨主机访问

    前言 自定义网络 建议使用自定义的网桥来控制哪些容器可以相互通信,还可以自动DNS解析容器名称到IP地址.Docker提供了创建这些网络的默认网络驱动程序,你可以创建一个新的Bridge网络,Over ...

  8. docker容器4:docker网络类型+跨主机访问

    文章目录 一.网络类型介绍 1.查看支持网络类型 2.测试使用种类网络类型 3.网络类型设置 3.1 bridge 3.2 host 3.3 none 3.4创建自定义网络 4.Docker跨主机网络 ...

  9. Kubernetes Docker 容器网络终极之战(十四)

    与 Docker 默认的网络模型不同,Kubernetes 形成了一套自己的网络模型,该网络模型更加适应传统的网络模式,应用能够平滑的从非容器环境迁移到 Kubernetes 环境中. 自从 Dock ...

最新文章

  1. SoC(System on chip)与NoC(network-on-chip)
  2. Vista下的Asp.net Mvc安装
  3. linux服务器调用端口超时,Linux服务器可以ping,但是telnet端口超时,网站wget超时,访问超时的解决办法...
  4. opencv python 生成画布_用Python做自己的2020专属Flag动图
  5. 6.4高级查询:分组查询 链接查询 子查询 联合查询
  6. 05--MySQL自学教程:DDL(Data Definition Language:数据库定义语言)操作数据库(一)
  7. 封装各种生成唯一性ID算法的工具类
  8. 计算机控制系统从本质上看,计算机控制系统测试题.doc
  9. 前端学习(3202):函数式组件
  10. 第一个 Rails App 从安装到创建(windows版本)
  11. javafx项目_为什么选择javafx?
  12. 小米11渲染图曝光:屏下摄像头技术现身还有方形5摄相机模组
  13. Codeforces Good Bye 2015 D. New Year and Ancient Prophecy 后缀数组 树状数组 dp
  14. 字典表该如何写查询语句?
  15. 计算机维修轿车,解决方案:轿车电脑故障维修两例
  16. 网络设计:搭建校园网(组网工程课设)【译】
  17. Linux 操作系统原理 — PCIe 总线标准
  18. 360断网急救箱显示为dns配置问题解决
  19. python风格变换图片_图片风格转换--深度学习介绍
  20. 笔记本键盘帽脱落解决

热门文章

  1. 正规式到nfa dfa java_正规式与正规集,DFA与NFA
  2. 麒麟子Cocos Creator 3D研究笔记九:初尝Shader并实现边缘光(RimLight)
  3. zynq sdk 开发之通过 BRAM 进行 PL 与 PS 的数据交互
  4. 51单片机蜂鸣器播放音乐C语言程序实例,基于proteus的51单片机仿真实例八十八、用蜂鸣器播放一段音乐应用实例...
  5. 抖音跳转能力总结攻略
  6. 【LayUi】之入门
  7. 学习淘淘商城第四十八课(商品搜索功能Controller实现)
  8. 我的创作纪念日(一周年)
  9. 基于appinventor开发阿里云物联网Android软件(胎教级包懂教程)
  10. selenium加载cookie报错问题:selenium.common.exceptions.InvalidCookieDomainException: Message: invalid cooki