参考文档:
什么是 SNMP
SNMP: SNMP 是(Simple Network Management Protocol)简单网络管理协议的缩写。SNMP 用于通过设置某些属性的值来管理网络设备(通常称为托管对象),并通过从设备轮训必要的指标来监控网络设备。
SNMP 工作原理
SNMP 包括简单的客户端-服务器架构。在你的网络管理解决方案上运行的 SNMP 客户端将负责轮询数据或设置数据。运行在你实际设备上的 SNMP 服务器将响应 SNMP 客户端的调用。默认情况下,在网络设备中不会打开 SNMP 代理。如果需要,网络管理员必须启用 SNMP。
需要了解 SNMP Mib 和 SNMP OID 才能使用 SNMP 并轮询我们需要的指标。
什么是 MIB 和 OID
MIB 代表管理信息库,是定义要管理的设备内被管理对象的属性的定义集合。MIB 文件以独立的格式编写,并且它们包含的对象信息是分层组织的。各种信息都可以通过 SNMP 访问。
OID 或 对象标识符是 MIB 中被管理对象的唯一标识符。通常,OID 是一长串数字,对节点进行编码,用点分隔。以下是一个 OID 的示例结构:
例如,要获取被管理设备的系统启动时间,可以轮询下面的 OID
1 | OID -1.3.6.1.6.3.10.2.1.3 |
OID -1.3.6.1.6.3.10.2.1.3
将返回自 SNMP 引擎上次以来的秒数。
所以,OID 是某个指标的唯一标识,MIB 是包含基于制造商的特征和组织的 OID 树。
SNMP 版本
- SNMP V1: 任何可以访问网络的人都可以轮询设备数据(较弱的安全性)
- SNMP V2: 包括在性能、安全性、机密性和经理对经理通信方面的改进。
- SNMP V3: 使数据加密成为可能。它还允许管理员在细粒度的基础上为 Managers 和 Agent 指定不同的身份验证要求。这可以防止未经授权的身份验证,并且可以选择用于要求对数据传输进行加密。因此能够设置身份验证和隐私参数,数据将仅由经过身份验证的 SNMP 服务器轮询,并且数据将以这种方式加密。
SNMP 操作
从托管设备中提取数据
- GetRequest: 获取特定 OID 的值;
- SetRequest: 设置特定 OID 的值;
- GetNextRequest: 从下一个 OID 获取值;
- GetBulkRequest: 批量获取 MIB 树的值;
将数据从受管设备推送到 SNMP 服务器
- Traps: Traps 将事件从网络设备发送到 Traps 服务器,以防止网络设备中发生的任何事件,例如: 接口关闭,VPN 关闭等。Traps 服务器的位置和凭据必须在每个要被监控的网络设备中进行配置。
更多有关 SNMP 操作的内容,请查看 SNMP Operations
使用 Prometheus 监控网络设备
Prometheus 是一个时间序列数据库,可以有效地存储随时间变化而变化的信息,以特定的方式查询,并比以往任何时候都更快地检索。
Prometheus 的特点
- 一个多维数据模型,具有由指标名称和键/值对标识的时间序列数据
- 一种灵活的查询语言来利用这种维度
- 时间序列收集通过 HTTP 上的拉模型发生
- 多种绘图模式和公开 API 以获取时间序列数据。
安装 Prometheus
Prometheus 的安装请参考 Linux 安装部署 Prometheus 服务
安装 SNMP Exporter
Exporter: Exporter 是一个库,它从源收集数据并将其转换为 Prometheus 服务器可以接受的格式;
SNMP Exporter: SNMP Exporter 是一种从受管设备收集数据并以 Prometheus 服务器可接受的格式公开数据的工具。
SNMP Exporter 是开源的,GitHub 仓库地址: prometheus/snmp_exporter
默认情况下,SNMP 导出器读取配置文件 snmp.yml
,并且配置包含要从设备访问/获取的 OID 和要使用的凭据 (如果它是 SNMP v2 或 SNMP v3)。
snmp.yml
配置文件不是手写的,因为配置中会指定大量 OID,并且命名和标记指标很复杂。所以我们可以使用生成器来生成 snmp.yml
配置。此配置生成器使用 NetSNMP 解析 MIB,并使用它们为 snmp_exporter 生成配置。
安装和使用生成器
由于对 NetSNMP 的动态依赖性,我们必须自己构建生成器。
安装 SNMP 工具以及依赖的库
1
yum install -y net-snmp net-snmp-utils net-snmp-libs net-snmp-devel golang p7zip*
下载生成器源码
1
go get github.com/prometheus/snmp_exporter/generator
构建生成器,SNMP Mibs 必须放在文件夹
$HOME/.snmp/mibs
中,这样 NetSNMP 就可以使用它。1
2
3cd go/src/github.com/prometheus/snmp_exporter/generator/
go build
make mibs #如果已下载相关设备厂家提供的mib文件则无需再次生成mib库,跳过此步期间可能需要梯子才能进行构建
如果报fatal: git fetch-pack: expected shallow list
错误,是 git 版本 太低导致,解决方法如下1
2yum install http://opensource.wandisco.com/centos/7/git/x86_64/wandisco-git-release-7-2.noarch.rpm
yum update git
生成 snmp 配置文件
去相关交换机厂商官方地址下载相关mib文件
将获取的 mib 文件上传至
${GOPATH-$HOME/go}/src/github.com/prometheus/snmp_exporter/generator
编写
generator.yml
配置文件。generator.yml
提供模块列表。最简单的模块只是一个 name 和一组 walk 的 oid,如下所示1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54modules:
module_name: # 模块名称。自己定义,可以拥有任意数量的模块。
walk: # 需要 walk 的 OID 列表,也可以是 SNMP 的对象名称或者特定实例
- 1.3.6.1.2.1.2 # 等同于 "interfaces"
- sysUpTime # 等同于 "1.3.6.1.2.1.1.3"
- 1.3.6.1.2.1.31.1.1.1.6.40 # 索引为 "40" 的 "ifHCInOctets" 实例
version: 2 # 声明使用的 SNMP 版本,默认为 2,1 使用 GETNEXT 方法,2 和 3 使用 GETBULK 方法
max_repetitions: 25 # 使用 GET/GETBULK 请求多少对象,默认为 25。对于有缺陷的设备,可能需要减少。
retries: 3 # 重试失败请求的次数,默认为 3。
timeout: 5s # 每个单独的 SNMP 请求的超时时间,默认为 5 秒。
auth:
community: public # community 与 SNMP v1 和 v2 一起使用。默认为“公共”。
# v3 具有不同且更复杂的设置。需要哪些取决于 security_level。
# NetSNMP 命令的等效选项,如 snmpbulkwalk 和 snmpget 也在下面被列出。
username: user # 必填,无默认。 NetSNMP 的 -u 选项。
security_level: noAuthNoPriv # 默认为 noAuthNoPriv。NetSNMP 的 -l 选项。可以是 noAuthNoPriv、authNoPriv 或 authPriv;
password: pass # 没有默认值。也称为 authKey,NetSNMP 的 -A 选项。如果 security_level 是 authNoPriv 或 authPriv,则为必需项。
auth_protocol: MD5 # MD5、SHA、SHA224、SHA256、SHA384 或 SHA512。默认为 MD5。NetSNMP 的 -a 选项。如果 security_level 是 authNoPriv 或 authPriv,则使用。
priv_protocol: DES # DES、AES、AES192 或 AES256。默认为 DES。 NetSNMP 的 -x 选项。在 security_level 为 authPriv 时使用。
priv_password: otherPass # 没有默认值。也称为 privKey,NetSNMP 的 -X 选项。如果 security_level 为 authPriv,则为必需
context_name: context # 没有默认值。 NetSNMP 的 -n 选项。如果在设备上配置了上下文,则为必需。
lookups: # 要执行的查找的可选列表。`keep_source_indexes` 的默认值为 false。要使用此选项,索引必须是唯一的。
# 如果表的索引是 bsnDot11EssIndex,通常标签就是来自该表的结果指标。否则,使用索引来查找 bsnDot11EssSsid 表条目并创建一个bsnDot11EssSsid 标签有了那个价值。
- source_indexes: [bsnDot11EssIndex]
lookup: bsnDot11EssSsid
drop_source_indexes: false # 如果为 true,则删除此查找的源索引标签。当新索引是唯一的时,这可以避免标签混乱。
overrides: # 允许每个模块覆盖 MIB 位
metricName:
ignore: true # 从输出中删除指标。
regex_extracts:
Temp: # 将创建一个新指标,将其附加到 metricName 以成为 metricNameTemp。
- regex: '(.*)' # 正则表达式,从返回的 SNMP walks 值中提取一个值。
value: '$1' # 结果将被解析为 float64,默认为 $1。
Status:
- regex: '.*Example'
value: '1' # 正则表达式匹配且值解析的第一个条目获胜。
- regex: '.*'
value: '0'
type: DisplayString # 覆盖度量类型,可能的类型有:
# Gauge:一个带有gauge 类型的整数。
# counter:一个类型为 counter 的整数。
# OctetString:位串,呈现为 0xff34。
# DateAndTime:一个 RFC 2579 DateAndTime 字节序列。如果设备没有时区数据,则使用 UTC。
# DisplayString:ASCII 或 UTF-8 字符串。
# PhysAddress48:一个 48 位 MAC 地址,呈现为 00:01:02:03:04:ff。
# Float:一个 32 位浮点值,类型为gauge。
# Double:一个 64 位浮点值,类型为gauge。
# InetAddressIPv4:一个 IPv4 地址,呈现为 1.2.3.4。
# InetAddressIPv6:一个 IPv6 地址,呈现为 0102:0304:0506:0708:090A:0B0C:0D0E:0F10。
# InetAddress:符合 RFC 4001 的 InetAddress。必须以 InetAddressType 开头。
# InetAddressMissingSize:由于索引中没有大小而违反了 RFC 4001 的第 4.1 节的 InetAddress。必须以 InetAddressType 开头。
# EnumAsInfo:为其创建单个时间序列的枚举。适用于恒定值。
# EnumAsStateSet:每个状态具有时间序列的枚举。适用于可变的低基数枚举。
# Bits: 一个 RFC 2578 BITS 构造,它产生一个 StateSet,每个位都有一个时间序列。generator.yml 需要注意两点
- walk 下面写的是你需要查询的信息所对应的 oid,这个像华为交换机都是可以在原厂文档上查的到的;要监控交换机的端口流量、状态,CPU 使用率,内存状态,温度等,关键是找出与之相对应的 oid。获取到的监控信息相关的 oid 可通过
snmpwalk
过滤查询,snmpwalk 命令格式如下
1
2
3snmpwalk -v "snmp版本" -c "coummunity" IP oid(可选)
# 如下
snmpwalk -v 2c -c test1234 192.168.1.100 1.3.6.1.4.1.2011.5.25.31.1.1.1.1.11|grep -v 0$- 还有一点就是 community 这个要写自己设置的团体名,如果不知道可以自己手动设置一个,我这里设置的是test1234。其他的地方基本不需要修改,模块名也可以改,后面使用 snmp 查的时候,以及写 prometheus 配置文件的时候对应也写自己刚刚修改的 mib 名称就好。
- walk 下面写的是你需要查询的信息所对应的 oid,这个像华为交换机都是可以在原厂文档上查的到的;要监控交换机的端口流量、状态,CPU 使用率,内存状态,温度等,关键是找出与之相对应的 oid。获取到的监控信息相关的 oid 可通过
以下以 ikuai 路由器为例,将下载的私有 MIB 放到 mibs 目录,编写 generator.yml 文件,内容如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37modules:
# Default IF-MIB interfaces table with ifIndex.
if_mib:
walk: [sysUpTime, interfaces, ifXTable]
version: 2
auth:
community: public-route
lookups:
- source_indexes: [ifIndex]
lookup: ifAlias
- source_indexes: [ifIndex]
# Uis OID to avoid conflict with PaloAlto PAN-COMMON-MIB.
lookup: 1.3.6.1.2.1.2.2.1.2 # ifDescr
- source_indexes: [ifIndex]
# Use OID to avoid conflict with Netscaler NS-ROOT-MIB.
lookup: 1.3.6.1.2.1.31.1.1.1.1 # ifName
overrides:
ifAlias:
ignore: true # Lookup metric
ifDescr:
ignore: true # Lookup metric
ifName:
ignore: true # Lookup metric
ifType:
type: EnumAsInfo
IKUAI-MIB:
walk:
- apNumber
- apId
- apMac
- apIpAddress
- apVersion
- apChannel
- apUptime
version: 2
auth:
community: public-route运行 generator 生成 snmp.yml 文件
1
2
3
4
5
6
7
8export MIBS=IKUAI-MIB # IKUAI-MIB 这个模块名称可以从下载的 IKUAI-MIB.mib 文件中查看
./generator generate # 生成 snmp.yml 文件
level=info ts=2021-09-20T01:57:15.820Z caller=net_snmp.go:144 msg="Loading MIBs" from=$HOME/.snmp/mibs:/usr/share/snmp/mibs
level=info ts=2021-09-20T01:57:15.917Z caller=main.go:52 msg="Generating config for module" module=if_mib
level=info ts=2021-09-20T01:57:15.928Z caller=main.go:67 msg="Generated metrics" module=if_mib metrics=40
level=info ts=2021-09-20T01:57:15.928Z caller=main.go:52 msg="Generating config for module" module=IKUAI-MIB
level=info ts=2021-09-20T01:57:15.937Z caller=main.go:67 msg="Generated metrics" module=IKUAI-MIB metrics=7
level=info ts=2021-09-20T01:57:15.967Z caller=main.go:92 msg="Config written" file=/root/go/src/github.com/prometheus/snmp_exporter/generator/snmp.yml
安装配置 SNMP Exporter
从 Github 下载安装 SNMP Exporter
1
2
3wget https://github.com/prometheus/snmp_exporter/releases/download/v0.20.0/snmp_exporter-0.20.0.linux-amd64.tar.gz
tar xvf snmp_exporter-0.20.0.linux-amd64.tar.gz
mv snmp_exporter-0.20.0.linux-amd64 /usr/local/snmp_exporter将生成 snmp.yml 文件拷贝到 snmp_exporter 应用的根目录,替换默认的 snmp.yml 文件,测试并验证 snmp_exporter
1
2
3
4
5
6
7cp snmp.yml /usr/local/snmp_exporter/
cd /usr/local/snmp_exporter/
./snmp_exporter
level=info ts=2021-09-20T02:09:12.592Z caller=main.go:152 msg="Starting snmp_exporter" version="(version=0.20.0, branch=HEAD, revision=c33572b6c8c8e43a479fde0f9fa8ac86e15598bc)"
level=info ts=2021-09-20T02:09:12.593Z caller=main.go:153 build_context="(go=go1.15.8, user=root@eebd39e6960e, date=20210212-11:37:48)"
level=info ts=2021-09-20T02:09:12.607Z caller=main.go:246 msg="Listening on address" address=:9116
level=info ts=2021-09-20T02:09:12.608Z caller=tls_config.go:191 msg="TLS is disabled." http2=false打开浏览器,测试访问
http://192.168.64.11:9116
,在 Target 中输入路由器地址,模块名称,然后点击 Submit
创建snmp_exporter的system unit文件
1
2
3
4
5
6
7
8
9
10
11
12
13cat > /usr/lib/systemd/system/snmp_exporter.service<<EOF
[Unit]
Description=SNMP Exporter
After=network-online.target
# This assumes you are running snmp_exporter under the user "prometheus"
[Service]
Restart=on-failure
ExecStart=/usr/local/snmp_exporter/snmp_exporter --config.file=/usr/local/snmp_exporter/snmp.yml
[Install]
WantedBy=multi-user.target
EOF启动服务并配置开机启动
1
systemctl enable --now snmp_exporter.service
配置 Prometheus,添加抓取 snmp_exporter 的指标
- 在 prometheus.yaml 文件的最下面添加以下内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15# 以下是需要抓取的网络设备指标
- file_sd_configs:
- files:
- 'configs/networks.yml'
refresh_interval: 10s
job_name: 'Networks'
metrics_path: /snmp
metric_relabel_configs:
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: instance
- target_label: __address__
replacement: 192.168.55.11:9116- 创建 configs/network.yml 文件,内容如下
1
2
3
4
5- labels:
region: 'dg2'
type: 'route'
targets:
- '192.168.64.2'- 刷新 Prometheus 配置
1
curl -X POST http://localhost:9090/-/reload
在 Prometheus 页面查看 Targets,如下所示
在 Grafana 官网下载 SNMP Stats 模板,模板ID 为: 11169,然后导入 Grafana,稍加修改,效果如下所示