
Flannel UDP模式
Tap与Tun设备
tap/tun 提供了一台主机内用户空间的数据传输机制。
不同是一个处理二层一个处理三层。
更多可参考以往文章:https://www.tnblog.net/hb/article/details/7233#TAP%E4%B8%8ETUN%E8%AE%BE%E5%A4%87
Tun设备应用举例
Flannel UDP 模式原理
UDP模式下flanneld进程在启动时会通过打开/dev/net/tun
的方式生成一个TUN设备(也就是我们的flannel0
),TUN设备可以简单理解为Linux当中提供的一种内核网络与用户空间(应用程序)通信的一种机制,TUN设备的特殊性在于它可把数据包转给创建它的用户空间进程,从而实现内核到用户空间的拷贝。即可通过直接读取tun设备的方式收发RAW IP包。
netstat -ulnp | grep flanneld
首先安装Flannel UDP
修改kube-flannel.yaml
文件中的net.conf
的Backend.Type
为udp
,关于UDP模式默认的Port为8285
,如果想更改为其他的Port仍然可以通过Backend.Port
参数来进行修改。
net-conf.json: |
{
"Network": "10.244.0.0/16",
"Backend": {
"Type": "udp"
}
}
kubectl delete -f kube-flannel.yaml
kubectl apply -f kube-flannel.yaml
然后我们运行三个pod,进行不同节点上的pod进行ping,这里我们以c1和c3为例子。
我们首先尝试一下是否能够ping得通,发现是没问题的。
kubectl exec pod/c1 -- ping 192.168.2.40
我们ping的时候,源IP与目的IP不变,中间MAC每隔一跳就变一次,可通过tcpdump -pne -i cni0 icmp
尝试抓包。
接着我们需要查路由表了,如果要访问192.168.2.40
网络应该从第二条路由出去到主机网络名称空间下,
kubectl exec pod/c1 -- route -n
接着我们再次查询node1节点的路由表,发现它的网关下一跳为0.0.0.0
,从接口flannel0
出去,而flannel0
是由我们的flanneld
创建的tun设备。
如何知道flannel0
是一个tun设备呢?我们再通过ip -d link show flannel0
命令查看,是有一个tun
标志的。
由于是tun
设备那么是不需要mac地址的,因为两端是直连的,我们可以通过下面的命令抓包查看。
tcpdump -pne -i flannel0
然后数据包从内核空间copy到我们?户空间的flanneld上去。
由于flanneld进程会采?UDP来分装原始的ping包(ICMP包),所以会在其原始数据包外层再加上?层数据头。
问题一
数据报?交给flanneld进程,此时他需要指导内核去安装?定的数据形式,这?是UDP Mode来做数据包的封装。这?涉及?个问题,就是如何获取?
?的Pod所在的?的Node。因为封装的?的就是想要数据包的IP头能在外部的交换或是路由设备上进程数据转发。
flanneld在启动时会将该节点的?络信息通过api-server保存到etcd当中,故在发送报?时可以通过查询etcd得到192.168.2.40这个Pod的IP属于10.211.55.9该Node2。
所以在数据包在即将被封装的时候,这?就获取到了四元组信息:
S_IP: 10.211.55.8 D_IP: 10.211.55.9
S_MAC:00:1c:42:fd:68:ff D_MAC: 00:1c:42:ad:be:97
问题二
这?还有?个Note:对于flanneld是如何知道采?哪?张宿主机上的?卡进?封装外层IP的呢?
1.通常是以默认路由的地址来作为缺省封装的外层地址。
2.也可以指定。
此时数据包就可以被转发出去了。
我们可以通过抓包的方式进行查看。
tcpdump -pne -i eth0 -w eth0_udp.cap
打开鲨鱼,我们先将UDP的包转换成IPv4的格式,这样就能查看到完整的包了。
现在已经看到flanneld封装完整的包,现在我们知道要发往的是10.211.55.9
这个地址,走的就是第二条路由出去。
然后到达节点二后又通过进入内核,从tun出去到flanneld进行解开包,然后再查询node2的路由表到达cni0,最后到达c3 pod节点。
欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739

