3.flannel的vxlan模式
环境介绍
两Pod的ip和mac信息
两节点物理网卡和flannel.1的ip和mac信息
原理解析
我们使用k8s-1上的pod cni-w4q8t 去ping k8s-2上的pod cni-m9l94
对于pod cni-w4q8t 要去的目的地址10.244.1.5 和自己10.244.0.3并不是同一个网段:
我们需要进行路由查询
需要查询Gateway 10.244.0.1所对应的MAC地址
此时数据包送到ROOT NS中,那么就开始走ROOT NS的逻辑。
查询宿主机路由表可得
需要注意的是:多条路由条目时候,除了网关很重要以外,出接口也非常的重要,每一个出接口都有对应的MAC地址。如要发送请求需要知道
由上述路由信息,我们可以得到两条重要信息:
1: 网关是10.244.1.0 该地址是k8s-2节点上的flannel.1(VTEP)的地址。
2. 数据的出接口为flannel.1。也就是说数据包要从此接口发出。
这里的转发:需要查询到地址10.244.1.0对应的MAC地址(flannel网络中,为避免地址冲突,将VTEP设备中flannel.1网卡IP都设为.0地址,正常情况下IP是从1开始,所以不会有任何IP跟flannel.1冲突)。
根据路由表信息我们知道了目的VTEP设备的IP地址,而根据三层IP地址查询二层MAC地址正是ARP表的功能。
而这里用ARP表的记录,也就是flanneld进程在k8s-2节点启动时,自动添加到API-server和k8s各节点上的,所以此时ARP就自动在k8s-1的节点上缓存下来了,也就意味着此时k8s-1不再需要查询ARP了。
####################
所以此时的数据报文形式为:
S_IP: 10.244.0.3 S_MAC: $k8s-1_flannel.1_MAC # [06:85:e5:d3:67:f1]
D_IP: 10.244.1.5 D_MAC: $k8s-2_flannel.1_MAC # [e2:49:6e:06:0d:d0]
在flannel.1网卡抓包显示
注意:源MAC地址是当前网卡的MAC(当前节点VTEP网卡flannel.1),目的MAC为下一跳MAC(对端节点flannel.1的MAC),但源IP与目的IP不变,仍是pod对应IP
2.3:由于flannel.1在此环境中同时还扮演VxLAN VTEP的角色,所以需要对应的方式去封装VxLAN的数据报文。
此时涉及到Inner和Outer的IP和MAC信息问题:[注意:此时的封装数据包是在flannel.1这个VTEP设备的指导下做数据报文的封装----非常重要]
那么对于k8s-1上的这个VTEP flannel.1它现在知道它所在宿主机上的Outer的S_IP和S_MAC。也知道Inner的S_IP和S_MAC 和 D_IP和D_MAC。
但是唯独不知道的是Outer的D_IP。也就是说不知道10.244.1.0这个地址下的flannel.1在哪一个节点上。
在Linux内核里面,网桥设备进行二层转发的依据来自FDB表的转发数据库。这个flannel网桥对应的FDB信息,就是flanneld进程维护的。
所以我们查询:
bridge fdb show | grep $10.244.1.0's_MAC
[root@k8s-1 ~]# bridge fdb show | grep e2:49:6e:06:0d:d0
e2:49:6e:06:0d:d0 dev flannel.1 dst 172.12.1.12 self permanent
[root@k8s-1 ~]#
由fdb转发信息,我们可以得出10.244.1.0此vtep所在node是172.12.1.12
到此k8s-1上的VTEP flannel.1获得了所有的封装包信息:
然后此时外部的IP信息为:S_IP:172.12.1.11 D_IP:172.12.1.12
封包后需要再次查询路由表信息:
在ens33网卡抓包显示