记一次kubernetes Pod跨节点访问不通的调查过程

问题描述

其他组同事在客户现场部署了一套kubernetes环境,在其之上部署了volcano,一个用于高性能计算调度的组件。环境部署成功后,出现了一个问题,在node上ping经由volcano创建调度的pod时,如果pod在本节点上,可以ping通,如果跨界点ping不通。但是ping普通的pod,无论是否在本节点上都可以ping通。
总结一下,情况如下表:

pod类型pod IPnode上ping本node上的podnode上ping其他node的pod
volcano创建调度的pod10.103.99.141不通
非volcano创建调度的pod10.103.99.142

问题分析

客户现场的同事反馈说CNI使用的是calico,原来在测试环境使用的是flannel,读到这里有经验的读者可能已经知道大概是什么原因了。这里先卖个关子,其实问题很简单,但是恰逢周末,另外客户现场网络涉密也不能远程链接,所有的沟通都靠同事拍照回传,所以脑子混乱,一直到第二天周一使用了最麻烦的debug方式才找到问题所在。

下面记录了整个过程:

  1. 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
  1. 继续分析想到用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
  1. 在node2上执行下面的命令,抓经过tunl0的包。可以看到有包经过,但是只能抓到request的包,没有response的包。
tcpdump -i tunl0 icmp and host 10.103.99.141
  1. 继续在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 
  1. 判断是不是因为这些Drop规则将ping包丢弃的,组里大佬提示在forword链上加上一条接收所有请求的规则,然后看看ping pod能否通。执行如下命令,添加规则。
iptables -I FORWARD -j ACCEPT
  1. 添加规则后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对
  • 10
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当然可以帮你绘制一个菱形的WinForms按钮控件。以下是一个基本的示例代码: ```csharp using System; using System.Drawing; using System.Windows.Forms; namespace DiamondButtonExample { public partial class DiamondButton : Button { public DiamondButton() { InitializeComponent(); SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true); FlatStyle = FlatStyle.Flat; FlatAppearance.BorderSize = 0; BackColor = Color.Transparent; Size = new Size(100, 100); } protected override void OnPaint(PaintEventArgs pevent) { GraphicsPath path = new GraphicsPath(); Point[] points = { new Point(ClientRectangle.Width / 2, 0), new Point(ClientRectangle.Width, ClientRectangle.Height / 2), new Point(ClientRectangle.Width / 2, ClientRectangle.Height), new Point(0, ClientRectangle.Height / 2) }; path.AddPolygon(points); Region = new Region(path); base.OnPaint(pevent); } } } ``` 要使用这个自定义的按钮控件,可以按照以下步骤进行: 1. 创建一个新的 WinForms 项目。 2. 在解决方案资源管理器中,右键单击项目,选择“添加”->“类”。 3. 将上述代码复制到新创建的类文件中。 4. 在主窗体或其他窗体上添加一个按钮控件。 5. 在设计器中选择该按钮控件,然后在属性窗口中找到“Modifiers”属性,并将其设置为“Public”。 6. 打开主窗体或其他窗体的代码文件,在顶部添加 `using DiamondButtonExample;`。 7. 在窗体的构造函数或加载事件中,使用如下代码创建和添加自定义的菱形按钮控件: ```csharp DiamondButton diamondButton = new DiamondButton(); Controls.Add(diamondButton); ``` 现在你应该能够在你的 WinForms 项目中看到一个菱形按钮控件了。你可以根据需要修改按钮的大小、颜色和其他属性。希望这能帮到你!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值