zabbix6自动化配置监控项监控GPU

关键词: zabbix 监控 GPU 监控项自动化注册 脚本监控服务

部署

部署具体细节就不详细展开了,我这里有三台机器,其中一台部署docker版的zabbix server
然后在这三台机器都部署zabbix agent2,
整体组成了这个三台机器的zabbix监控集群

配置

在server端的web console配置主机(host),配置监控项(item),我这边的服务器目前数量不多,暂时没有配置模板(template)
具体配置参考其他教程,或者官网用例

开发

这里我具体展开说下。
正常使用官方提供的监控项,可以监控机器的cpu / mem / desk / net 等等,但是没有监控到GPU,所以只能自己加监控项。
官方提供的简单的脚本监控,在zabbix_agent2.d做相关配置就能实现,但是这个一个监控项需要写一个脚本,我需要监控的一个机器就有40+的监控项,不太方便。所有我使用python开发一个脚本来实现所有的监控项的数据监控,然后在服务器起一个系统服务来做gpu的状态监控。
具体就是不经过zabbixagent处理,使用zabbix api实现监控数据的上传,然后在web console进行监控。
相关代码:

    def get_nv_info(self):
        self.packet = []
        pynvml.nvmlInit()
        device_count = pynvml.nvmlDeviceGetCount()
        self.packet.append(
            ZabbixMetric(self.hostname, 'gpu.num', device_count)
        )
        for i in range(device_count):
            handle = pynvml.nvmlDeviceGetHandleByIndex(i)
            gpu_name = pynvml.nvmlDeviceGetName(handle)
            mem_info = pynvml.nvmlDeviceGetMemoryInfo(handle)
            temperature = pynvml.nvmlDeviceGetTemperature(handle, 0)
            powerusage = pynvml.nvmlDeviceGetPowerUsage(handle)
            self.packet.extend(
                [ZabbixMetric(self.hostname, f'gpu.{str(i)}.name', gpu_name.decode('utf-8')),
                 ZabbixMetric(self.hostname, f'gpu.{str(i)}.powerusage', powerusage / 1000),
                 ZabbixMetric(self.hostname, f'gpu.{str(i)}.temperature', temperature),
                 ZabbixMetric(self.hostname, f'gpu.{str(i)}.mem.total', mem_info.total),
                 ZabbixMetric(self.hostname, f'gpu.{str(i)}.mem.free', mem_info.free),
                 ZabbixMetric(self.hostname, f'gpu.{str(i)}.mem.used', mem_info.used),
                 ZabbixMetric(self.hostname, f'gpu.{str(i)}.mem.used.percent', mem_info.used / mem_info.total),
                 ])
        pynvml.nvmlShutdown()
        self.packet.extend(
            [ZabbixMetric(self.hostname, f'gpu.all.powerusage',
                          sum([float(x.value) for x in self.packet if 'powerusage' in x.key])),
             ZabbixMetric(self.hostname, f'gpu.all.temperature.max',
                          max([float(x.value) for x in self.packet if 'temperature' in x.key])),
             ZabbixMetric(self.hostname, f'gpu.all.mem.total',
                          sum([float(x.value) for x in self.packet if 'mem.total' in x.key])),
             ZabbixMetric(self.hostname, f'gpu.all.mem.free',
                          sum([float(x.value) for x in self.packet if 'mem.free' in x.key])),
             ZabbixMetric(self.hostname, f'gpu.all.mem.used',
                          sum([float(x.value) for x in self.packet if 'mem.used' in x.key])),
             ZabbixMetric(self.hostname, f'gpu.all.mem.used.percent',
                          sum([float(x.value) for x in self.packet if 'mem.used' in x.key]) / sum(
                              [float(x.value) for x in self.packet if 'mem.total' in x.key])),
             ])
             
        result = self.zabbix_sender.send(self.packet)

这里有一点,必须先把监控项的key写入到server才能通过api把数据写入到server,类似需要先注册item key,才能在这个item 下记录数据。
所以实现了写数据之前,需要先检查下item key是否已经在server生成了,没有的化先使用item.create进行初始化。
这里有个细节,就是zabbix api需要写 params ,这个需要稍微研究下对应的方法的params写法。
比如 Zabbix采集器 类型的 监控项, 在 item.create方法下需要指定几个参数,
看官方文档并没有明确给出每一种监控项类型的 params 写法,但是在监控项对象中给出params 参数又有很多必填项,我这里卡住导致很多参数不该有而导致的报错。具体信息如下
下面报错就是因为url不该有。

---------------------------------------------------------------------------
ZabbixAPIException                        Traceback (most recent call last)
Cell In[203], line 11
      1 params = {
      2            "name": "gpu.0.powerusage",
      3            "key_": "gpu.0.powerusage",
   (...)
      9            "delay": "30s"
     10        }
---> 11 zabbixapi.do_request('item.create', params=params)

File /usr/local/lib/python3.8/dist-packages/pyzabbix/api.py:304, in ZabbixAPI.do_request(self, method, params)
    302     err = res_json['error'].copy()
    303     err.update({'json': str(request_json)})
--> 304     raise ZabbixAPIException(err)
    306 return res_json

ZabbixAPIException: {'code': -32602, 'message': 'Invalid params.', 'data': 'Item with key "gpu.0.powerusage" already exists on "aiserver2".', 'json': "{'jsonrpc': '2.0', 'method': 'item.create', 'params': {'name': 'gpu.0.powerusage', 'key_': 'gpu.0.powerusage', 'hostid': '10597', 'type': 2, 'value_type': 3, 'units': 'MB', 'url': '', 'delay': '30s'}, 'id': '1', 'auth': '********'}"}

item创建的可用代码:

    def _regist_key(self, key):
        params = {
            "name": key,  #监控项 name 和 key 可以一样
            "key_": key,
            "hostid": self.zabbix_host_id,  #hostid 可以先通过host调用api拿到对于的hostid ,这里host是web console配置的主机名
            "type": 2,  # 监控项的类型 这里使用的 Zabbix采集器	类型  以及下面几个枚举值都参考官方文档吧
            "value_type": self._check_item_value_type(key),  # 记录的数据类型,字符串 整型  浮点 等
            "units": self._check_item_unit(key),  #单位 例如 B / ℃ / W
            "delay": "30s"
        }
        self.zabbix_api.do_request('item.create', params)

GPU监控服务配置

整体代码调通之后,再吧代码配置到系统服务中,避免服务器重启后监控丢失
目前经常会因为要更新驱动而重启机器的情况


# cd /etc/systemd/system
# vim gpumoniter.service
[Unit]
Description=gpumoniter
After=network.target


[Service]
ExecStart=python3 /etc/zabbix/read_gpu_status_info.py


[Install]
WantedBy=multi-user.target

# scp 分发到其他服务器
# scp  xxx.py  host:`pwd`
# scp  xxx.service  host:`pwd`
# systemctl enable --now gpumoniter.service
# systemctl status  gpumoniter.service
# systemctl restart gpumoniter.service
# journalctl -u gpumoniter.service -n 10 -f

扩展

在GPU监控逻辑开发中发现,在自己的后端服务监控中也可以埋点到zabbix来做监控,然后在前端配置相关监控图标,感觉这个链路是通的,也挺方便,统计服务都省了。
后续在有相关内容的话,会再回来更新。

参考链接:

[1]:zabbix6 api item object
[2]:zabbix6 api hostgroup
[3]:Python 调用 zabbix api
[4]:最强Linux课程上线 玩转Zabbix监控实战开发

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值