Zabbix进阶:自动发现原理、规则与原型搭建详解

本文深入剖析 Zabbix 的低级别发现(LLD)功能,以及如何借助 SNMP 自动发现网络接口并监控入方向流量。通过具体示例,详细阐释 LLD 规则的配置,涵盖net.if.discovery和ifInOctets键的运用,以及如何利用自定义脚本实现 ping 响应的自动发现。自定义脚本返回的 JSON 数据需遵循 Zabbix 规定格式,用于生成监控项原型。最后,展示在 Zabbix 中设置和应用这些规则的具体步骤。

自动发现(LLD)为在计算机上为不同实体自动创建监控项、触发器和图形提供了有效途径。例如,Zabbix 能够在机器上自动启动对文件系统或网络接口的监控,无需为每个文件系统或网络接口手动创建监控项;还可配置 Zabbix 依据定期执行发现后的实际结果,移除不必要的监控。

除 Linux 系统自带的发现字段外,Zabbix 还支持通过 snmp OID 进行自动发现。用户可自行定义发现类型,只要脚本返回值遵循特定的 JSON 格式即可。

配置自动发现过程通常如下:首先,用户在 “配置”→“模板”→“发现” 列中创建一个发现规则。该发现规则包含(1)发现必要实体(如文件系统或网络接口)的项;(2)应根据该项的值创建的监控项、触发器和图形的原型。

Zabbix 内置关键字可理解为 Zabbix 底层的函数 / 接口,用户能通过调用这个函数 / 接口(或在调用时传参)获取指定格式的值;若需自定义发现规则,Zabbix 内置关键字可以是用户自行编写的脚本 / 函数 / 接口。


SNMP OID 自动发现

以通过 SNMP 发现接口入方向流量的示例进行解析。首先创建一个模板:

63nedgA367bee03141ac2.png

GDkfOc1W67bee0507249f.png

然后找到刚创建的模板并进行编辑:

aD9hr0Uq67bee06d9761b.png

进入模板后,创建一个自动发现规则:

1gjICNC167bee0915dd8d.png

填入如下内容:

FcMn9VqL67bee0b17dfde.png


图中:

  • Key 字段:net.if.discovery 用于标识自动发现规则的名称,一般采用 “.” 分隔的字符,以便理解规则的作用(当然,也可使用自己觉得顺口好记的名字或分隔符,如 “_”“-” 等)。
  • SNMP OID 字段:discovery 是 Zabbix 内置关键字,可视为一个函数,将后面 “[]” 的值作为参数传入,参数格式由 discovery 预先规定(若为自定义函数,可按自己的喜好编写)。其中,{#IFDESCR} 为变量名称,1.3.6.1.2.1.2.2.1.2 为获取该变量值的 SNMP OID 值,执行类似 snmpwalk 的操作,获取设备信息。


这个步骤用于获取自动发现规则中的键值:discovery [{#IFDESCR},1.3.6.1.2.1.2.2.1.2,{#IFTYPE},1.3.6.1.2.1.2.2.1.3] 的行为大致等同于:

{#IFDESCR} = snmpwalk -v 2c -c public 192.168.1.1 1.3.6.1.2.1.2.2.1.2
{#IFTYPE} = snmpwalk -v 2c -c public 192.168.1.1 1.3.6.1.2.1.2.2.1.3


由于 snmpwalk 遍历出的值较多,假设 snmpwalk 的结果如下:

$ snmpwalk -v 2c -c public 192.168.1.1 1.3.6.1.2.1.2.2.1.2
1.3.6.1.2.1.2.2.1.2.1 = STRING: G1/0/1
1.3.6.1.2.1.2.2.1.2.2 = STRING: G1/0/2
1.3.6.1.2.1.2.2.1.2.3 = STRING: G1/0/3
$ snmpwalk -v 2c -c public 192.168.1.1 1.3.6.1.2.1.2.2.1.3
1.3.6.1.2.1.2.2.1.3.1 = STRING: route
1.3.6.1.2.1.2.2.1.3.2 = STRING: bridge
1.3.6.1.2.1.2.2.1.3.3 = STRING: ppp


snmp 一般通过索引定位,Zabbix 内置关键字 discovery 为返回结果自动添加了索引,所以 discovery [{#IFDESCR},1.3.6.1.2.1.2.2.1.2,{#IFTYPE},1.3.6.1.2.1.2.2.1.3] 最终获取的结果为(JSON 格式也是预先定义好的,我们只需填充值):

{
"data": [
{
"{#SNMPINDEX}": "1",
"{#IFDESCR}": "G1/0/1",
"{#IFTYPE}": "route"
},
{
"{#SNMPINDEX}": "2",
"{#IFDESCR}": "G1/0/2",
"{#IFTYPE}": "bridge"
},
{
"{#SNMPINDEX}": "3",
"{#IFDESCR}": "G1/0/3",
"{#IFTYPE}": "ppp"
}
]
}

Zabbix 规定自动发现规则必须是上述 JSON 格式,即以 “data” 为字典的键,值为字典组成的列表,字典中包含用户自定义的变量和根据关键字获取的值。(实际测试表明,自定义脚本只有值(字典组成的列表)也是可行的)。


接下来添加【监控项原型】,原型即模板,用于生成一系列监控项。

UYwZnZs167bee10bbaa38.png

图中:

  • Key 字段:if.in.bits 用于标识这个监控项的名称(同 net.if.discovery),后面跟着自动发现规则中定义的变量,以便在自动生成监控项时区分不同的接口。
  • SNMP OID 字段:使用 1.3.6.1.2.31.1.1.1.6 这个 OID,再加上具体接口的 index,即内置 discovery 自动生成的变量 {$SNMPINDEX},来获取指定接口的入方向流量。


自动发现规则与监控项原型协同工作,原理大致如下:

discovery 获取 SNMPINDEX 和 IFDESCR 的对应信息,如:

{#SNMPINDEX}: 1,{#IFDESCR}: "G1/0/1",

{#SNMPINDEX}: 2,{#IFDESCR}: "G1/0/2"}


自动发现规则获取接口列表后,根据监控项原型中的 SNMP OID 获取流量,为当前设备的其中一个接口生成监控项,如:if.in.bits.G1/0/1:102400

① 监控项的 key:if.in.bits [G1/0/1] 由第一步自动发现和监控项原型 key 拼接而成。

② 流量信息 102400 由 1.3.6.1.2.31.1.1.1.6.1 这个 OID 获取(类似 snmpwalk 操作)。


将这个自动发现规则应用到设备上后,可获得三个监控项,分别是:

名称key 流量获取方法
Incoming traffic on interface G1/0/1if.in.bits[G1/0/1]
通过 OID 1.3.6.1.2.31.1.1.1.6.1 获取
Incoming traffic on interface G1/0/2if.in.bits[G1/0/2]
通过 OID 1.3.6.1.2.31.1.1.1.6.2 获取
Incoming traffic on interface G1/0/3if.in.bits[G1/0/3]
通过 OID 1.3.6.1.2.31.1.1.1.6.3 获取

以上就是通过 snmp oid 获取自动发现接口入方向流量的示例。


自定义自动发现规则

为加深理解,可手动添加一个自定义发现规则。

以自动返回 ping 结果的自动发现规则为例,首先编写如下脚本,返回的 JSON 需遵循固定格式:

#!/root/bin/python3
import sys
import json
import subprocess
dns_ip_map = {
"baidu": "180.76.76.76",
"ali": "223.5.5.5",
"tencent": "119.29.29.29",
}
def ping(ip):
cmd = "ping -c 2 -W 2 %s" % (ip)
result = subprocess.getstatusoutput(cmd)[0]
return result
if __name__ == "__main__":
# 不加任何参数的时候,返回自动发现的变量,遵循指定的JSON格式,经zabbix 5.0版本测试
# 仅返回列表,没有`data`作为键也可以
if len(sys.argv) == 1:
lld_key_list = [
{"{#DNS_IP}": ip} for ip in dns_ip_map.keys()
]
print(json.dumps(lld_key_list))
# 传入参数的时候,即:将变量{$DNS_IP}对应的值传入的时候,可以获取到对应的执行结果
if len(sys.argv) == 2:
result = ping(dns_ip_map.get(sys.argv[1]))
print(result)


脚本具备两个功能:

  • 1. 不加参数运行时输出自定义变量列表,可作为【自动发现规则】的 key。
  • 2. 加参数运行时输出指定 ip 的 ping 结果,ip 不存在时返回 - 1,可作为【监控项原型】的 key。


执行结果如下:

# 直接执行
python3 dns_ping.py
[{"{#DNS_IP}": "baidu"}, {"{#DNS_IP}": "ali"}, {"{#DNS_IP}": "tencent"}]
# 加参数,网络是通的,返回0
python3./dns_ping.py baidu
0
# 加参数,ip不存在,返回-1
python3./dns_ping.py baidu111
-1

一般情况下,实现这两个功能的脚本应分开编写,本示例为简化操作放在了一起。


接下来添加自动发现规则,以在 agent 添加自定义 key 为例:

# 修改agent的配置文件,添加客户端自定义key,允许传参
AllowRoot=1
UserParameter=dns_ping[*],/root/dns_ping.py $1


页面上添加自动发现规则:

UahDnWAA67bee258e5874.png

添加完成后,点进规则里面,添加【监控项原型】

OfomYOGx67bee269b0b89.png

添加完成后,手动执行一下发现规则:

upISxiaJ67bee2896a542.png

查看自动发现的监控项:

YnKolPVP67bee29d7068a.png

查看获取到的数据:

NoNZvJZu67bee2b19fa52.png

0 条评论

请先 登录 后评论
乐维君
乐维君

415 篇文章

作家榜 »

  1. 乐维君 415 文章
  2. YOHOHO 14 文章
  3. 机灵小和尚 13 文章
  4. 细雨闲花 12 文章
  5. 我是一只小菜鸡 12 文章
  6. 。。。 9 文章
  7. 御前侍卫张五哥 9 文章
  8. 小黄人 8 文章