k8s集群网络(13)-flannel udp overlay网络通讯
在上一篇文章里我们介绍了k8s集群中flannel udp overlay网络的创建,这在里我们基于上一篇文章中的例子,来介绍在flannel udp overlay网络中pod到pod...
在上一篇文章里我们介绍了k8s集群中flannel udp overlay网络的创建,这在里我们基于上一篇文章中的例子,来介绍在flannel udp overlay网络中pod到pod的通讯。
在介绍之前我们先大致了一下linux TUN设备:
linux TUN device:Linux TUN device是一种网络设备,它可以有自己的ip地址,其最重要的特性就是可以被应用程序监听读写,被监听读写的对象为三层ip数据包。
TUN device一端连接网络内核空间,另一端连接用户空间的应用程序。
用户空间的应用程序有能力通过TUN device读写修改三层ip数据包。
数据从内核空间进入TUN device的时候,该设备会把数据交给用户空间的应用程序,使得应用程序有机会根据自己的逻辑修改ip数据包。
用户空间的应用程序可以把数据发给TUN device,该设备会把数据交由内核空间进行路由转发。
flannel udp模式就是利用TUN device,由flannel进程完成对原始ip包的udp封包,然后转发并解包。
查看集群中所有的pod:
我们用以前文章里部署的nginx application为例子,对于这个应用:
有2个pod,10.1.55.2和10.1.74.6
pod 10.1.55.2,在host 172.20.11.42上
pod 10.1.74.6,在host 172.20.11.43上
我们从10.1.55.2访问10.1.74.6,ping或者traceroute
kubectl get pods -o wide --all-namespaces
利用以前文章中的kubectl-debug进入pod 10.1.55.2调试:
kubectl-debug deployment-nginx-app-69b6bbfd6d-5k8pd --namespace default
ip addr
从pod 10.1.55.2访问pod 10.1.74.6
ip addr
ping -c 4 10.1.74.6
ip addr
traceroute 10.1.74.6
我们发现无论是ping命令还是traceroute命令都可以从pod 10.1.55.2访问的到pod 10.1.74.6,说明flannel udp overlay网络是没有问题的。
我们分析数据是如何从pod 10.1.55.2访问的到pod 10.1.74.6的
数据在pod network namespace的路由:
根据以前文章,10.1.55.2 pod从自己的network namespace访问10.1.74.6,根据10.1.55.2 pod network namespace的路由表,数据进入了10.1.55.2 pod宿主 172.20.11.42 network namespace的linux bridge docker0中。
数据在宿主network namespace的路由:
ip addr|grep 42
route -n
我们发现10.1.0.0/16网段的访问是直连路由,并且用flannel0设备发送。而这个flannel0设备就是flannel启动的时候在宿主机上创建的TUN device。这个时候ip数据包源ip为10.1.55.2,目标ip为10.1.74.6,数据由在内核空间进入了flannel0 TUN设备,然后由这个设备进入用户空间的flannel进程。
flannel进程udp封包:
flannel进程在用户空间对原始ip包进行upd封包
对于原始三层包:源ip为10.1.55.2,目标ip为10.1.74.6
对于外层udp包:源ip为172.20.11.42,目标ip为172.20.11.43,目标port为8285(可以配置),源端口为随机端口。
flannel确定upd封包目标ip
flannel连接着etcd,而etcd中已经存储overlay各个子网网段和host的关系,所以对于这个case,flannel判断目标ip10.1.74.6属于子网10.1.74.0/24,而这个子网就在host 172.20.11.43,所以udp封包的目标ip就确定了。
flannel确定upd封包源ip
根据当前host路由表,发往172.20.11.0/24宿主子网的数据都由enp0s3设备发送,而这个设备的ip地址就是172.20.11.42,所以udp封包的源ip就确定了。
数据由内核发送路由到目标host 172.20.11.43 上。
目标节点处理upd封包:
目标节点172.20.11.43的8285端口接收到udp包之后交由flannel进程处理,数据由内核空间进入程序用户空间。
flannel进程开始对这个upd数据解包,去掉upd的ip和port数据信息,得到内层的原始ip包。然后把这个包发送给TUN device flannel0,数据由应用程序的用户空间进入内核空间。
在内核空间根据路由表进行转发
根据172.20.11.43上路由表,将数据由linux bridge docker0做本地转发。
根据以前文章,docker0作为linux bridge利用veth pair将数据转发到目标pod 10.1.74.6。
总结flannel udp overlay网络pod到pod的通讯过程如下:
每个宿主都有名字为flannel0的TUN网络设备来完成对于原始ip数据包的udp封包与拆包,upd数据在宿主的8285端口上(端口值可配置)的flannel进程处理。
数据从原始pod的network namespace进入到host的network namespace中。
根据host network namespace中的路由表,下一跳ip为目标为直连,并且由当前host的TUN设备flannel0发送。
当前host的TUN设备flannel0将数据从内核空间交给用户空间应用程序flannel。
户空间应用程序flannel根据目标ip属于哪个子网,然后在etcd中查询这个子网所在的目标host,最后完成upd封包,这个时候:
对于原始三层包:源ip为源pod ip,目标ip为目标pod ip。
对于外层udp包:源ip为当前host的ip,目标ip为flannel在etcd中查询的匹配ip,目标port为8285(可以配置),源端口为随机端口。
flannel将upd包发送给TUN设备flannel0,数据由用户空间进入内核空间。
数据在内核空间根据路由策略发送到目标宿主的8285端口。
目标宿主的8285端口为flannel进程,数据由内核空间进入用户空间。
flannel进程对udp数据拆包,去掉ip和port信息,得到内层的原始ip包。然后把这个包发送给TUN device flannel0,数据由应用程序用户空间进入内核空间。
根据目标节点host上路由表,将数据由linux bridge docker0做本地转发。
数据由linux bridge docker0利用veth pair转发到目标pod。
目前先写到这里,下一篇文章里我们继续介绍k8s集群中underlay网络和overlay网络的总结对比。
更多推荐
所有评论(0)