用Prometheus+SNMP一步步搭建网络设备监控平台

发布时间:2026/10/15 5:50:25
用Prometheus+SNMP一步步搭建网络设备监控平台
干运维这行网络设备监控是个绕不开的硬骨头。以前我们监控网络设备要么靠商业网管软件一台设备一个授权价格不便宜要么写Shell脚本定时去ping丢包了才知道设备挂了等发现的时候业务早就抖了一圈。后来我试着用Prometheus这套开源的指标监控体系来统一接管交换机、防火墙、路由器配合一个SNMP导出器效果意外地好部署简单、指标丰富、出图漂亮最关键的是企业内网没那么多额外负担。这篇就按照我自己的实践路径从安装Prometheus服务端开始一步一步把网络设备接入、抓取、出图和告警全流程搭起来目标是让之前没碰过Prometheus的运维小白也能照着做出一套能直接上线的监控平台。这套方案的开箱即用程度比我预想的高很多。你不用去理解每个MIB节点的含义也不用给每台设备装Agent只要设备支持SNMP协议交换机、防火墙、路由器基本都能纳管。下面我把整个搭建过程、配置细节和排障经验完整写出来包括那些文档里不会告诉你的坑。1. 为什么用 Prometheus 盯网络设备选型思路1.1 网络设备监控和服务器监控不是一回事服务器监控很好办装个Agent就能上报CPU、内存、磁盘要什么有什么。但网络设备不太一样你很难在交换机或者防火墙上装Agent就算某些高端设备支持也会占用业务资源而且每台设备的装法还不一样。所以行业内最通用的做法是走SNMP协议让监控中心主动去设备上读数据。SNMP相当于设备预留出来的一扇只读窗口。设备内部的各种计数器、状态值按树形结构组织每个节点有一个唯一的标识也就是OID。比如接口的入方向字节数、接口状态、设备运行时长、CPU占用率都对应着具体的OID。监控系统通过 SNMP Get/Walk 操作把这些值读出来变成时序数据。大多数人的第一反应是写脚本去轮询这些值。我自己也干过写个Python脚本循环读取几十台设备的OID存到库里再画图。短期看没毛病用久了全是问题设备一多脚本就乱MIB各家有差异告警和图表还要另外做最后疲于维护脚本本身。1.2 选 Prometheus 的几个硬理由我最后选择 Prometheus不是因为它最时髦而是它真的解决了我上面说的那些问题。首先是部署成本低。Prometheus 主程序就是单个二进制文件解压就能跑不依赖数据库和复杂中间件。这一点在企业内网环境下特别友好不用把环境搞得很重。其次是拉取模型天然适合网络设备。Prometheus 定期从目标地址抓取数据网络设备这边只需要保证 SNMP 可达就可以不需要主动上报也不需要在设备上安装任何探针。配合 service discovery 还能自动发现新增设备当然小规模环境直接用静态配置也够。然后是生态成熟。官方维护了一个snmp_exporter专门负责把 SNMP 轮询到的结果转换成 Prometheus 指标格式。转换规则都写在配置文件里用什么MIB模块、采集哪些OID、轮询结束后怎么映射标签全部可控。配合 Grafana模板面板可以直接用。最后是查询语法强大。PromQL 做速率计算、百分比统计、趋势对比非常顺手比如接口流量直接rate()一算就出来比起自己在脚本里折腾数据清洗方便太多了。方案部署复杂度指标丰富度维护成本告警生态商业网管软件高一般要单独装服务器和数据库取决于授权和设备适配中需续费自带但灵活性一般自研脚本轮询低但随设备增加迅速失控取决于自己实现的MIB解析高要持续修脚本接邮件/微信等需自己造轮子Prometheus snmp_exporter低高可自定义OID采集低一处配置全局生效规则灵活配Alertmanager即可如果你单位已经有 Prometheus 在监控服务器那加网络设备监控基本就是“顺手的事”主程序不用动加个 job 配置就完事。这也是我推荐它的重要原因。2. 开箱即用搭建环境与安装组件2.1 需要准备的清单动手之前先理清楚需要哪些东西避免装到一半才发现缺依赖。一台 Linux 服务器2核4G内存足够系统建议 Ubuntu 20.04/22.04 或 CentOS 7/8装好普通用户权限。目标网络设备若干确认设备支持 SNMPv2c 是最常见的v3 也可以。提前规划好网络确保监控服务器能访问设备的 UDP 161 端口防火墙策略需要放通。Prometheus 二进制包、snmp_exporter 二进制包从各自官网的 Release 页面下载即可。组件端口分配我整理成了表格方便你规划防火墙和安全组组件端口说明Prometheus9090Web UI 和 APIsnmp_exporter9116供 Prometheus 拉取SNMP转换后的指标node_exporter可选9100监控服务器自身状态Grafana3000可视化面板整个数据流是这样的监控服务器上的 snmp_exporter 监听 9116Prometheus 按照设定的采集间隔去请求http://127.0.0.1:9116/snmp?target设备IPmoduleif_mibsnmp_exporter 收到请求后去设备上执行 SNMP 轮询拿到OID数值转换成 Prometheus 指标返回Prometheus 保存时序数据Grafana 负责出图Alertmanager 负责发告警。2.2 安装 Prometheus 主程序安装其实很简单我习惯把软件都放到/opt下然后用普通用户运行避免用 root 跑服务。# 下载以当前Linux amd64版本为例下载你需要的版本即可 wget https://github.com/prometheus/prometheus/releases/download/v2.x.x/prometheus-2.x.x.linux-amd64.tar.gz # 解压并放到 /opt 目录 tar xzf prometheus-2.x.x.linux-amd64.tar.gz mv prometheus-2.x.x.linux-amd64 /opt/prometheus # 创建专属用户 useradd --no-create-home --shell /bin/false prometheus chown -R prometheus:prometheus /opt/prometheus解压目录里有两个文件需要注意prometheus是主程序prometheus.yml是主配置文件。先看一眼默认配置能跑起来就行后面再改。很多人会在这里踩坑直接用了 root 用户起服务后面 snmp_exporter 和目录权限越搞越乱。用普通用户的好处是即使程序有漏洞被利用权限也有限而且配置目录归属清晰不容易误改系统文件。2.3 安装并验证 snmp_exportersnmp_exporter 的安装方式几乎和 Prometheus 一样也是二进制包解压即用。wget https://github.com/prometheus/snmp_exporter/releases/download/v0.x.x/snmp_exporter-0.x.x.linux-amd64.tar.gz tar xzf snmp_exporter-0.x.x.linux-amd64.tar.gz mv snmp_exporter-0.x.x.linux-amd64 /opt/snmp_exporter useradd --no-create-home --shell /bin/false snmp_exporter chown -R snmp_exporter:snmp_exporter /opt/snmp_exporter解压出来的包里有一个snmp.yml这是 snmp_exporter 的核心配置里面定义了各种采集模块比如if_mib接口监控、sysUpTime设备运行时间等。默认文件已经内置了常用的模块不需要自己从零写。如果你是第一次用建议先不动它直接用默认模块跑通流程。启动后快速验证一下curl http://127.0.0.1:9116/metrics能输出一堆以snmp_或者scrape_开头的指标说明进程已经在正常工作了。2.4 systemd 服务统一托管生产环境里不能用nohup ./xxx 这种土办法要用 systemd 管理。我贴两个 service 文件照着抄就行。Prometheus 的服务文件/etc/systemd/system/prometheus.service[Unit] DescriptionPrometheus Wantsnetwork-online.target Afternetwork-online.target [Service] Userprometheus Groupprometheus Typesimple ExecStart/opt/prometheus/prometheus \ --config.file/opt/prometheus/prometheus.yml \ --storage.tsdb.path/opt/prometheus/data \ --web.listen-address:9090 Restartalways [Install] WantedBymulti-user.targetsnmp_exporter 的服务文件/etc/systemd/system/snmp_exporter.service[Unit] DescriptionSNMP Exporter Afternetwork-online.target [Service] Usersnmp_exporter Groupsnmp_exporter Typesimple ExecStart/opt/snmp_exporter/snmp_exporter \ --config.file/opt/snmp_exporter/snmp.yml Restartalways [Install] WantedBymulti-user.target启动并设置开机自启systemctl daemon-reload systemctl enable --now prometheus systemctl enable --now snmp_exporter到这里服务端环境已经就绪。接下来大头来了就是怎么让 Prometheus 去采集网络设备。3. 设备接入交换机、防火墙、路由器的配置方法3.1 给设备预留 SNMP 权限在配置 Prometheus 之前需要先到设备上把 SNMP 打开。不同品牌设备的配置入口差异很大但通用逻辑是一样的启用 SNMP设置一个只读团体名限定允许访问的网段。不限定网段的话等于把设备的只读资料暴露给内网任何人风险很大。用命令行方式配置的设备大致是类似这样的思路snmp-server enable snmp-server community monitor-ro ro 10.0.0.0/8意思是启用 SNMP团体名为monitor-ro只允许来自10.0.0.0/8网段的读取请求。如果你管理的设备是图形界面去“系统管理”或者“网络监控”菜单里找“SNMP配置”勾选启用填写只读团体名指定管理主机地址即可。防火墙设备要格外注意两点。一是很多防火墙默认没有开放 UDP 161需要在安全策略里放通监控服务器到设备管理口的这段流量。二是别把读写团体名混用监控只需要只读权限意图越窄越安全。有些防火墙还提供了 SNMP v3如果支持优先用 v3账号认证加上加密安全性比 v2c 的明文团体名好得多。配置 v3 的时候给监控账号一个只读视图不要给它全局读写权限。3.2 修改 Prometheus 抓取配置环境都准备好之后核心的一步来了。你可能会想是不是直接在 Prometheus 的配置文件里写上“采集某台交换机”就行没那么简单。Prometheus 本身不会说 SNMP 协议它只能拉 HTTP 接口真正干活的是 snmp_exporter。所以配置上要做一次“目标地址传递”让 snmp_exporter 知道去轮询哪个设备。我用的方式是 relabel 配置这也是社区里推荐的做法scrape_configs: - job_name: network-devices scrape_interval: 60s static_configs: - targets: - 192.168.10.1 # 核心交换机 labels: device_type: switch role: core - targets: - 192.168.10.2 # 出口路由器 labels: device_type: router - targets: - 192.168.10.3 # 防火墙 labels: device_type: firewall metrics_path: /snmp params: module: [if_mib] auth: [public_v2] relabel_configs: - source_labels: [__address__] target_label: __param_target - source_labels: [__param_target] target_label: instance - target_label: __address__ replacement: 127.0.0.1:9116这段配置要做三件事第一告诉 Prometheus 要监控的“目标”其实是那些设备IP先把设备IP放在__address__里。第二通过 relabel把__address__原封不动复制给__param_target。这样 Prometheus 去请求 snmp_exporter 的时候URL 里会自动带一个target设备IP的参数snmp_exporter 就知道该去轮询谁了。第三把__address__替换成127.0.0.1:9116也就是最终 HTTP 请求要发给本地 snmp_exporter。module: [if_mib]是让 snmp_exporter 用接口监控模块来采集设备支持的标准 MIB-2 接口表基本都兼容。auth: [public_v2]对应 snmp.yml 里定义的 v2c 认证配置你也可以在 snmp.yml 里自定义一个团体名套到 auth 上。很多人第一次配完发现设备没有数据九成都是漏了 relabel 这段。如果直接用targets: [192.168.10.1:9116]去写Prometheus 只会去抓取9116端口并不知道该轮询哪个设备自然拿不到任何数据。3.3 加载配置并验证抓取配置改完后先检查语法/opt/prometheus/promtool check config /opt/prometheus/prometheus.yml没问题就重启 Prometheussystemctl restart prometheus打开 Web UI地址http://服务器IP:9090进入Status - Targets会看到network-devices这个 job 下面有几条 target。状态变成绿色 UP说明采集链路已经通了。这时候到 Graph 页面执行一条查询ifHCInOctets如果设备接口有流量能看到一串序列值。再配合rate()函数就能算出接口每秒入向字节数rate(ifHCInOctets[5m]) * 8乘8是换算成 bit单位就是最常见的带宽值。我建议你在这步把 snmp_exporter 的 debug 日志开着观察一下它和设备交互的情况journalctl -u snmp_exporter -f一旦出现连接错误或者 OID 超时日志里会直接体现后续排障会非常省心。4. 让监控看得见Grafana 面板与告警4.1 接入 Grafana数据采集到位之后剩下就是可视化。Prometheus 自带的 UI 适合临时查询不适合固定监控大屏所以我一般会再加一个 Grafana。Grafana 的安装也很直白用官方源装上之后直接访问 3000 端口。首次进入 Grafana默认账号密码都是 admin登录后会强制改密码。接着添加数据源类型选择 PrometheusURL 填写http://127.0.0.1:9090保存并测试出现绿色提示说明连接成功这一步不需要额外装插件内置就能连 Prometheus。4.2 核心指标怎么选、怎么写查询网络设备监控的核心指标抛开品牌差异基本都是这几类接口流量入向/出向字节数用rate()转成带宽占用。这是判断链路是否拥塞最直接的指标。# 入向流量 bps rate(ifHCInOctets{instance192.168.10.1}[5m]) * 8 # 出向流量 bps rate(ifHCOutOctets{instance192.168.10.1}[5m]) * 8接口状态ifOperStatus的值如果是 2 表示 down1 表示 up。这个指标适合做接口掉线告警。ifOperStatus{instance192.168.10.1} 2错误包和丢包接口下如果持续出现大量错包或丢包往往意味着物理链路或双工模式有问题。rate(ifInErrors{instance192.168.10.1}[5m])如果你不熟悉 MIB刚开始不建议自己一上来就写复杂查询。Grafana 官方面板市场里有很多现成的SNMP 设备监控模板搜索“SNMP”就能找到导入后把数据源选成刚才配的 Prometheus一般立刻就有图。等跑顺了再往里加自己关心的指标。需要提醒的是不同模块采集出来的指标名不一样。比如if_mib模块里接口流量叫ifHCInOctets而某些自定义模块里可能会映射成snmp_ifHCInOctets。出现查询无数据时先确认指标名是不是对得上这是最容易忽略的地方。4.3 告警规则怎么配置只出图不做告警的话监控的价值要打一半折扣。Prometheus 的告警规则配置是在主配置文件里通过rule_files引入规则文件然后定义一个规则组。创建一个规则文件/opt/prometheus/rules/network_rules.ymlgroups: - name: network_devices rules: - alert: InterfaceDown expr: ifOperStatus 2 for: 2m labels: severity: critical annotations: summary: 设备 {{ $labels.instance }} 接口 {{ $labels.ifName }} 宕机 description: 接口状态为 down持续超过 2 分钟请检查链路和端口配置。 - alert: InterfaceHighErrorRate expr: rate(ifInErrors{jobnetwork-devices}[5m]) 100 for: 5m labels: severity: warning annotations: summary: 设备 {{ $labels.instance }} 接口 {{ $labels.ifName }} 错误包过多 description: 入向错误包速率超过 100 pps可能存在双工不匹配或线路质量问题。 - alert: LinkBandwidthUsageHigh expr: rate(ifHCInOctets{jobnetwork-devices}[5m]) * 8 / ifSpeed 0.8 for: 10m labels: severity: warning annotations: summary: 链路 {{ $labels.instance }} - {{ $labels.ifName }} 带宽占用超过 80%规则里的for参数意思是持续多久才算触发避免瞬时抖动导致误报。比如接口闪断一下又恢复不会立刻报警。expr表达式需要保证返回的结果有 label 能够定位到具体设备和接口所以$labels.instance、$labels.ifName在告警信息里非常有用。在主配置文件prometheus.yml里引入这个文件rule_files: - /opt/prometheus/rules/network_rules.yml验证规则/opt/prometheus/promtool check rules /opt/prometheus/rules/network_rules.yml重启 Prometheus 后在 UI 的Status - Rules页面能看到规则状态。如果你配了 Alertmanager告警会自动推送到邮件、企业微信或者 Webhook不配的话告警只显示在 Prometheus 的 Alert 页面上适合刚开始测试阶段。5. 常见问题与排查技巧实录5.1 设备在 Targets 里显示 DOWN这是新手最常遇到的问题。配置看起来都对但 target 就是起不来。按下面的顺序排查基本都能解决。第一步先确认 SNMP 通不通。在监控服务器上执行snmpwalk -v2c -c monitor-ro -t 3 192.168.10.1 1.3.6.1.2.1如果你没有安装 snmp 工具先装snmp和snmp-mibs-downloader包。如果这条命令能输出一串 OID 和值说明设备和团体名没问题。如果提示超时或者无响应就去设备上检查 SNMP 是否启用、团体名是否一致、ACL 是否限制了你当前的网段。第二步看 snmp_exporter 日志。用journalctl -u snmp_exporter -f实时观察采集失败时日志里会出现类似Error walking target的信息还有具体是哪个 IP 出问题。第三步查 relabel 配置是否生效。在 Prometheus Targets 页面点击某个 target 查看标签。如果instance标签还是192.168.10.1:9116而__param_target不存在说明 relabel 规则写错了。这是一个特别隐蔽的问题一定要确认__address__的转移过程。5.2 抓到指标是空的target 是 UP但查询指标根本没有数据或者只有一部分设备有数据。这种问题大概率出在模块不匹配上。标准设备的 MIB-2 接口表是通用的大多数网络设备都能用if_mib模块采集。但有些设备厂商在私有 MIB 里才有 CPU 和内存指标默认公共模块采集不到。这时候需要自己写 OID 映射在 snmp.yml 里增加新的模块。还有一种情况设备启用了 SNMP over TCP 或者限制了 max-request-size导致 snmp_exporter 默认的批量 Walk 请求失败。日志里常出现SNMP walk failed: request timeout或者unexpected end of snmp walk。这种时候把 snmp.yml 里对应模块的max_repetitions调小比如从默认值改成 5能明显提高兼容性。我遇到过一次老型号交换机默认配置怎么都不行调小 max_repetitions 后一切正常。5.3 Grafana 面板无数据Grafana 导入模板后没数据先别怀疑模板有问题。按这几步排查数据源选对了没有Dashboard 的 data source 变量是不是指向 Prometheus。时间范围是不是太短有些接口流量本身很低5分钟范围内曲线平了看不出来。指标名里带不带引号ifHCInOctets和ifHCInOctets{instancexx}查询结果差异可能很大。我自己有个习惯先在 Prometheus 的 Graph 页面把查询语句跑出数据确认有曲线再粘贴到 Grafana 的 Panel Editor 里。这样能把问题和可视化分开定位更快。5.4 防火墙设备的特殊注意点防火墙接入监控的时候坑最多我单独强调一下。很多防火墙默认不响应 SNMP或者只在特定安全区域响应。配置时要确保允许从监控服务器所在网段访问防火墙的管理接口。规则上经常是“管理接口可以 ping 通但 SNMP 不通”原因多半是策略只放行了 ICMP 和 HTTPS漏掉了 UDP 161。另外防火墙的资源指标比如会话数、新建连接速率在标准 MIB 里一般没有要看厂商私有 MIB。如果你发现只能采到接口流量但采不到会话数这是正常的需要去查设备的 MIB 文件找到对应的 OID 手写映射。这个过程不复杂但确实需要耐心。最后说一点我自己的经验。这套方案跑起来之后我建议先别急着把所有设备一次性加入先挑一台核心交换机和一台防火墙跑一周确认指标稳定、告警不误报再慢慢把其他设备加进来。网络设备监控跟服务器监控不一样设备型号杂、MIB 差异大一次铺开出了问题很难排查。从一个可控的小范围开始你会发现这套体系越跑越顺手后面基本都是复制粘贴加改 IP 的事。