SNMP采集数据的常见问题

记录基于 SNMP 协议采集设备数据时遇到的各种坑。

SNMP 是基于 UDP 的请求-响应方式的协议,服务端(agent)是常见的各种设备,客户端(network management station)向 agent 请求该设备上的数据。数据中心各设备使用的通信协议中,除 MODBUS 外,SNMP 占比最多。

从网络上看,相比 MODBUS RTUSNMP 不要求采集器与设备直接连接;从工具上看,相比于仅可运行在 Windows 平台的 Modbus Pollsnmpgetlinux/mac 可以很方便地安装运行,在 Windows 上也有编译好的二进制版本。因此 SNMP 的调试非常方便。

由于厂商实现参差不齐,通过 SNMP 请求采集器的数据时,也会出现各种问题。

OID 缺失

在请求中,变量绑定(variable-binding) 指定了 10 个 oid: p1, p2, ..., p10,响应中只有 9 个 oid ——p1, p2, ..., p9,不是 p10nosuch* 等错误数据,而是压根没有,整个响应数据中都不存在 p10

因此,在请求数据时,不能假设响应报文与请求报文中的 oid 一一对应——甚至响应 oid 与请求 oid 的个数都不能保证一致,于是,在解析响应数据时,使用 map 保存中间结果会比较方便。

OID 不存在

响应中的某个 oid 在 agent 中不存在,可能是请求了错误的 oid,也可能是 agent 的配置错误,等等。这些情况下,该 oid 在响应中可能的值包括但不限于NoSuchObject, NoSuchInstance, Null

IP 不一致

正常情况下,向 IP A 发送请求,响应报文的源 IP 也是 A,但实际中也会出现向 IP A 请求数据,发送响应的却是 IP B。

程序能否正常收到响应,取决于使用的 snmp 库能否处理这种情况,若使用 github.com/gonsmp/gosnmp,需要指定 UseUnconnectedUDPSockettrue 才能兼容这种情况。

另外,如果响应的源 IP 与请求的目的 IP 不一致,k8s 设置的网络策略会对发自 Pod 的 IP 包进行 SNAT,因此在 Pod 中无法收到响应——尽管节点收到了来自 IP B 的响应报文,但由于 IP 不一致,内核无法反向 SNAT,响应报文的目的 IP(节点 IP)无法转换为真正的目的 IP(Pod IP)。

响应超时

agent 性能不足

当请求 oid 个数比较多时,可能出现该情况,需要 agent 优化性能或者降低请求频率与 oid 个数。

agent bug

请求 n-1 和 n+1 个 oid 时都能正常收到响应,但请求 n 个 oid 时无法收到。

这种情况可能的原因是 n 个 oid 的响应报文长度落在了一个特定范围,agent 恰巧无法发送长度在特定范围的报文。

------ 本文结束 ------

版权声明

Memory is licensed under a Creative Commons BY-NC-SA 4.0 International License.
博客采用知识共享署署名(BY)-非商业性(NC)-相同方式共享(SA)
本文首发于Memory,转载请保留出处。