本文主要是介绍flannel 实战与源码分析(二),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
上一篇介绍了基本使用,这一篇我想详细介绍一下flannel网络包的是怎样传输的,应为这些基本东西没有解释清楚,只看代码是没法理解的。先看看一张经典图:
这个是flannel官方提供的一个数据包图,从这个图片里面里面可以看出docker0分别处于不同的段:10.1.20.1/24 和 10.1.15.1/24 现在从上面的一个pod(10.1.15.2)去连接另一台主机上的pod(10.1.20.3),网络包从宿主机192.168.0.100发往192.168.0.200时,数据包被封装到UDP里面,并且在外边包装了宿主机的IP和mac地址。这就是一个经典的overlay网络,应为容器的IP是一个内容IP,无法从跨宿主机通信,所以容器的网络互通,需要承载到宿主机的网络之上。介绍完网络包的结构后,再深入看看网络包是怎样一步一步封装的。下面根据我自己的测试环境来讲解
上面的截图是我自己的环境,现在容器从192.168.52.2->192.168.90.8发送ping请求。从路由分析192.168.0.0/16的流量都交给flannel.1处理,这是一个vlan的的tun设备,现在要解决两个问题网络才能通,第一个是90.8这个IP在哪里?它的mac地址是多少?第二个问题是如果vxlan的数据包已经组装好了,要发送到哪一台宿主机上面的tun设备呢?带着疑问我们深入看看
先看这个配置
cat /proc/sys/net/ipv4/neigh/flannel.1/app_solicit
3
ARP将首先试着询问本地arp进程app_solicit次,获取更新了的MAC(介质访问控制)地址。如果失败,并且旧的MAC地址是已知的,则发送 ucast_solicit 次的 unicast probe。如果仍然失败,则将向网络广播一个新的ARP请求,此时要有待发送数据的队列。这里可以看到flannel会监听内核发出的L3 MISS请求,fannel从etcd里面可以获取到90.8这个目的ip所在主机的宿主机地址和对方fannel.1的mac地址,并写到本地邻接表中,
ip n
192.168.90.8 dev flannel.1 lladdr 02:e6:a9:31:4c:fa STALE
这个是已经过期(STALE)的当在容器里面ping 90.8后
ip n
192.168.90.8 dev flannel.1 lladdr 02:e6:a9:31:4c:fa REACHABLE
这个里面又重新变成可到(REACHABLE)这个就是flannel通过etcd获取并写入的。相同的原理,当封装最外层UDP数据包时,需要对方宿主机的地址,那么怎么知道4c:fa这个flannel在那台宿主机上呢?
bridge fdb show dev flannel.1
02:e6:a9:31:4c:fa dst 10.39.0.7 self permanent
这个规则的下发也是依赖flannel和etcd,通过事件监听去更新这个转发表。那么这个数据包就发到slave2上面了,在slave2上面flannel.1进行拆包,通过路由进入docker0从而到达90.8这个容器。这是vxlan模式,其实flannel还支持别的模式常用的是UPD,它是直接封装到udp,没有vxlan的封装,这种网络模式损耗非常大50%左右,即便是vxlan也有30%左右的损耗,如果允许的话host-gw是个很好的选择,它也是通过路由的方式,类似于calico,但不使用BGP罢了。这种网络损耗最少,建议使用。在扩展一下,上面几种都是flannel,现在4.2内核加入的ipvlan性能应该是最好的,本质上是一个网卡多个IP。
在slave2上就可以抓取数据包了,先看宿主机
tcpdump -vvv -i eth0 |grep 10.39.0.17
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes10.39.0.17.53091 > slave2.otv: [no cksum] OTV, flags [I] (0x08), overlay 0, instance 1slave2.46050 > 10.39.0.17.otv: [no cksum] OTV, flags [I] (0x08), overlay 0, instance 110.39.0.17.53091 > slave2.otv: [no cksum] OTV, flags [I] (0x08), overlay 0, instance 1slave2.46050 > 10.39.0.17.otv: [no cksum] OTV, flags [I] (0x08), overlay 0, instance 110.39.0.17.53091 > slave2.otv: [no cksum] OTV, flags [I] (0x08), overlay 0, instance 1slave2.46050 > 10.39.0.17.otv: [no cksum] OTV, flags [I] (0x08), overlay 0, instance 1
可以看到从slave1到slave2上发送的数据包,并且是overlay。再看看flannel.1上的
从容器的192.168.69.2 ping 192.168.49.2
外层是宿主机的IP和mac,内层IP是容器的IP,但源mac和目的mac分别是宿主机上面flannel.1(vtep设备的)的mac,这点一定要注意。
这篇关于flannel 实战与源码分析(二)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!