问题描述
其他组同事在客户现场部署了一套kubernetes环境,在其之上部署了volcano,一个用于高性能计算调度的组件。环境部署成功后,出现了一个问题,在node上ping经由volcano创建调度的pod时,如果pod在本节点上,可以ping通,如果跨界点ping不通。但是ping普通的pod,无论是否在本节点上都可以ping通。
总结一下,情况如下表:
pod类型 | pod IP | node上ping本node上的pod | node上ping其他node的pod |
---|---|---|---|
volcano创建调度的pod | 10.103.99.141 | 通 | 不通 |
非volcano创建调度的pod | 10.103.99.142 | 通 | 通 |
问题分析
客户现场的同事反馈说CNI使用的是calico,原来在测试环境使用的是flannel,读到这里有经验的读者可能已经知道大概是什么原因了。这里先卖个关子,其实问题很简单,但是恰逢周末,另外客户现场网络涉密也不能远程链接,所有的沟通都靠同事拍照回传,所以脑子混乱,一直到第二天周一使用了最麻烦的debug方式才找到问题所在。
下面记录了整个过程:
- ip route 检查两个pod所在node上的路由信息,发现有以下两条路由信息。证明calico把去往calixxxx的路由信息已经写到node上了。那为什么10.103.99.141跨节点不通,而10.103.99.142跨节点可以通。
10.103.99.141 dev calixxxxxxx scope link
10.103.99.142 dev calixxxxxxx scope link
- 继续分析想到用tcpdump在各个nic上抓包看一下,到底是在哪一步断掉了。我们假设,pod运行在node2上,我们从node1上来ping有问题的pod。整个ping的过程会经过下面几个nic。流量从node1物理网卡出来,进入node2物理网卡,转发到node2上的tunl0设备,最终到达pod所对应的cali开头的veth pair对,pod就会接收到请求。
node1.eth0 -> node2.eth0 -> node2.tunl0 -> node2.calixxxxx
- 在node2上执行下面的命令,抓经过tunl0的包。可以看到有包经过,但是只能抓到request的包,没有response的包。
tcpdump -i tunl0 icmp and host 10.103.99.141
- 继续在node2上抓10.103.99.41所对应的veth pair设备的包。
tcpdump -i calixxx icmp and host 10.103.99.141
结果符合预期在10.103.99.141的veth pair对上没有抓到icmp包。也就是说icmp包到达tunl0以后就没有向veth pair对转发。
6. 包到了tunl0上后,理论上应该根据路由信息转发到calixxx设备上才对,但是在calixxx上却没有抓到包,icmp包不会无缘无故消失。猜测是iptable上面添加了drop规则。关于iptable的内容,下面的两篇文章给了不少帮助
iptables详解
iptables与tcpdump谁更靠近网卡
执行下面的命令,发现在forword链上添加了好多Drop规则。
iptables -vL|grep Drop
- 判断是不是因为这些Drop规则将ping包丢弃的,组里大佬提示在forword链上加上一条接收所有请求的规则,然后看看ping pod能否通。执行如下命令,添加规则。
iptables -I FORWARD -j ACCEPT
- 添加规则后pod能ping通了。所以确定ping包被丢弃就是因为FORWARD链上面的drop规则导致的,但是规则好多,到底是哪一条呢。多亏组里大佬又有了新的发现,其中一条规则前两列,packets和bytes都是有数值的。而其他规则packets和bytes为0,也就是说只有一条规则被命中过,并实行了丢包行为。这一条规则的comments 写着 “calixxxx Drop if no policies passed packet”。
结论
很明显这条规则是calico添加的,而且还提到了policies,calico 有什么policies呢。想到这我恍然大悟,客户现场部署的应用肯定是添加了networkpolicy。他们在自己环境测试的时候用的是flannel,flannel是不支持networkpolicy的所以创建的networkpolicy根本没有生效。而换成calico后,networkpolicy生效了导致pod不通。最终临时解决方案是删掉这些networkpolicy。
过程很艰辛,但是问题很简单,如果从一开始就去检查networkpolicy,就不需要费力抓包分析iptables规则了。但是经过复杂的调查过程,也是有收获的。比如知道了calico的networkpolicy drop规则是添加在FORWORD链上的。这也解释了为什么在同节点上ping pod上可以ping通的。因为同节点ping时不会经过forward链,那流量也就不会drop掉了。
同节点ping包流程如下
用户态ping命令 -> iptables output链 -> 路由表 -> postrouting链 -> calixxx veth pair对