目前,Flannel 支持三种后端实现,分别是:

1. VXLAN
2. host-gw
3. UDP

UDP

image.png
第一次:用户态的容器进程发出的 IP 包经过 docker0 网桥进入内核态;
第二次:IP 包根据路由表进入 TUN(flannel0)设备,从而回到用户态的 flanneld 进程;
第三次:flanneld 进行 UDP 封包之后重新进入内核态,将 UDP 包通过宿主机的 eth0 发出去。

VXLAN (虚拟可扩展局域网 )

对比UDP模式,减少用户态到内核态的切换次数,并且把核心的处理逻辑都放在内核态进行
VXLAN,即 Virtual Extensible LAN(虚拟可扩展局域网),是 Linux 内核本身就支持的一种网络虚似化技术。所以说,VXLAN 可以完全在内核态实现上述封装和解封装的工作,从而通过与前面相似的“隧道”机制,构建出覆盖网络(Overlay Network)。
VXLAN 的覆盖网络的设计思想是:在现有的三层网络之上,“覆盖”一层虚拟的、由内核 VXLAN模块负责维护的二层网络,使得连接在这个 VXLAN 二层网络上的“主机”(虚拟机或者容器都可以)之间,可以像在同一个局域网(LAN)里那样自由通信。当然,实际上,这些“主机”可能分布在不同的宿主机上,甚至是分布在不同的物理机房里。
而为了能够在二层网络上打通“隧道”,VXLAN 会在宿主机上设置一个特殊的网络设备作为“隧道”的两端。这个设备就叫作 VTEP,即:VXLAN Tunnel End Point(虚拟隧道端点)。而 VTEP 设备的作用,其实跟前面的 flanneld 进程非常相似。只不过,它进行封装和解封装的对象,是二层数据帧(Ethernet frame);而且这个工作的执行流程,全部是在内核里完成的(因VXLAN 本身就是 Linux 内核中的一个模块)
image.png

  1. 数据包到达flannel.1,通过查找路由表,知道数据包要通过flannel.1发往10.1.16.3
  2. 通过arp cache表,知道了目的ip10.1.16.3的mac地址。kernel需要查看node上的fdb(forwarding database)以获得内层封包中目的vtep设备所在的node地址。

因为已经从arp table中查到目的设备mac地址为52:77:71:e6:4f:58,同时在fdb中存在该mac地址对应的node节点的IP地址。如果fdb中没有这个信息,那么kernel会向用户空间的flanned程序发起”L2 MISS”事件。flanneld收到该事件后,会查询etcd,获取该vtep设备对应的node的”Public IP“,并将信息注册到fdb中。当内核获得了发往机器的ip地址后,arp得到mac地址,之后就能完成vxlan的外层封装。

  1. Node节点的eth0网卡接收到vxlan设备包,kernal将识别出这是一个vxlan包,将包拆开之后转给节点上的flannel.1设备。这样数据包就从发送节点到达目的节点