异构集群中如何解决容器组网络不通的问题?
问题描述
通过平台为 global 集群添加了两个节点,其中,控制节点 使用 x86 架构,计算节点 使用 ARM 架构。启动集群服务后,使用如下命令,可以看到 计算节点 上的容器组(Pod)处于 CrashLoopBackOff 状态,并提示访问 APIServer 失败。
kubectl get pod -A -o wide | grep <节点 IP 地址>原因分析
在异构集群中,由于不同系统间硬件架构的差异,网卡校验和(checksum)计算方式可能不一致,导致接收方无法正确验证数据包的完整性,从而可能引发数据包丢失等问题。
排查方法
检查容器组的关联关系
检查北向数据库(nb)、南向数据库(sb)内容, 确保每个 Pod 都有关联的逻辑交换机端口(lsp)及端口绑定(Port_Binding)记录,从而保证 Pod 能够正常通信和访问网络,具体命令如下。
ovn-sbctl show检查节点间的网络连通性
-
由于异常状态的容器组都位于计算节点上,通过控制节点 Ping 异常节点的容器组,无法 Ping 通。
-
通过控制节点 Ping 计算节点的 ovn0 网卡,无法 Ping 通。
抓取数据包
注意:请使用实际环境的网卡名称、IP 地址替换如下命令中的 <节点网卡名称>、<虚拟网卡名称>、<节点虚拟 IP> 及 <节点 IP>。
-
使用
tcpdump -i <虚拟网卡名称> -nnve host <节点虚拟 IP>命令在控制节点上进行抓包,可以看到只有 ICMP request 报文,没有 reply 报文。
参数说明:
-
tcpdump:抓包工具,使用前需安装对应的应用包。 -
-i:指定需要抓取的网卡信息。 -
host:指定需要抓取数据包的主机 IP。
-
-
使用
tcpdump -i <虚拟网卡名称> -nnve host <节点虚拟 IP 地址>命令在计算节点上进行抓包,可以看到已收到 ICMP request 报文并返回 reply 报文,但是在 步骤 1 中未收到相关 reply 报文。
-
使用
tcpdump -i <节点网卡名称> -nnve host <节点 IP>命令在控制节点的网卡上抓包,可以看到控制节点发出的数据包的校验和不正确,而接收到的数据包校验和没有问题,在计算节点的网卡上抓包有同样的问题。因此可以确定是 checksum 校验的问题。
解决方案
关闭异构集群中 ARM 节点的 checksum 校验可解决此问题,具体命令如下,请使用实际节点的网卡名称替换 <节点网卡名称>。
说明:此更改会在网卡重启后失效,若需持久化更改,可将命令添加至相应启动文件中。
ethtool -K <节点网卡名称> tx off参数说明:
-
-K:启用或禁用指定网卡的功能。 -
<节点网卡名称>:ARM 节点中需要关闭校验和的网卡名称, -
tx off:禁用传输(发送)校验和校验。