本来上一篇文章应该是介绍flannel的udp模式的了,但因为其中的内容会涉及到linux虚拟网络设备tun的原理,所以先介绍一下tun设备,然后在这一篇才转入正题。
flannel一共有UDP、VXLAN、HOST-GW三种工作模式,如果开启了Directrouting的话,会使用VXLAN和HOST-GW组合,不跨网段就使用HOST-GW,跨网段就使用VXLAN。对于host-gw和vxlan我们在前面的文章中有过简单地介绍,在这篇文章我们来分析一下flannel的UDP模式,虽然这种模式现在基本上已经不在生产上用了,但通过对UDP模式的了解,可以让我们更好地理解linux中的虚拟网络设备tun,以及为我们提供一种在用户态操作内核协议栈数据的思路。
当flannel以udp模式运行的时候,每个节点会有两个守护进程以及一个binary文件:
-
以k8s的daemonset运行的kube-flannel,负责与ETCD交互,获取最新的节点与子网信息,通过unix domain socket 的方式把信息同步给相同节点的flanneld进程
-
一个名叫flanneld守护进程,负责监听UDP 8285端口(默认端口,可以修改)并打开/dev/net/tun设备,不管哪一端来的数据,都往另一端转;同时会打开一个unix domain socket,接收来自kube-flannel的指令,更新路由。
-
binary文件,存放目录为:/opt/cni/bin/flannel,在kubelet创建pod时会调用这个binary文件,负责创建同主机容器的相互通信,但它不具体做创建bridge或veth的工作,它只是生成了一个配置文件,然后调用本机的其它cni插件(例如:bridge和host-local,通常cni插件都在/opt/cni/bin目录下)来完成配置同主机容器的通信。
另外,在每个节点还会:
- 创建一个名为flannel.1的tun设备
- 创建了一条到POD-CIDR的直连路由,流量全部引到flannel.1的tun设备,注意是pod-cidr,不是某个node-cidr,这就意味着这台机出的流量只要是去容器的(当然除了本机的容器),就会走这张网卡。
下面一步步地解释上面的部件是怎么联动起来并完成跨主机的POD之间的通信的,在下面我们创建的tun设备名为tun0。
环境准备
首先介绍一下准备的环境,