自动发现(LLD)提供了一种在计算机上为不同实体自动创建监控项,触发器和图形的方法。
例如,Zabbix可以在你的机器上自动开始监控文件系统或网络接口,而无需为每个文件系统或网络接口手动创建监控项;还可以配置Zabbix根据定期执行发现后的得到实际结果,来移除不需要的监控。

除了 Linux 系统自带的发现字段外,还支持通过 snmp OID 来进行自动发现

用户可以自己定义发现类型,只要脚本的返回值是遵循特定的 JSON 格式。

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


下面表达的 zabbix 内置关键字 可以理解为 zabbix 底层的一个函数/接口,用户可以通过调用这个函数/接口(或调用时为其传参)来获得指定格式的值;如果需要自定义发现规则, zabbix 内置关键字 可以是用户自己编写的脚本/函数/接口。

SNMP OID 自动发现

以一个通过 SNMP 发现接口入方向流量的例子作为解析,首先创建一个模板:
在这里插入图片描述
在这里插入图片描述
然后找到刚才创建的模板,进行编辑:
在这里插入图片描述
进入模板后,创建一个自动发现规则:
在这里插入图片描述
填入如下内容:
在这里插入图片描述

上图中:

  • 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 为字典的键,值为字典组成的列表,字典中为用户自定义的变量和根据关键字获取到的值。(实际测试,自定义的脚本只有值(字典组成的列表)也是可以的)。


接下来就是添加【监控项原型】,原型顾名思义就是一个模板,用来生成一系列监控项。
![在这里插入图片描述](https://img-blog.csdnimg.cn/efe96158f33b4d03a57c91d1a0eace72.png

上图中:

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

自动发现规则 + 监控项原型,两者共同工作,原理大致为:

  1. discovery 获得 SNMPINDEX 和 IFDESCR 对应信息,如
    { {#SNMPINDEX}: 1, {#IFDESCR}: “G1/0/1”,
    {#SNMPINDEX}: 2, {#IFDESCR}: “G1/0/2”}

  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/3if.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)

脚本有两个功能:

  • 不加参数运行时输出自定义变量列表,可以作为【自动发现规则】的 key
  • 加参数运行时输出指定 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

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

添加完成后,点进规则里面,添加【监控项原型】
在这里插入图片描述

在这里插入图片描述

添加完成后,手动执行一下发现规则:
在这里插入图片描述

查看自动发现的监控项:
在这里插入图片描述

查看获取到的数据:
在这里插入图片描述

参考资料:https://www.zabbix.com/documentation/5.0/zh/manual/discovery/low_level_discovery

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐