Hi~朋友,关注置顶防止错过消息
什么是Flannel
Flannel是一种跨主机容器间的网络通信方案,本身只是一个框架,真正提供网络功能的是其具体的后端实现
Flannel的后端实现有哪几种?
UDP
VXLAN
host-gw
Flannel TUN设备的作用是什么?
Flannel会在宿主机上创建一个flannel0设备,它是一个TUN设备,TUN设备工作在三层,用来在操作系统内核和应用程序之间传递IP包。
Flannel中的子网是?
要想找到另一个容器,我们必须先找到另一个容器的宿主机IP,这就依靠Flannel中的子网,子网与宿主机的关系均被保存在Etcd中。
$ etcdctl ls coreos.com/network/subnets
/coreos.com/network/subnets/100.96.1.0-24
/coreos.com/network/subnets/100.96.2.0-24
/coreos.com/network/subnets/100.96.3.0-24
$ etcdctl get/coreos.com/network/subnets/100.96.2.0-24
{"PublicIP":"10.168.0.3"}
Flannel UDP网络通信过程分析
从容器中eth0网卡到docker0的过程,我们不再赘述,详情请看谈谈同主机容器间的网络通信
当数据包到达宿主机时,会查找宿主机的路由表,如下假设我们访问的容器IP是100.96.2.5,根据路由规则会匹配到第二条规则,从而进入到flannel0设备
$ 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
flannel0设备在收到数据包以后,会交给创建该设备的Flannel进程
Flannel进程在收到数据包后,发现目的IP是100.96.2.5,根据Etcd维护的子网信息,可以找到容器对应的宿主机IP是10.168.0.3
Flannel在获取到上述信息后,会重新对数据包进行UDP封包,此时UDP的源地址就是请求容器的宿主机IP地址,目的地址是目的容器对应宿主机的IP,每台装有flanneld的主机都会监听8285端口,因此只需要将数据包发往目的主机的8285端口即可
此时只要源主机和目的主机网络是相通的,数据包即可被正常发送到目的主机
Flannel UDP模式下的通信图如下:

Flannel UDP模式的缺点
Flannel UDP模式最大的缺点是在发包过程中存在3次内核态和用户态的数据拷贝,上下文的切换和数据的拷贝代价都是极高的,如下图:

第一次是用户容器进程发出的IP包经过docker0网桥从用户态进入内核态
IP包在进入TUN设备后,从内核态回到用户态的Flannel进程(即flanneld)
flanneld重新封包UDP后,重新进入内核态,从而由宿主机的eth0网卡发往目的宿主机
到达目的主机后的解封装是逆向过程。
由于UDP模式存在极大的性能损耗,这种模式已基本被废弃,取而代之的是VXLAN,VXLAN可以模式可以完全在内核态进行上述的封包和解封工作。
本期文章就到这,长按扫码关注,更多内容我们下期再见!





