实战!使用夜莺 Nightingale 统一监控 48+ 台 RoCE 智算交换机
原创
小斐Lab
小斐Lab
网络小斐
2026年11月5日 15:17
浙江
去阅读
大家好,我是小斐呀。
上一篇展开介绍国内智算中心网络设备以 RoCE 协议为主,并基于夜莺体系展开说明如何监控对应指标,通过 Categraf 采集器下的 gNMI 作为 gRPC Client 端实现对 RoCE 交换机的数据采集 RoCE 交换机作为 gRPC Server 端,最终数据会格式化为 Prometheus 格式经过夜莺并最终转储到 VictoriaMetrics 时序数据库中。
关于上一篇内容具体架构和数据流转方向可以看点击链接查看:
网络监控:夜莺基于 gNMI 采集 RoCE 交换机指标数据
随着 AI 智算中心、高性能计算(HPC)以及大规模 GPU 集群的快速发展, RoCE 网络对低时延、高吞吐、低丢包及网络可观测性的要求不断提高。
面向 AI 智算场景的新一代数据中心交换机逐步增强了对 gRPC 、 gNMI 、 YANG 、 OpenConfig 及 Streaming Telemetry 等技术的支持。因此,预计未来交换机监控体系将逐步从传统 SNMP 周期性轮询,向基于 gNMI/gRPC 的 Streaming Telemetry 流式指标采集演进。
需要注意 gRPC 是通信框架, gNMI 是可基于 gRPC 承载的网络管理接口协议, Telemetry 则是遥测机制。并非所有 RoCE 交换机都支持相同的 gNMI 能力,具体取决于厂商、型号和软件版本。
Telemetry 应用场景
看我之前文章的朋友们,应该知道我适配了很多基于 SNMP 的网络设备,我深刻知道这个协议的适配性和弱点,有传统的网络中应用场景比较广泛,但在 AI 智算中心中是非常有局限的,下面我们看下两者对比:
基于对比可以看出 SNMP 应用场景在 RoCE 网络监控下非常有局限,必须拥抱 Streaming Telemetry 才能把想要的指标全部采集到。
采集实际案例
上一篇基于锐捷的 RoCE 智算交换机完成了以下几个模块数据的采集:
gnmi_ruijie_system.tomlgnmi_ruijie_interface.tomlgnmi_ruijie_optical.tomlgnmi_ruijie_lldp.tomlgnmi_ruijie_roce.tomlgnmi_ruijie_bgp.toml
主要是这几个采集模块,其中前面系统、接口、光模块、邻居等指标都是在 SNMP 下也可以一起拿到,前面普通标准化下都是基于这四个模块方式进行标准化指标采集的,这里使用 gNMI 去采集实现:
使用锐捷私有 Yang 实现,基于锐捷 RGOS 12.x 系列接口指标其实也支持使用 OpenConfig 的公共指标,但是私有的能拿到的信息更符合我指标数据采集的需求。
但是我们知道 RoCE 交换机的监控重点,不仅是传统的接口流量、丢包、错误和设备状态,更重要的是监控 PFC 流控、 ECN 拥塞、 Buffer 缓冲区、 Queue 队列及 RoCE 网络通信质量,所以我们需要基于 Yang 拿到 RoCE 交换机的专项指标:
核心监控指标里面,上面的才是只是覆盖了很小的一部分, P0 级别的有一堆还没有覆盖,那么这里就放在 gnmi_ruijie_roce.toml 采集配置里面了:
这些指标几乎涵盖了主要的监控模块,可以完整的实现对 PFC 流控 、 ECN 拥塞 、 Buffer 缓冲区 、 Queue 队列 、 QoS 优先级 、 微突发检测 、 RDMA 通信 等核心指标数据都拿到。
上面的 RoCE 采集配置如下所示:
[[instances]]
addresses = [\"172.16.10.10:50051\"]
username = \"categraf\"
password = \"categraf@321\"
encoding = \"json\"
redial = \"10s\"
max_msg_size = 16777216
canonical_field_names = false
trim_field_names = false
guess_path_tag = false
enable_tls = false
# tls_ca = \"/etc/pki/ca.pem\"
# tls_min_version = \"TLS12\"
insecure_skip_verify = true
# tls_cert = \"/etc/pki/cert.pem\"
# tls_key = \"/etc/pki/key.pem\"
# origin = \"\"
# prefix = \"\"
# target = \"\"
# vendor_specific = [\"juniper_header\"]
updates_only = false
dump_responses = true
agent_host_tag = \"ident\"
# [instances.aliases]
# ifcounters = \"openconfig:/interfaces/interface/state/counters\"
[[instances.subscription]]
name = \"gnmi_roce_out_ecn_sign_pkts\"
origin = \"openconfig-rdma-counters\"
path = \"/qos/rdma-counters/interfaces/interface/state/out-ecn-sign-pkts\"
subscription_mode = \"sample\"
sample_interval = \"0s\"
suppress_redundant = false
disable_concatenation = true
[[instances.subscription]]
name = \"gnmi_roce_out_wreddrop_pkts\"
origin = \"openconfig-rdma-counters\"
path = \"/qos/rdma-counters/interfaces/interface/state/out-wreddrop-pkts\"
subscription_mode = \"sample\"
sample_interval = \"0s\"
suppress_redundant = false
disable_concatenation = true
[[instances.subscription]]
name = \"gnmi_roce_port\"
origin = \"openconfig-rdma-counters\"
path = \"/qos/rdma-counters/interfaces/interface/state/counters\"
subscription_mode = \"sample\"
sample_interval = \"0s\"
suppress_redundant = false
disable_concatenation = false
[[instances.subscription]]
name = \"gnmi_roce_input\"
origin = \"openconfig-qos\"
path = \"/qos/rdma-counters/interfaces/interface/input/queues/queue/state\"
subscription_mode = \"sample\"
sample_interval = \"0s\"
suppress_redundant = false
disable_concatenation = false
[[instances.subscription]]
name = \"gnmi_roce_output\"
origin = \"openconfig-qos\"
path = \"/qos/rdma-counters/interfaces/interface/output/queues/queue/state\"
subscription_mode = \"sample\"
sample_interval = \"0s\"
suppress_redundant = false
disable_concatenation = false
[[instances.subscription]]
name = \"gnmi_roce_buffer_pool_ingress\"
origin = \"openconfig-qos\"
path = \"/qos/rdma-counters/buffer-pools/buffer-pool/ingress\"
subscription_mode = \"sample\"
sample_interval = \"0s\"
suppress_redundant = false
disable_concatenation = false
[[instances.subscription]]
name = \"gnmi_roce_buffer_pool_egress\"
origin = \"openconfig-qos\"
path = \"/qos/rdma-counters/buffer-pools/buffer-pool/egress\"
subscription_mode = \"sample\"
sample_interval = \"0s\"
suppress_redundant = false
disable_concatenation = false
[[instances.tag_subscription]]
name = \"hostname\"
origin = \"openconfig-system\"
path = \"/system/state/hostname\"
subscription_mode = \"sample\"
suppress_redundant = false
match = \"unconditional\"
disable_concatenation = true
[[instances.processor_enum]]
metrics = [\"*overspeed\", \"*recover\"]
[instances.processor_enum.value_mappings]
true = 1
false = 0
其实用 AI 写不出比较完整的配置,我分别用了 ChatGPT 和 workbuddy 去实现,模型也用了 GPT 6 和 国内几个通用的都不太行,只能写个大概,不能开箱即用,还是要做测试和适配,所以 AI 对于这种比较非主流的采集器配置还是有点,或者需要提供更多的数据反馈和功能错误反馈以及足够的文档,可以慢慢磨出来。
由于 Categraf 下的 gNMI 插件有很多问题,在我实际使用和采集的情况下,发现有一些小漏洞,结合我自己真实实践想法加上 AI 辅助修复并优化了采集方式,所以实际使用的时候请优先选择 Categraf 最新版本,以便出现利用网盘面板的时候出现问题,具体修复问题如下:
- 添加
gnmi_up指标,默认开启 - 添加
gnmi icmp指标,需要配置开启 - 标签订阅:标签成功关联且值一致时删除源 key
上面三项示例配置:
[[instances]]
...
# 开启 gNMI 插件 ICMP
enable_icmp = true
# gnmi up 指标上报间隔时间
gnmi_up_interval = \"30s\"
...
源标签删除示例,就比如我订阅接口状态指标,接口状态指标中需要带入 labels 数据时,比如接口名称,那么我就需要订阅接口名称:
# 指标订阅:接口运行状态
[[instances.subscription]]
name = \"gnmi_interface_oper_status\"
origin = \"\"
path = \"/rg-interfaces:interfaces-state/interface/oper-status\"
subscription_mode = \"sample\"
suppress_redundant = false
disable_concatenation = true
# 标签订阅:接口名称
[[instances.tag_subscription]]
name = \"ifname\"
origin = \"\"
path = \"/rg-interfaces:interfaces-state/interface/name\"
subscription_mode = \"sample\"
match = \"elements\"
elements = [\"interface\"]
# 我需要删除源 name 标签
drop_source_key = true
suppress_redundant = false
disable_concatenation = true
由于我把接口名称重命名 ifname 但是由于标签名原始会带入 name 那么指标会类似这样:
# 不加 drop_source_key
gnmi_interface_oper_status{ifname=\"FH 0/1\", name=\"FH 0/1\", ...}
# 加 drop_source_key = true name 标签就删除
gnmi_interface_oper_status{ifname=\"FH 0/1\", ...}
使用图解析如下:
还有一个非常有用的应用场景,比如你写入的 yang 有接口名称 name 作为 elements 同时又有 queue 作为 \\name\\:
[[instances.subscription]]
name = \"gnmi_roce_input\"
origin = \"openconfig-qos\"
path = \"/qos/rdma-counters/interfaces/interface/input/queues/queue/state\"
subscription_mode = \"sample\"
sample_interval = \"0s\"
suppress_redundant = false
disable_concatenation = false
# 标签订阅:接口名
[[instances.tag_subscription]]
name = \"ifname\"
origin = \"openconfig-qos\"
path = \"/qos/rdma-counters/interfaces/interface/name\"
subscription_mode = \"sample\"
match = \"elements\"
elements = [\"interface\"]
drop_source_key = true
suppress_redundant = false
disable_concatenation = true
# 标签订阅:队列名
[[instances.tag_subscription]]
name = \"qename\"
origin = \"openconfig-qos\"
path = \"/qos/rdma-counters/interfaces/interface/input/queues/queue/name\"
subscription_mode = \"sample\"
match = \"elements\"
elements = [\"interface\", \"queue\"]
drop_source_key = true
suppress_redundant = false
disable_concatenation = true
这里 yang path 下 interface 是有接口索引,通过队列 queue 也是有队列索引,并且原始的索引 key 名称都是 name 如果按照原始采集指标如下:
# 原始未加 drop_source_key
gnmi_roce_input_pf_pkts{ifname=\"FH 0/1\", name=\"FH 0/1\", openconfig-qos:/qos/rdma-counters/interfaces/interface/input/queues/queue/name=queue5, qename=\"queue 5\", ...} 1
# 加入 drop_source_key
gnmi_roce_input_pf_pkts{ifname=\"FH 0/1\", qename=\"queue 5\", ...} 1
使用解析图如下:
这些采集指标和信息完成后,后续如果写一个自定义的网络监控平台也是非常方便,把前端写好,后端数据直接拿来就用,非常方便的就完成监控告警数据最难的一步。
指标展示
通过上述配置采集系统状态、接口信息指标、邻居信息指标、光模块指标、RoCE指标等数据可以通过 AI 生成对应的前端大屏:
Grafana 前端展示图在你网盘拿,不过我现在喜欢自己自定义前端效果。
SNMP 网络设备已经适配了大量的品牌,并且标准化了,现在 gNMI 也将慢慢把对应品牌适配起来,主流还是华为、华三、锐捷等国内网络设备,之前针对英伟达的 Cumulus Linux 系列也做了一些适配,主要是英伟达 SN5000 系列。
网络监控:夜莺开源 Categraf 如何利用 gNMI 采集网络设备指标最佳实践
end
这次开始使用夜莺采集智算中心的网络设备,也争取实现指标的标准化,如果您的环境下也有对应智算中心相关的网络设备需要统一化采集和监控,也想构建一套比较合适的网络基础设施统一监控告警系统,可以试试这套开源架构,有深入需求可以加我沟通。
我建立了一些对关于网络和基础设施等相关的监控告警群,针对这块的有需求或者想沟通交流,可以加入到群里交流即可,可公众号后台私信加我,我拉你进群。
📣欢迎朋友们关注公众号📢📢:【网络小斐】!
🙋♂️有想法的朋友也可以加我沟通,朋友🔘做个点赞之交!😂😂
欢迎点赞 👍、收藏 💗、关注 💡 三连支持一下,我们下期见~✨
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。









![buuctf WEB[强网杯2019]随便注writeup"](/images/random/titlepic/13.jpg)
评论