之前用Zabbix来监控,grafana来绘图,但是发现zabbix经常会出现绘图中断的情况,没有找到解决方案,所以想换个监控程序,首先想到的是nagios,但是nagios和grafana集成度可能不算太高,需要使用其他数据库。于是搜索发现Prometheus也能监控,之前用Prometheus主要是监控服务器,没想到配合snmp_exporter也挺好用,于是开始琢磨这套监控。
prometheus主要是一个数据采集器,需要监控的设备清单需要配置在Prometheus上,通过snmp_exporter来获取相关信息,并转化为Prometheus能够理解的内容,然后在通过Grafana进行绘图展示。
安装grafana及prometheus
建议从官网下载最新安装,否则部分新支持的特性可能无法使用,也可直接通过apt源安装
apt isntall grafana prometheus net-snmp snmp -y
snmp用于测试snmp是否配置成功
安装snmp_exporter
github地址https://github.com/prometheus/snmp_exporter
一定一定要使用最新版本的程序,否则新特性无法使用,如果你在网上看到一个别人生成的mib文件无法使用,那么很可能就是你的snmp_exporter版本太旧导致。
下载完了解压放到相应目录,并添加自启动,我将配置文件放到了和prometheus一个目录,方便维护,并使用默认的snmp.yml文件进行启动。基本够用了,我只需要监控系统运行时长、接口状态,大部分厂商基本都把基础的snmp遵循共有标准设计的。
[Unit]
Description=Prometheus exporter for SNMP-enabled devices
Documentation=https://github.com/prometheus/snmp_exporter
After=network.target
[Service]
Restart=on-failure
User=prometheus
EnvironmentFile=/etc/default/snmp-exporter
ExecStart=/usr/bin/snmp-exporter --config.file=/etc/prometheus/snmp.yml
ExecReload=/bin/kill -HUP $MAINPID
[Install]
WantedBy=multi-user.target
配置Prometheus及snmp_exporter
# Sample config for Prometheus.
global:
scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
# scrape_timeout is set to the global default (10s).
# Attach these labels to any time series or alerts when communicating with
# external systems (federation, remote storage, Alertmanager).
external_labels:
monitor: 'example'
# Alertmanager configuration
alerting:
alertmanagers:
- static_configs:
- targets: ['localhost:9093']
# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:
# - "first_rules.yml"
# - "second_rules.yml"
# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:
- job_name: 'FW'
static_configs:
- targets:
- 172.31.1.253 # SNMP device.
- 172.31.1.254
metrics_path: /snmp
params:
auth: [public_v2]
module: [if_mib]
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 # The SNMP exporter's real hostname:port.
- job_name: 'SW'
scrape_interval: 15s
#scrape_timeout: 5s
file_sd_configs:
- files:
- "./device/sw.yml"
refresh_interval: 5s
metrics_path: /snmp
params:
auth: [public_v2]
module: [if_mib]
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: instance
- source_labels: [auth] # 使用auth 替换param的auth
target_label: __param_auth
- source_labels: [module] # 使用module 替换param的module
target_label: __param_module
- target_label: __address__
replacement: 127.0.0.1:9116 # The SNMP exporter's real hostname:port.
我没深入研究过这个配置文件,只简单记录,最简单的配置是要监控的设备,job部分为任务名称,比如我要监控防火墙,这里就是FW
,主机写到targets
部分,格式如上,scrape_interval(抓取频率)和evaluation_interval(规则评估频率)的时间根据需要进行修改,不要太频繁就行。 scrape_timeout是全局抓取超时时间,这个可以不设置,设置也不建议太短,至少15s起步,如果太短,你配置的主机太多且snmp主机太弱无法及时获取到相应设备的相应,那么会导致主机不在线抓取失败。
另一个配置主机方式是直接通过外部文件获取你要监控的设备列表,我个人理解这个适用于设备很多,需要单独维护一个清单的情况,不同主机需要监控不同模块的情况,且不同主机需要不同认证方式的情况?(我暂时没遇到,也许支持?)。主要配置就是job名称及如下部分,sw.yml单独贴出。
file_sd_configs:
- files:
- "./device/sw.yml"
sw.yml配置文件内容:
- labels:
mib: if_mib
targets:
- 172.17.1.1
- 172.17.1.40
- 172.17.1.41
- 172.17.1.42
- 172.17.1.43
snmp.yml开头加入如下格式的认证信息
# WARNING: This file was auto-generated using snmp_exporter generator, manual changes will be lost.
auths:
public_v1:
community: public
security_level: noAuthNoPriv
auth_protocol: MD5
priv_protocol: DES
version: 1
public_v2:
community: test
security_level: noAuthNoPriv
auth_protocol: MD5
priv_protocol: DES
version: 2
public_v3:
community: Huawei94laji
security_level: noAuthNoPriv
auth_protocol: MD5
priv_protocol: DES
version: 2
modules:
apcups:
public_vx随便写,主要是community要包含你在设备上面配置的内容,认证协议那些都要根据自己的配置进行修改。
自定义snmp.yml文件
如果你要监控的设备模块为非公有标准,比如设备的HA状态,路由条目等这些一般都为厂商私有MIB,那么你需要自己生成MIB文件,主要通过snmp_exporter里面的generator生成文件,需要找厂商拿到MIB文件,最好获取到对应的说明文档。
需要自己编译,安装对应组件,具体看官方文档把https://github.com/prometheus/snmp_exporter/tree/main/generator
apt-get install unzip build-essential libsnmp-dev golang
git clone https://github.com/prometheus/snmp_exporter.git
cd snmp_exporter/generator
make generator mibs
配置Grafana绘图
官方库已经有人共享出一些模板了,例如ID(10523)、ID(11169),导入模板的时候填数字ID进去就可以了,其实挺好用,但是不满足我的需求,我需要自定义。使用上面模板的时候也要根据自己的job名称等信息进行修改,才能正常绘图。
添加数据源
Grafana首页-连接-数据源,点添加数据源,选择Prometheus,填入相关信息即可。
创建变量
首先是创建一个仪表盘,然后添加可视化,可以先点保存也可以不保存,点击设置按钮进入配置页面。
我定义了如图三个变量
- Device主要是获取指定任务下的设备列表
- Interface主要获取设备下的接口
- Interface也是获取接口,但是获取方式不一样
详细说说各参数配置:
Device:
- Select variable type: Query
- Name: Device
- Show on dashboard: Nothing
- Data source: prometheus
- Query Type:Label Values
- Label: instance
- Metric:不选
- Label filters: job=FW
- Sort: Natural(asc)
Refresh: On dashboard load
FW是我的job名称,下面有个正则匹配,不需要填,如果会正则也可以填,Sort根据自己需求选择
Interface:
- Select variable type: Query
- Name: Interface
- Show on dashboard: Nothing
- Data source: prometheus
- Query Type:Label Values
- Label: ifName
- Metric:不选
- Label filters: instance=$Device
- Sort: Natural(asc)
- Refresh: On dashboard load
Selection options: Include All option
$Device就是上面设置的Device变量
Interfaces:
- Select variable type: Query
- Name: Interfaces
- Show on dashboard: Nothing
- Data source: prometheus
- Query Type:Query result
- Query: ifHCInOctets{instance="$Device"}
- Regex:
.*ifName="((?!fortilink|ha|l2t.root|mgmt|modem|naf.root|ssl.root|Callcenter|x1|x2|x7|x8).+?)",.*
- Sort: Natural(asc)
- Refresh: On dashboard load
Selection options: Include All option
.*ifName="((?!fortilink|ha|l2t.root|mgmt|modem|naf.root|ssl.root|Callcenter|x1|x2|x7|x8).+?)",.*
是一个正则表达式,这里在获取ifName的同时过滤掉了从fortilink到X8的这些打头的接口名称。如果想要获取指定的网络接口名称可使用如下正则表达式.*ifName="((?:Aggregate|Bridge-Aggregation).+?)",.*
比如这个表达式只获取了Aggregate和BridgeAggregation开头的接口名称
上面的三个变量根据需求进行调用。
创建绘图及图表
添加运行天数
添加可视化,类型选择Stat
。
直接点击右边的code,进入代码模式,填入下面内容:
sysUpTime{instance="$Device"}/100/(24*3600)
也可切换到Builder模式查看可视化选择条件。Options中的Legend选择Custom,填入对应名称,比如sysUpTime,强烈建议改,否则可能在调用到这个查询结果的时候在图表上会显示一串超长的返回内容值。Formate根据图像类型选择,一般默认为Time Series。Type一般默认Range。
最右边可以改Title,Value Options中的show选择Calculate,下面选Last,Fields选择Numeric Fields,Unit自己选一个或者自己输入,这里我填入自定义的Days,其他都是细微调整,自己根据想法调整。
添加可自动绘制不同接口的流量图
只需要添加一个,其他接口的图他会自动绘制出来,不需要再手动添加,这也是前面设置变量的作用,还是添加可视化,类型选择Time Series
添加A、B两个查询条件,A为入方向流量,B为出方向流量,条件如下:
irate(ifHCInOctets{instance='$Device',ifName='$Interfaces'}[5m]) * 8
irate(ifHCOutOctets{instance='$Device',ifName='$Interfaces'}[5m]) * 8
还是那句话Options中的Legend选择Custom,填入对应名称,强烈建议改。这里分别填入方向流量
和出方向流量
,其他默认
最右边Titile填$Interfaces
,下面Repeat options中的Repeat by variable选择Interfaces,Max per row根据你一行想展示几个图选择,2-4个最佳。
下面的Legend中的Values,选择Max和Last可显示最大值和最新值,Graph styles根据喜好选择,单位选择bits/sec(IEC),这个可能选得不对,但是单位大致对上就行。
添加表格类型图
这对我来说可能是最难的一个点了,因为别人的模板用的是老的表格,没有参考意义,需要自己研究。样式如下
- 创建可视化,选择表格。
创建查询条件
irate(ifHCInOctets{instance='$Devices'}[5m]) * 8 irate(ifHCOutOctets{instance='$Devices'}[5m]) * 8 ifHighSpeed{instance='$Devices'}/1000 ifOperStatus{instance='$Devices'} ifAdminStatus{instance='$Devices'} ifInErrors{instance="$Devices"} ifOutErrors{instance="$Devices"} ifInDiscards{instance="$Devices"} ifOutDiscards{instance="$Devices"}
这里的难点是如何在一个表中显示所有接口的信息,其实很简单就是不要加ifName='$Interfaces'这个条件就行,这样查询的时候就会查询这台设备所有的接口。以上所有查询条件Options中的Format都需要选择为Table
创建数据转换条件
由于查询出的数据有很多接口,且是单独的表格,所以需要将所有数据合并为一个表格。
- 创建
Merge Series/tables
条件 - 创建
Organize fileds by name
条件
这里隐藏掉不需要展示的值,并将对应的值重命名(也可不做最终以Options中的Legend值显示),如果前面没改,那么可以建立Override添加Display name属性进行名字修改覆盖。
创建Group by条件
选择根据接口编号排序,这个选group by,其他选择计算,并选择last。这一步其实我很疑惑,我在做另一个图表的时候发现只做前两步就可以实现效果了,但是做这个图表的时候,只做前两步发现同一个接口会展现很多行数据,所以一定要 做Group by这个条件。可以根据世纪情况看要不要做。
- 创建
右边标题随便起,不需要repeat,单位不要选,单独设置override对值进行单位设置,并对值进行映射,不如接口管理状态查询有1、2两个值分别对应up和down。可以设置值映射,1为up,2为down,在图表中就不显示1和2而是up和down,并可以根据值的阈值设置起颜色。
总结
整个图表我最需要的就是接口重复绘图和图表生成,比较难的就是图表生成,没有比较有用的参考资料。可以结合图表生成条件,自己建立更多好看的展示图。即兴记录,如有漏记、错记需自行补充更正,仅为自己备忘使用。
本文由 Ethan 创作,采用 知识共享署名4.0 国际许可协议进行许可。
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名。