参考

补充内容

  • 本篇文章主要为入门理解,可能部分有些误差或不够全面,若想更详细的内容,可以查看下面的文章
  • 【k8s网络】梳理cni发展脉络-CSDN博客

calico几种模式对比

注意 Calico 不会有任何网桥!!!

会为每一个容器创建一个Veth pair 设备,一端在容器内,一端设置到宿主机上

数据的转发,靠 Calico 维护的路由规则

模式数据包封包优点缺点
vxlan封包, 在vxlan设备上将pod发来的数据包源、目的mac替换为本机vxlan网卡和对端节点vxlan网卡的mac。外层udp目的ip地址根据路由和对端vxlan的mac查fdb表获取只要k8s节点间三层互通, 可以跨网段, 对主机网关路由没有特殊要求。各个node节点通过vxlan设备实现基于三层的”二层”互通, 三层即vxlan包封装在udp数据包中, 要求udp在k8s节点间三层可达;二层即vxlan封包的源mac地址和目的mac地址是自己的vxlan设备mac和对端vxlan设备mac。需要进行vxlan的数据包封包和解包会存在一定的性能损耗
ipip封包,在tunl0设备上将pod发来的数据包的mac层去掉,留下ip层封包。 外层数据包目的ip地址根据路由得到。只要k8s节点间三层互通, 可以跨网段, 对主机网关路由没有特殊要求。需要进行ipip的数据包封包和解包会存在一定的性能损耗
bgp不需要进行数据包封包不用封包解包,通过bgp协议可实现pod网络在主机间的三层可达, k8s节点不跨网段时和flannel的host-gw相似;
支持跨网段, 满足复杂的网络架构
跨网段时,需要主机网关路由也充当BGP Speaker能够学习到pod子网路由并实现pod子网路由的转发

其中Vxlan模式和ipip模式都可以设置crosssubnet, 即在跨网段的k8s节点的pod间通信时才使用vxlan或ipip进行封包, 同一网段的8s节点的pod间通信则直接使用bgp模式。使用同网段内的k8s节点作为BGP Speaker全互联交换各自的pod子网路由实现互通, 避免封包。

性能比较

fannel三种模式效率calico 模式
UDP(已废弃)性能较差,封包解包涉及到多次用户态和内核态交互
VXLAN性能较好,封包解包在内核态实现,内核转发数据,flanneld负责动态配置ARP和FDB(转发数据库)表项更新类似IPIP
host-gw性能最好,不需要再次封包,正常发包,目的容器所在的主机充当网关
flanneld 负责主机上路由表的刷新
类似 BGP

img

vxlan

什么是VXLAN?
VXLAN,即Virtual Extensible LAN(虚拟可扩展局域网),是Linux本身支持的一网种网络虚拟化技术。VXLAN可以完全在内核态实现封装和解封装工作,从而通过“隧道”机制,构建出覆盖网络(Overlay Network)

VXLAN的设计思想是:
在现有的三层网络之上,“覆盖”一层虚拟的、由内核VXLAN模块负责维护的二层网络,使得连接在这个VXLAN二层网络上的“主机”(虚拟机或容器都可以),可以像在同一个局域网(LAN)里那样自由通信。
为了能够在二nfcu网络上打通“隧道”,VXLAN会在宿主机上设置一个特殊的网络设备作为“隧道”的两端,叫VTEP:VXLAN Tunnel End Point(虚拟隧道端点)

简而言之:
- 不需要关注 VTEP 与 VTEP 设备之间的通信(如何跨网段,如何进行三层网络的连通)
- 只需关注,将数据包传给当前 VTEP 设备后,如何获取目的 VTEP 的 MAC 地址,完成二层通信

基于三层的”二层“通信

三层 —— 指的是实际物理网络架构

”二层“通信 —— 指的是,需要维护「MAC 地址级别的信息」,即「虚拟IP」与「MAC 地址」的映射关系

基于三层的”二层“通信 —— 可实现跨网段的 Pod 通信

  • 基于三层 —— 指的是利用三层网络进行跨网段通信 —— 也就是不同 VTEP 设备之间的通信 —— 这个通信的路径不需要进行考虑(VTEP 设备会自动处理)
  • ”二层“通信 —— 主要是需要知道「目的 VTEP 设备的 MAC 地址」(类似与 ARP 获得 MAC 地址),之后完成通信
    • 知道对方 MAC 便可直接完成通信, 这种类似二层通信
    • 但是主要是 —— 如何由「目的容器 IP 」知道「目的 VTEP 设备的 MAC 地址」?传统网络是通过 ARP 协议
    • 对于 Calico 则是通过「路由规则」
      • 维护「每个 k8s 节点上 Pod 网段」 与 「节点上 VTEP 设备的 MAC 地址」的对应关系
      • 因此知道 「目的容器 IP 」—— 便可判断在哪个「Pod 网段」—— 从而知道对应的「VTEP 设备的 MAC 地址」

通信总体流程解析

基础封包解包知识

封包是「自顶向下的」,解包是「自底向上的」

简单描述封包:

  1. 原始数据 —— 应用发送的一些数据 —— 基础数据单元
  2. 传输层封包 —— UDP、TCP 协议等 —— 添加「源、目的端口」,可以称之为「数据段」
  3. 网络层封包 —— IP 协议 —— 添加 「源、目的 IP」,可以称之为「数据包」
  4. 链路层封包 —— 以太网协议 —— 添加「源、目的 MAC 地址」,可以称之为「数据帧」

简单描述解包(反着来):

  1. 链路层解包 —— 拆去 MAC 包头 —— 传给网络
  2. 网络层解包 —— 拆去 IP 包头 —— 传给传输层
  3. 传输层解包 —— 插曲 UDP/TCP 包头 —— 传到对应「目的端口」的应用
  4. 目的应用 获得真正数据

img

VXLAN 和 UDP 包结构

对比之下,可以看出:

  1. 外层以太网头(就是源、目的MAC地址)—— 相同 —— UDP 也具有,这里没画出来而已

  2. 外层 IP 头 —— 都具有

  3. UDP 头 —— 都具有

  4. 因此不同的就是后面几部分 「VXLAN头,内侧以太网头、内层 IP 头、负载」,「UDP数据」

    • 用 UDP 协议理解就是, 「VXLAN头,内侧以太网头、内层 IP 头、负载」 —— 相当于「UDP数据」

      • 相当于用 UDP 封装一个 「VXLAN 数据包」
      • 这里简单将 「VXLAN头,内侧以太网头、内层 IP 头、负载」 称为 「VXLAN 数据包」 —— 这是下文的基础
      • 其实应该是整体(包含外层以太网头等)称为「VXLAN 数据包」
    • 所以可以简单认为 「VXLAN协议相比于 UDP 多了更多控制功能,毕竟相当于将 UDP数据 分了 四层」

    • 那么这么分配的原因是为了什么呢?

      • 原因就是:宿主机的「虚拟IP」(如 Pod IP,容器IP等)无法利用「基础物理网络」进行「跨网段通信」

    • 这四部分的作用是什么呢?

      • 因为这么分配后,UDP 设备不能识别,所以需要一个新设备部署到宿主机上 —— 「VTEP设备」
      • 宿主机支持 VXLAN 协议,因此通过 「VXLAN头」知道该传输给哪个「VTEP设备」
      • 「VTEP设备」发现「内层以太网头」(即MAC地址)是自己,进行拆除
      • 之后「VTEP设备」将「内层 IP 头、负载」传给下一个「网络处理设备」
        • 这个「网络处理设备」由不同网络方案进行实现,calico就是「虚拟路由器」,fannel 就是「网桥」
        • 之后这个「网络处理设备」进行解包,将真正的「负载」数据传输给应用

img

img

通信总体流程

我们结合这个 VXLAN 数据包结构进行讲解

下文基于这样讲解

  • 简单将 「VXLAN头,内侧以太网头、内层 IP 头、负载」 称为 「VXLAN 数据包」

img

上面的「目的容器 IP 」,在这用「目的 Pod IP」这个概念

因为在 k8s 中,Pod 是最基础的运行单元,Pod 封装了容器,你可以把 「目的 Pod IP」近似看做「目的容器 IP 」

  1. 通过「目的 Pod IP」—— 得知「目的 VTEP 设备的 MAC 地址」 —— 「源 VTEP 设备」根据得到的信息构建 Vxlan 数据包

    • 如何得知呢?

    • calico 会维护 「目的 Pod IP 网段」 —— 「目的 VTEP 设备的 MAC 地址」的路由条目,因此进行匹配后便可得知

    • fannel 会维护一个数据库,存储着 「目的 Pod IP 网段」 —— 「目的 VTEP 设备的 MAC 地址」的信息,因此也可以得知

    • 因为这个过程我们需要管理,但需要「维护 Pod IP 与 VTEPS 设备 MAC 地址 的映射关系」,也就类似二层通信中的 ARP 广播

      所以我们称之为 —— ”二层“通信

  2. 之后「源 VTEP 设备」 —— 会将此「 Vxlan 数据包」进行「UDP封装」,其中「 Vxlan 数据包」会视为「UDP数据包的基础数据信息」

    • 封装 UDP 数据包 —— 用于三层网络通信,即跨网段 —— 也就是 VTEP 设备间的通信

    • 可以把 VTEP 设备封装的 「 Vxlan 数据包」看做为 「UDP封包中的基础数据单元,或 UDP 的负载」

    • 之后就属于传统网络的 UDP 发包过程,从「一台主机的VTEP 设备」发送到「另一台主机的 VTEP 设备」

    • 这个过程我们不需要管理,仿佛直接将「 Vxlan 包 」直接传递到了「目标 VTEP 设备」,没有感知且不需要维护中间复杂的流程(UDP封包、拆包等),因此称之为 ——「 Vxlan 隧道」

      实际上的 UDP 包发送和接收需要走「三层网络」—— 因此称之为 —— 三层通信

      到此我们就全部理解了 —— 基于三层的”二层“通信

  3. 之后此封装好的「UDP数据包」,将会通过三层网络,到达目的容器所在的主机的「目的VTEP设备」

    • 「UDP数据包」经过拆包后,「目的 VTEP 设备」 便获得了 「源 VTEP 设备」发来的「Vxlan数据包」
  4. 目的容器所在的主机的「VTEP设备」会进行解包,根据「 Vxlan 数据包」的内容及相应的路由规则,发送给对应的Pod 或容器

    • 「VTEP设备」 将「Vxlan数据包」拆包后,会获得「目的 Pod 的 IP 信息」,之后根据「目的 Pod 的 IP 信息」便会转发到「相应的 Pod(也就是容器,可视为一样的概念)」
    • 如何根据「目的 Pod 的 IP 信息」转发到「相应的 Pod(也就是容器,可视为一样的概念)」?
    • calico有相应「路由规则」,会根据「目的 Pod 的 IP 信息」转发到对应的「calib开头的网卡」(此设备时 veth-pair),因此便可直接到达「容器内(也就是 veth-pair 的另一端)」
    • fannel 的「目的VTEP设备」拆除「Vxlan 数据包的 Vxlan头」后,会直接将数据包转发给「docker0 网桥」(可理解为交换机,维护着 Pod IP、MAC 与端口的对应关系),因此可以直接将数据包转发到「容器内(容器也是通过veth-pair连接到docker0网桥上的)」
VXLAN 隧道

将「 Vxlan 包 」从「一个 VTEP 设备」传到「另一个 VTEP 设备」,利用 UDP 协议进行三层网络传输 —— 不要考虑封包解包

仿佛直接将「 Vxlan 包 」直接传递到了「目标 VTEP 设备」,没有感知且不需要维护中间复杂的流程(UDP封包、拆包等),因此称之为 ——「 Vxlan 隧道」

img

Fannel VXLAN 模式通信流程图

img

Calico IPIP 模式通信流程图

在这里插入图片描述

Fannel UDP 模式通信流程图

img

小结
  • 但是其中 flannel UDP 涉及到 内核态和用户态切换较多,性能损耗大于 flannel VXLAN 模式
  • flannel UDP 模式现在基本上被废弃了
  • flannel VXLAN 模式性能应该和 calico IPIP 差不多

BGP

fannel-hostgw 只支持二层网络,不支持三层网络,因为路由器中不存在 【Pod IP】—— 【宿主机MAC地址】的映射信息

Calico BGP 解决了此问题,支持 BGP 的路由器中也会存储着 【Pod IP】—— 【宿主机MAC地址】的映射信息

  • 因此知道该如何转发
  • 这个信息的分发和维护,是BGP的内在机制 (好像是 Brid 组件)

fannel host-gw

  • 必须二层连通
  • Pod 通信时相当于,把对方的宿主机当做网关
    • 本机上会有路由规则: 【对方 Pod IP 段】 —— 【对方主机 MAC 地址】
    • 这样本机 Pod 要发送给对方 Pod,就会直接发给对方主机,对方主机上当然会有自己所有 Pod 的路由信息,这样完成了通信
    • 同样,对方需要发回数据时,也是直接将数据发到本宿主机上,然后转发给对应的 Pod
    • 封装的数据包为 【对方主机mac地址】【Pod IP 地址】【端口】 【数据信息】
      • 因此这样要求必须二层连通,直接可以到达对方宿主机
      • 若是三层,中间的路由器不认识【Pod IP 地址】,也无法解析到【下一跳】,因此【不知道该发到哪】,所以只能二层连通
      • 不过 Calico BGP 解决了此问题,支持 BGP 的路由器中也会存储着 【Pod IP】—— 【宿主机MAC地址】的映射信息
        • 因此知道该如何转发
        • 这个信息的分发和维护,是BGP的内在机制 (好像是 Brid 组件)

img

Calico host-gw(BGP) 模式通信流程图

img

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐