SNMP Exporter

经过通过 SNMP 协议来监控交换机、路由器等网络硬件设备。对于 SNMP ,维基百科的解释如下:

简单网络管理协议(SNMP,Simple Network Management Protocol)构成了互联网工程工作小组(IETF,Internet Engineering Task Force)定义的Internet协议族的一部分。该协议能够支持网络管理系统,用以监测连接到网络上的设备是否有任何引起管理上关注的情况。它由一组网络管理的标准组成,包含一个应用层协议(application layer protocol)、数据库模式(database schema),和一组资料对象。

在一台 Linux 主机上,我们可以使用 snmpwalk 命令来访问设备通过 SNMP 协议暴露的数据,比如最简单的查看所有信息的命令如下:

snmpwalk -v 2c -c xxxxxxxx 172.16.1.1

参数解释:

  • -v 2c : 指定 SNMP 协议的版本,当前指定为 2c
  • -c xxxx : SNMP 的 Community 值
  • 172.16.1.1 : 硬件的 IP地址

简单查看以后,我们需要长期监控,这个时候就要借助 SNMP Exporter 这个工具了。

SNMP Exporter 是 Prometheus 开源的一个支持 SNMP 协议的采集器,GitHub 地址 : https://github.com/prometheus/snmp_exporter

可以通过 docker 部署或者二进制文件来进行部署

下载 docker image 使用如下命令,使用中请切换对应的版本。

docker pull prom/snmp-exporter:v0.20.0

如果使用二进制文件部署 ,下载地址如下:

https://github.com/prometheus/snmp_exporter/releases

对于 SNMP Exporter 的使用来说, 配置文件比较重要,配置文件中根据硬件的 MIB 文件生成了 OID 的映射关系。以 Cisco 交换机为例,在官方 GitHub 上下载最新的 snmp.yml 文件,由于 Cisco 交换机使用的是 if_mib 模块,在 if_mib 下新增 auth ,用来在请求交换机的时候做验证使用,这个值是配置在交换机上的。

关于采集的监控项是在 walk 字段下,如果要新增监控项,写在 walk 项下。我新增了交换机的 CPU 和内存信息。

......

if_mib:
  auth:
    community: xxxx
  walk:
  - 1.3.6.1.2.1.2
  - 1.3.6.1.2.1.31.1.1
  - 1.3.6.1.4.1.9.2.1  # 交换机 CPU 相关信息
  - 1.3.6.1.4.1.9.9.48  # 交换机内存相关信息
  get:
  - 1.3.6.1.2.1.1.3.0
  metrics:
  - name: busyPer
    oid: 1.3.6.1.4.1.9.2.1.56.0
    type: gauge
    help: CPU utilization
  - name: avgBusy1
    oid: 1.3.6.1.4.1.9.2.1.57.0
    type: gauge
    help: CPU utilization in the past 1 minute
  - name: avgBusy2
    oid: 1.3.6.1.4.1.9.2.1.58.0
    type: gauge
    help: CPU utilization in the past 5 minute
  - name: MemoryPoolFree
    oid: 1.3.6.1.4.1.9.9.48.1.1.1.6.1
    type: gauge
    help: ciscoMemoryPoolFree
  - name: MemoryPoolUsed
    oid: 1.3.6.1.4.1.9.9.48.1.1.1.5.1
    type: gauge
    help: ciscoMemoryPoolUsed
......

在 Linux 系统中使用 Docker 来运行 SNMP Exporter 可以使用如下脚本

#!/bin/bash

docker run -d --name snmp-exporter  --restart=always -m 1g \
    --volume /erdong/snmp-exporter/conf:/config \
    --network host prom/snmp-exporter:v0.20.0 \
    --web.listen-address :9107 \
    --config.file=/config/snmp.yml

在 Linux 系统部署二进制文件,使用系统的 Systemd 来控制服务启停,系统服务文件可以这么写, 该脚本源自官方提供的脚本,相比于官方脚本增加了SNMP Exporter 运行端口的指定。文件 snmp_exporter.service 的内容如下:

[Unit]
Description=SNMP Exporter
After=network-online.target

# This assumes you are running snmp_exporter under the user "prometheus"

[Service]
User=prometheus
Restart=on-failure
ExecStart=/usr/local/prometheus/snmp_exporter/snmp_exporter --config.file=/usr/local/prometheus/snmp_exporter/snmp.yml --web.listen-address=:9116

[Install]
WantedBy=multi-user.target

起动好以后,我们可以访问 http://localhost:9116 来查看启动的 SNMP Exporter ,页面上会显示 TargetModuleSubmitConfig 这几个选项和按钮。

Target 中填写交换机的地址,Module 里选择对应的模块,然后点击 Submit 这样可以查到对应的监控指标,来验证采集是否成功。

或者使用 curl 命令来验证,命令格式如下:

curl http://localhost:9116/snmp?module=if_mib&target=192.168.2.2

点击 Config 会显示当前 snmp.yml 的配置内容。

如果上边验证没有问题,那么我们就可以配置 Prometheus 进行采集了。

Prometheus 配置

  - job_name: NET-SW
    static_configs:
      - targets: 
          - 192.168.2.2  # 思科交换机的 IP 地址
    metrics_path: /snmp
    params:
      module: 
        - if_mib  # 如果是其他设备,请更换其他模块。
      community:
        - xxxxxx  #  指定 community,当 snmp_exporter snmp.yml 配置文件没有指定 community,此处定义的 community 生效。
    relabel_configs:
      - source_labels: [__address__]
        target_label: __param_target
      - source_labels: [__param_target]
        target_label: instance
      - target_label: __address__
        replacement: 192.168.1.2:9116  # SNMP Exporter  的地址和端口

配置好 Prometheus 以后启动 Prometheus 服务 ,就可以查到 Cisco 交换机的监控信息了。

接下来就 Prometheus 配置告警规则,Grafana 进行画图了。这些操作和其他组件并无区别,就不再赘述。

手动生成 snmp.yml 配置文件

上边在配置 SNMP Exporter 的配置文件的时候,使用了官方提供的默认的 snmp.yml ,有些设备官方的配置里并没有支持,这个时候就需要通过 MIB 文件来自己生成了,接下来我们看看这个配置文件怎么生成。

官方当前的 snmp.yml 支持 如下这些模块[2021.04.28]

apcups  : 一般用于 UPS 监控
arista_sw
cisco_wlc : 一般用于 ap 监控
ddwrt  : 一般用于软路由
if_mib  : 一般用于网络设备。该MIB描述了网络接口子层的通用表项。是MIB-II中ifTable的升级版本,也是对RFC1573扩展定义的具体说明。IF-MIB包含了一组与网络设备的通用接口相关的管理对象。这些管理对象适用于所有的网络接口,与接口上使用的通信介质合协议的类型无关。IF-MIB也定义了用于特殊介质和低层协议栈(子网层或更低层)的管理对象。
infrapower_pdu
keepalived
kemp_loadmaster
liebert_pdu
mikrotik
nec_ix
paloalto_fw
printer_mib
raritan
servertech_sentry3
servertech_sentry4
synology
ubiquiti_airfiber
ubiquiti_airmax
ubiquiti_unifi
wienner_mpod

多机器不同模块如何采集

  - job_name: snmp
    scrape_interval: 30s # 覆盖全局默认值
    scrape_timeout: 5s # 覆盖全局默认值
    file_sd_configs:
      - files:
        - /etc/prometheus/file_sd/snmp_device.yml # 指定 snmp 服务发现配置文件路径
    metrics_path: /snmp
    params:
      module:
      - if_mib   # 指定默认采集 MIB 模块的名称
      community:
      - xxxxx  指定 community,当 snmp_exporter snmp.yml 配置文件没有指定 community,此处定义的 community 生效。 缺省值一般是 public 。
    relabel_configs:
    - source_labels:
      - __address__
      target_label: __param_target
    - source_labels:
      - __param_target
      target_label: instance
    - replacement: snmp_exporter:9116
      target_label: __address__
    - source_labels:  # 从目标中获取MIB模块名称
      - mib
      target_label: __param_module

snmp_device.yml 的内容参照如下格式即可。我在下面的示例中添加了architecture与model等变量,这些变量prometheus获取目标信息是,会作为目标的标签与目标绑定。

[
    {
        "labels": {
            "mib": "if_mib",
            "brand": "Huawei",
            "hostname": "BJ-LG-HW5328",
            "model": "S5328C-EI"
        },
        "targets": [
            "192.168.100.1"
        ]
    },
    {
        "labels": {
            "mib": "if_mib",
            "brand": "Huawei",
            "hostname": "SH-GQ-HW9306CSS",
            "model": "Quidway S9306"
        },
        "targets": [
            "192.168.100.2"
        ]
    },
    {
        "labels": {
            "mib": "if_mib",
            "brand": "Huawei",
            "hostname": "BJ-LG-HW9306CSS",
            "model": "Quidway S9306"
        },
        "targets": [
            "192.168.100.3"
        ]
    },
    {
        "labels": {
            "mib": "if_mib",
            "brand": "Huawei",
            "hostname": "GZ-RMZ-HW9306CSS",
            "model": "Quidway S9306"
        },
        "targets": [
            "192.168.100.4"
        ]
    }
]

ifOutOctets 和 ifInOctets 的指标说明,这是一个历史 http://www.net-snmp.org/docs/mibs/interfaces.html

  1. 获取MIB可以在下面的 GitHub 里面找。这个里面有很多基础的MIB

https://github.com/librenms/librenms/tree/master/mibs

results matching ""

    No results matching ""