目前顶尖的云服务商都包含百万台服务器、数十甚至上百个机房、上万台网络设备、百万级网络链路。单单一个GPU集群,就有上万卡的级别。对这些网络和服务器的监控,一个分钟级别的故障,可能就是上百万资产的损失。
这不是一个ping能解决的问题。
今天,我们将百度物理网络黑盒监控方向的工具集 nettools 开源了(https://github.com/baidu/nettools),第一批放出的是 bitflip 和 bitflip6,用于检测网络丢包和比特翻转,在百度内部跑了很长时间了。
后续还有更多工具和SDK正在整理中,包括骨干网fullmesh监控、网关设备监控、连接客户内部机房设备的监控、定位工具等等,还有对巨量监控数据的处理。百度物理网络黑盒监控团队积累了一大批经验、产品和工具,后续逐步整理开源出来,欢迎关注。
为什么不是一个ping?
在大规模物理网络中,ping几乎没有用。
下面是一个集群简化的示意图。实际上层级比这更多,同一层级的网络设备数量远远大于图中画的,一个交换机有几十个端口而不是图中的几根连线,一个ToR交换机可能连接几十台服务器……两台服务器之间可走的链路有很多种可能。
bitflip用4种salt填充模式来覆盖各种跳变场景:
| 模式 | 值 | 作用 |
|---|---|---|
| 全1 | 0xFF |
检测 1→0 跳变 |
| 全0 | 0x00 |
检测 0→1 跳变 |
| 固定 | 0x5A |
检测混合模式跳变 |
| 互补交替 | 0xAAAA/0x5555 |
专门检测checksum盲区的互补跳变 |
每个包按序列号选择一种模式,服务端用相同模式验证,精确到哪个字节、哪个bit翻转了。
这个场景非常讨厌。可能一年就遇到一次,遇到了就特别麻烦,影响还大,错误数据被当成正常数据保存了。客户发现还算容易,因为除了能绕过checksum的那部分,大部分坏包会被服务器的checksum校验drop掉,通过采集监控服务器的checksum指标,理论上容易发现(实际还有一些坏包干扰)。
但定位起来就头疼了。客户报过来说好几个机房有改包现象,到底是哪个机房哪一层设备的哪个板卡?
这时候用bitflip工具,如果能复现,就可以通过找改包五元组的共同路径,定位到故障的设备和端口。这要靠单向监控,双向的话就像前面说的,有可能误导。
工程细节:raw socket + BPF
在百度的规模下,每秒要发送数千甚至上万个探测包。普通的UDP socket不够用:
- 需要自由构造IP头(设置TOS/DSCP等网络参数)
- 需要用极少的socket覆盖上百个端口对
- 需要精确控制发包速率
bitflip客户端用raw socket直接构造IP+UDP包,通过BPF过滤收包,只接收目标端口范围内、特定TOS值的回包。读侧按端口范围切分为最多8个goroutine,每个绑定独立的BPF过滤器。
1 | func portRangeBPF(minPort, maxPort, tos int) []bpf.Instruction { |
双向对比判断故障方向
bitflip同时支持客户端和服务端两侧统计。对比两侧丢包:
- 仅服务端有丢包:故障在正向路径(Client → Server)
- 仅客户端有丢包,服务端正常:故障在回程路径(Server → Client)
- 两端都有丢包:需要进一步分析
结合traceroute获取的链路拓扑,分析丢包五元组的公共端口/设备,就能定位到具体哪台设备、哪个板卡、哪个端口。
快速体验
1 | # 克隆并编译 |
IPv6环境使用 bitflip6,用法一致。
使用手册查看:bitflip使用指南
后续规划
nettools 目前开源的是 bitflip/bitflip6。后续还有更多工具和SDK在整理中:
- 更多探测场景的工具
- 通用的网络探测SDK
- 定位分析相关的工具
写在最后
在百度这种体量的物理网络中做监控和定位,不是写几个socket程序就能搞定的。为什么用UDP不用ICMP和TCP?为什么有时候又采用TCP syn探测?为什么需要单向探测?为什么协议头要带上一个窗口的发送信息?为什么salt要用4种模式?每个选择背后都有对应的故障场景和教训。
这些东西以前都在内部,现在开源出来了。
项目地址:https://github.com/baidu/nettools
欢迎Star、试用、提Issue和PR。
