Flannel是kubernetes的网络插件之一,通过构建k8s集群节点之间的overlay网络,实现跨节点通信等功能。flannel常用的网络转发模式有hostgw、udp、vxlan等,在实际生产中常用的是vxlan模式。
子网划分
k8s会为每个集群节点划分子网,这样pod调度到某节点时,就会按照该节点的子网网段分配ip,保障pod ip的集群唯一性。
我们可以查看/run/flannel/subnet.env 文件,里面主要包括当前节点的子网信息。例如本机集群192.168.249.10节点子网网段是10.244.0.0/24,192.168.249.12节点子网网段是10.244.1.0/24
Flannel通过daemonset的方式在每个k8s节点上运行了一个flanneld的服务,通过flanneld进程对节点进行创建隧道,添加路由信息,修改iptables等操作。
跨节点Pod通信
我们以vxlan模式为例看一下flannel如何实现的pod间的通信。
Flannel创建名为flannel.1的vxlan设备(nolearning),设备ip是子网的第一个IP 10.244.1.0,并把设备的mac和ip和本节点的ip记录到etcd中。还会创建名为cni0的网桥,网桥的ip是子网的第二个ip 10.244.1.1,起到docker0网桥的作用。
我们先看一下跨节点通信的流程图,然后一步一步查看数据包流向。
我们从节点192.168.249.12上的pod1 10.244.1.4中ping节点192.168.249.10上的pod2 10.244.0.2
进入pod1 执行route -n,我们发现pod的默认网关是10.244.1.1,也就是cni0
为什么pod的eth0可以发给cni0网桥呢,查看pod的eth0网卡,发现他的对端是if11。
我们再看宿主机上的网络设备if11是vethc8894304,这个设备在cni0网桥上。这里可以理解成一根网线一头插在pod里,另一头插在了cni0网桥上。
到了cni0网桥其实就到了宿主机,再看宿主机的路由信息。可以发现flannel专门为每个子网网段创建了一条路由,10.244.0.0/24网段就通过宿主机上的vxlan设备flannel.1发给网关10.244.0.0,网关的ip、mac与宿主机的对应关系都可以在etcd中查到。
之后通过flannel.1 进行vxlan封包。vxlan包结构如图所示。
包内层就是pod到pod发送的二层链路层包,在此基础上添加了vxlan的header,并使用udp、宿主机的ip和mac信息进行封包后,传输给对方宿主机再进行拆包。
最后查看对端宿主机的路由表,route -n。
对于本机pod网段的数据包 10.244.0.0/24,都转给了虚拟网桥cni0,而cni0再通过上面的veth对将数据包转发到pod中。至此就完成了跨node节点的pod通信。
同节点Pod通信
了解了跨节点pod通信,再考虑同节点pod通信就明白,直接通过cni0网桥就可以了。
UDP与Host-gw模式
Flannel还提供了UDP和Host-gw两种模式。UDP模式和Vxlan基本一致,只是封包方式不同,UDP封包结构如下图所示。
所以UDP封包就是直接将内层IP层数据包封装到了UDP中,由于是使用flanneld应用层面进行封包解包,效果比vxlan内核封包要差,使用较少。
我们修改flannel的configmap,将flannel从vxlan模式换成host-gw模式,并重启flannel的pod。这样就从vxlan模式切换成了host-gw模式。
kubectl edit cm -nkube-system kube-flannel-cfg
我们发现其他pod网段的路由信息有所变化,输出网卡从flannel.1变成了本机网卡,因为不需要进行封包,同时flannel的mtu从1450改成1500。而网关直接配置为宿主机ip,这就需要所有的集群节点处于同一个二层网络中,即二层可达。这也是host-gw模式的最大限制。
文章来源:https://www.toymoban.com/news/detail-417629.html
最后,如果你对kubernetes感兴趣的话,欢迎关注~文章来源地址https://www.toymoban.com/news/detail-417629.html
到了这里,关于Kubernetes网络插件flannel原理简介的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!