根据调查结果,你的 netperf 测试失败是因为该工具在进行 UDP 串流测试时,其默认的网络处理逻辑与你的 Kubernetes 集群网络拓扑发生了冲突。
以下是详细的原因分析及解决方案:
1. 核心原因:默认禁用路由(SO_DONTROUTE)
netperf 的 UDP_STREAM 测试有一个未在显著位置说明的特性:在默认情况下,它会为数据套接字设置 SO_DONTROUTE 选项 。
- 机制: 该选项会强制内核绕过标准的系统路由表,仅尝试在“本地链路(Local Link)”内寻找目标主机 。
- 冲突点: 你的节点
xs4772IP 为10.34.251.21,而目标节点xs1274为10.34.75.35。由于它们处于不同的子网(10.34.251.x与10.34.75.x),跨子网通信必须经过路由转发。当netperf尝试不经路由直接发送数据时,内核会因为在本地链路找不到目标而返回errno 101(网络不可达) 。
2. 为什么 Ping 和 Telnet 可以成功?
- 标准路由:
ping和telnet使用的是标准的套接字配置,它们会遵循系统的路由表,通过默认网关或特定路由条目将数据包转发到另一个子网 。 - 控制连接:
netperf自身的控制连接(即通过 11256 端口进行的初始握手)使用的是 TCP 协议,而 TCP 测试默认不会禁用路由,因此telnet和netperf的控制阶段都能成功连接 。只有在进入 UDP 数据传输阶段时,错误才被触发。
3. 解决方案:使用 -R 1 参数
要解决此问题,必须显式告知 netperf 在 UDP 测试中启用路由功能。
-
修复命令: 在命令的测试专用参数部分(即
--之后)添加-R 1参数 。 -
建议命令:
netperf -H 10.34.75.35 -p 11256 -t UDP_STREAM -l 10 -- -m 1472 -M 1472 -R 1
4. 其他注意事项
- MTU 与分片: 你使用的
-m 1472是非常专业的选择。在标准 1500 字节 MTU 的网络中,1472 字节正好是 UDP 载荷的最大值( 字节 IP 头 字节 UDP 头),这可以避免因 IP 分片导致的性能下降 。 - 测量位置: 由于 UDP 是不可靠协议,测试结果应以接收端(
netserver所在的xs1274)报告的接收速率为准,因为发送端报告的速率可能包含大量在网络中丢失的数据包 。
通过添加 -R 1 标志,netperf 将允许 UDP 数据包通过网关,从而解决子网不一致导致的“网络不可达”错误。