场景
根据领导要求需要去配置zabbix去监控docker容器,在网上找了很多文章,最后进了这个坑https://www.cnblogs.com/binglansky/p/9132714.html,最后验证这位老哥这个办法是可以的,只不过中间一些配置的细节没有描述太清楚,怪我才疏学浅找了各种文档,试了很多办法,最终搞定这个监控,在这里做下记录,希望能帮到和我一样的初学者。
第一步 配置zabbix-agent
首选,修改zabbix_agentd 配置
#zabbix_agent节点的配置文件,不同部署方法位置可能不太相同
vim /usr/local/zabbix/etc/zabbix_agentd.conf
添加如下两行
#用于远程使用root用户远程执行脚本
EnableRemoteCommands=1
#开启自定义脚本
UnsafeUserParameters=1
#自定义监控项
#这个docker.py脚本需要拥有执行权限,存放位置自定义
UserParameter=docker.discovery,/usr/local/zabbix/script/docker.py
UserParameter=docker.[*],/usr/local/zabbix/script/docker.py $1 $2
说明:
- docker.[*] 这个是key,可以自定义,server端的模板会用到,[*] 接收模板传过来的参数
- docker.py 是用来采集数据的脚本
- $1对应[∗]server端传过来的参数第一个参数,$2对应[∗]server端传过来的参数第二个参数,例如server端传的是 mysql ping,对应为docker.py mysql ping (类似shell中的位置变量)
下面是docker.py 脚本,采用自动发现规则来发现容器,然后指定容器获取状态信息,使用shell脚本的>>看这里<<
#!/usr/bin/python
import sys
import os
import json
def discover():
d = {}
d['data'] = []
with os.popen("sudo docker ps -a --format {{.Names}}") as pipe:
for line in pipe:
info = {}
info['{#CONTAINERNAME}'] = line.replace("\n","")
d['data'].append(info)
print json.dumps(d)
def status(name,action):
if action == "ping":
cmd = 'sudo docker inspect --format="{{.State.Running}}" %s' %name
result = os.popen(cmd).read().replace("\n","")
if result == "true":
print 1
else:
print 0
else:
if action == "MemUsage" :
cmd = 'sudo docker stats %s --no-stream --format "{{.%s}}" |sed -r "s#(.*)([A-Z])iB.*iB#\\1 \\2#" |awk \'{if ($2=="M") print $1; else if ($2=="G") print $1*1024 ; else if ($2=="K") print $1/1024 }\' ' % (name,action)
else:
cmd = 'sudo docker stats %s --no-stream --format "{{.%s}}"' % (name,action)
result = os.popen(cmd).read().replace("\n","")
if "%" in result:
print float(result.replace("%",""))
else:
print result
if __name__ == '__main__':
try:
name, action = sys.argv[1], sys.argv[2]
status(name,action)
except IndexError:
discover()
注意:
- 我是使用python2版本去执行的此脚本,不知道python3是否支持
- 自动发现规则的坑:1 是必须返回json格式内容,2. 是 info['{#CONTAINERNAME}' ] 这个key一定要这么写{#CONTAINERNAME}
在机器上试试执行下
#python docker.py
返回结果如下,一定要是这样的层级关系...
{"data": [{"{#CONTAINERNAME}": "node-3"}, {"{#CONTAINERNAME}": "node-2"}, {"{#CONTAINERNAME}": "node-1"}, {"{#CONTAINERNAME}": "web"}, {"{#CONTAINERNAME}": "cadvisor"}, {"{#CONTAINERNAME}": "updatol"}, {"{#CONTAINERNAME}": "research"}, {"{#CONTAINERNAME}": "services"}, {"{#CONTAINERNAME}": "data"}, {"{#CONTAINERNAME}": "rabbitmq"}, {"{#CONTAINERNAME}": "redis"}, {"{#CONTAINERNAME}": "mysql"}, {"{#CONTAINERNAME}": "ssdb"}]}
配置好后重启下zabbix_agent节点
可以在先使用zabbix-get命令验证下
注意:有的小伙伴可能在执行的时候提示Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock,这个错我也遇到了大家可以试试执行
visudo
#添加一条权限
zabbix ALL=(ALL) NOPASSWD:/usr/bin/docker
但是我添加了也不行,比较困扰,如果知道原因的小伙伴可以留言告诉我原因。这条路走不通那就另辟蹊径,我是又修改了docker.py脚本,把docker命令替换为sudo docker,至此问题解决
第二步 导入模板
把下面这个代码保存到 zbx_export_templates.xml
<?xml version="1.0" encoding="UTF-8"?>
<zabbix_export>
<version>4.4</version>
<date>2020-06-11T03:20:34Z</date>
<groups>
<group>
<name>Linux servers</name>
</group>
</groups>
<templates>
<template>
<template>Template-Docker-Stats</template>
<name>Template-Docker-Stats</name>
<groups>
<group>
<name>Linux servers</name>
</group>
</groups>
<applications>
<application>
<name>Docker-Status</name>
</application>
</applications>
<discovery_rules>
<discovery_rule>
<name>docker.discovery</name>
<key>docker.discovery</key>
<delay>60</delay>
<item_prototypes>
<item_prototype>
<name>Container {#CONTAINERNAME} Diskio usage:</name>
<key>docker.[{#CONTAINERNAME},BlockIO]</key>
<delay>120</delay>
<trends>0</trends>
<value_type>CHAR</value_type>
<applications>
<application>
<name>Docker-Status</name>
</application>
</applications>
</item_prototype>
<item_prototype>
<name>Container{#CONTAINERNAME} CPU usage:</name>
<key>docker.[{#CONTAINERNAME},CPUPerc]</key>
<delay>60</delay>
<value_type>FLOAT</value_type>
<units>%</units>
<applications>
<application>
<name>Docker-Status</name>
</application>
</applications>
</item_prototype>
<item_prototype>
<name>Container {#CONTAINERNAME} Mem usage</name>
<key>docker.[{#CONTAINERNAME},MemUsage]</key>
<delay>60</delay>
<value_type>FLOAT</value_type>
<units>MB</units>
<applications>
<application>
<name>Docker-Status</name>
</application>
</applications>
</item_prototype>
<item_prototype>
<name>Container {#CONTAINERNAME} NETio usage:</name>
<key>docker.[{#CONTAINERNAME},NetIO]</key>
<delay>120</delay>
<trends>0</trends>
<value_type>CHAR</value_type>
<applications>
<application>
<name>Docker-Status</name>
</application>
</applications>
</item_prototype>
<item_prototype>
<name>Container{#CONTAINERNAME} is_run :</name>
<key>docker.[{#CONTAINERNAME},ping]</key>
<delay>30</delay>
<applications>
<application>
<name>Docker-Status</name>
</application>
</applications>
<trigger_prototypes>
<trigger_prototype>
<expression>{last()}=0</expression>
<name>docker_{#CONTAINERNAME}_down</name>
<priority>DISASTER</priority>
</trigger_prototype>
</trigger_prototypes>
</item_prototype>
</item_prototypes>
</discovery_rule>
</discovery_rules>
</template>
</templates>
</zabbix_export>
在web界面导入模板
导入以后他会默认生成自动发现规则和监控项原型
在这里需要注意一点,也是折磨我最久的一点,就是这个自动发现规则并不会启用,是不支持状态,如图
这是因为里面配置的过滤器中的正则表达式错误造成的
解决办法:
就是去掉这个过滤器
然后等待这个自动发现规则启动了,去查看是否生成最新数据
以上就配置好了,zabbix监控docker容器
最后再总结下配置步骤
1. 修改zabbix_agent节点的配置
2. 创建docker.py文件,并添加执行权限
3. 导入模板,删除过滤器中的正则表达式
4. 查看最新数据,确认是否生效
配置时可以zabbix_get 来调试 找到问题出在哪去然后去解决
大佬链接: