zabbix自动发现实现批量监控docker状态

最近在搞zabbix监控docker以及docker内部应用状态信息,网上找的资料好少,只找到了一个大神的一篇文章,用的是python实现监控docker容器的基本状态,我在他给的脚本基础上进行修改,另外,增加了docker内部常用应用的状态监控,目前在测试环境上部署成功了,具体还需要在线上环境部署后才能检验出效果如何。

好了,根据惯例,废话讲完了,开始进入正题了。

首先,介绍下该监控套件有三个脚本,一个是自动发现主机上的docker容器脚本,另一个是用python写的获取每个docker容器的系统状态,包括CPU使用率,内存使用率以及网络资源使用率,最后这个脚本添加了一些我公司常用的应用的状态监控,包括应用占用内存,cpu资源以及进程的存活状态,至于读者们需要监控其他docker里面的应用,可以依照我的脚本来进行修改。

首先,需要编辑自动发现docker中容器个数的脚本,内容如下:

# cat /usr/local/zabbix/scripts/docker_low_discovery.sh 
#!/bin/bash
#Fucation:docker low-level discovery
docker() {
            port=($(sudo docker ps -a|grep -v "CONTAINER ID"|awk ‘{print $NF}‘))
            printf ‘{\n‘
            printf ‘\t"data":[\n‘
               for key in ${!port[@]}
                   do
                       if [[ "${#port[@]}" -gt 1 && "${key}" -ne "$((${#port[@]}-1))" ]];then
                          printf ‘\t {\n‘
                          printf "\t\t\t\"{#CONTAINERNAME}\":\"${port[${key}]}\"},\n"
 
                     else [[ "${key}" -eq "((${#port[@]}-1))" ]]
                          printf ‘\t {\n‘
                          printf "\t\t\t\"{#CONTAINERNAME}\":\"${port[${key}]}\"}\n"
 
                       fi
               done
 
                          printf ‘\t ]\n‘
                          printf ‘}\n‘
}
case $1 in
docker)
docker
;;
*)
echo "Usage:`basename $0` {docker}"
;;
esac

上面这个脚本是用来获取到docker里面应用的容器,并对其进行json化输出的,效果如下:

# sh /usr/local/zabbix/scripts/docker_low_discovery.sh docker
{
"data":[
 {
"{#CONTAINERNAME}":"hopeful_brown"},
 {
"{#CONTAINERNAME}":"happy_einstein"}
 ]
}

这样就能被zabbix_server获取到了,然后是python脚本,使用python获取docker的参数需要使用一个扩展包,可以通过pip或者easy_install安装docker-py扩展:

pip install docker-py或者easy_install docker-py或者不想这样安装的话可以去python官网下载docker-py的安装包,解压后使用docker docker-py-1.4.0/setup.py install命令安装,扩展包我将会打包放在附件中。

下面是python脚本:
# cat /usr/local/zabbix/scripts/docker_monitor.py 
#!/usr/bin/env python
#-*- coding: utf-8 -*-
#author:Xianglin Hu
#email: [email protected]
from docker import Client
import sys
import subprocess
import os

def check_container_stats(container_name,collect_item):
    container_collect=docker_client.stats(container_name)
    old_result=eval(container_collect.next())
    new_result=eval(container_collect.next())
    container_collect.close()
    if collect_item == ‘cpu_total_usage‘:
        result=new_result[‘cpu_stats‘][‘cpu_usage‘][‘total_usage‘] - old_result[‘cpu_stats‘][‘cpu_usage‘][‘total_usage‘]
    elif collect_item == ‘cpu_system_usage‘:
        result=new_result[‘cpu_stats‘][‘system_cpu_usage‘] - old_result[‘cpu_stats‘][‘system_cpu_usage‘]
    elif collect_item == ‘cpu_percent‘:
        cpu_total_usage=new_result[‘cpu_stats‘][‘cpu_usage‘][‘total_usage‘] - old_result[‘cpu_stats‘][‘cpu_usage‘][‘total_usage‘]
        cpu_system_uasge=new_result[‘cpu_stats‘][‘system_cpu_usage‘] - old_result[‘cpu_stats‘][‘system_cpu_usage‘]
        cpu_num=len(old_result[‘cpu_stats‘][‘cpu_usage‘][‘percpu_usage‘])
        result=round((float(cpu_total_usage)/float(cpu_system_uasge))*cpu_num*100.0,2)
    elif collect_item == ‘mem_usage‘:
        result=new_result[‘memory_stats‘][‘usage‘]
    elif collect_item == ‘mem_limit‘:
        result=new_result[‘memory_stats‘][‘limit‘]
    elif collect_item == ‘mem_percent‘:
        mem_usage=new_result[‘memory_stats‘][‘usage‘]
        mem_limit=new_result[‘memory_stats‘][‘limit‘]
        result=round(float(mem_usage)/float(mem_limit)*100.0,2)
    elif collect_item == ‘network_rx_bytes‘:
        network_check_command="""sudo /usr/bin/docker exec %s cat /proc/net/dev|sed -n 3p|awk ‘{print $2,$10}‘"""%container_name
        result=os.popen(network_check_command).read().split()[0]
    elif collect_item == ‘network_tx_bytes‘:
        network_check_command="""sudo /usr/bin/docker exec %s cat /proc/net/dev|sed -n 3p|awk ‘{print $2,$10}‘"""%container_name
        result=os.popen(network_check_command).read().split()[1]
    return result
if __name__ == "__main__":
    docker_client = Client(base_url=‘unix://var/run/docker.sock‘, version=‘1.17‘)
    container_name=sys.argv[1]
    collect_item=sys.argv[2]
    print check_container_stats(container_name,collect_item)

这里面使用到了docker里面的Client类,获取到某个docker容器的当前状态信息,然后进行运算,返回运算结果。但是容器当前信息那个dict中的network的key获取到的信息不准确,于是我使用了docker exec命令来获取docker容器内部的网络流量信息。这也是我在大神的基础上进行改进的地方,这里的改进将python脚本的执行时间缩短了,将有助于server获取duocker容器信息时减少长连接的数量,提升zabbix_server的性能。这里的docker exec命令将会在下一个脚本中大量使用来获取docker容器中的应用状态信息。

下面是获取容器应用状态信息的脚本:

# cat docker_processmonitor.sh 
#!/bin/bash
#license:GPL
#mail:[email protected]
#date:2015.09.22
processmem(){
        sudo /usr/bin/docker exec $1 ps aux|grep $2|grep -v "grep"|grep -v "processstatus.sh"|awk ‘{sum+=$6}; END{print sum}‘
}
processcpu(){
        sudo /usr/bin/docker exec $1 ps aux|grep $2|grep -v "grep"|grep -v "processstatus.sh"|awk ‘{sum+=$3}; END{print sum}‘
}
processport(){
        sudo /usr/bin/docker exec $1 ss -antlp|grep $2|grep LISTEN|wc -l
}
case "$3" in
mem)
processmem $1 $2
;;
cpu)
processcpu $1 $2
;;
port)
processport $1 $2
;;
*)
echo "Usage: $0 {docker_containername}{processname}{mem|cpu|port}"
;;
esac

这个脚本其实没啥说的,从我以前写的那个脚本上面修改来的,使用了一个case来判断需要获取的docker容器的名称以及该容器中应用的状态信息,只不过这里获取docker容器状态信息使用的是docker exec命令来进行获取。另外这里面添加了对于应用是否存活的状态监测,那就是检测该应用是否侦听了网络端口,假如该应用侦听的网络端口个数为0的话,可以认为该应用存在异常。这些应用只是我公司使用比较多的应用,各位读者可以根据自己需求修改相应应用的监控。

由于docker是以root权限来启用的,而zabbix监控是使用zabbix用户来执行的,所以需要给予zabbix用户相应的权限,需要编辑visudo:

echo "zabbix ALL=(root) NOPASSWD:/bin/docker,/usr/bin/python,/usr/local/zabbix/scripts/docker_monitor.py,/usr/local/zabbix/scripts/docker_low_discovery.sh,/usr/local/zabbix/scripts/docker_processmonitor.sh">>/etc/sudoers

并且还需要注释掉这条记录:#Defaults    requiretty(PS:注意,这条记录是要求使用sudo命令时需要有终端界面,注释掉这一条之后就可以不需要终端执行sudo命令了。)

然后就是编辑zabbix_agentd.conf文件,添加下面几行:

# tail -3 /usr/local/zabbix/etc/zabbix_agentd.conf
UserParameter=docker_low_discovery[*],/bin/bash /usr/local/zabbix/scripts/docker_low_discovery.sh $1
UserParameter=docker_stats[*],sudo /usr/bin/python /usr/local/zabbix/scripts/docker_monitor.py $1 $2
UserParameter=docker_process[*],/bin/bash /usr/local/zabbix/scripts/docker_processmonitor.sh $1 $2  $3

保存配置并重启zabbix_agentd服务,然后修改脚本的属主属组以及权限:

chown zabbix.zabbix /usr/local/zabbix/scripts/*

chmod 755 /usr/local/zabbix/scripts/*

然后可以在zabbix_server端测试是否能够获取到相应的数据:

[[email protected] ~]# /usr/local/zabbix-2.4.4/bin/zabbix_get -s x.x.x.x -k"docker_low_discovery[docker]"
{
"data":[
 {
"{#CONTAINERNAME}":"hopeful_brown"},
 {
"{#CONTAINERNAME}":"happy_einstein"}
 ]
}
[[email protected] ~]# /usr/local/zabbix-2.4.4/bin/zabbix_get -s x.x.x.x -k"docker_stats[happy_einstein,network_tx_bytes]"
9664252
[r[email protected] ~]# /usr/local/zabbix-2.4.4/bin/zabbix_get -s x.x.x.x -k"docker_process[happy_einstein,nginx,port]"
2

这里的IP地址我就用x.x.x.x代替了,这里应该填写客户端的IP地址。如上所示,能够正确获取到agentd的数据以后,然后就需要在zabbix_server这边配置监控模版了,关于监控模版的配置我在之前的文章中提及了很多次,相信大家应该都不会陌生了,这回就不详细描述模板的建立了,稍后我会将模板打包一起上传至附件中,这个模板目前还是半成品,各位可以根据模板进行修改,可以根据你们的需求来做,下面,演示一下监控出来的效果(PS:只是在测试环境小规模的部署,项目还不错,于是没有做成筛选出来。)

上面这些显示的是监控的结果,各位也可以根据自己的需求来进行修改,总之一句话,zabbix可以做到任何你想做的监控,嘻嘻!!!

时间: 2024-10-03 16:46:41

zabbix自动发现实现批量监控docker状态的相关文章

zabbix自动发现端口并监控

参考 http://ywzhou.blog.51cto.com/2785388/1580160 1 客户端新建脚本 #!/bin/bash portarray=(`sudo netstat -tnlp|egrep -i "$1"|awk {'print $4'}|awk -F':' '{if ($NF~/^[0-9]*$/) print $NF}'|sort|uniq`) length=${#portarray[@]} printf "{\n" printf  '\

zabbix自动发现硬盘并监控其IO

在使用zabbix监控Linux主机的时候,我们希望zabbix能够自动发现Linux主机上有多少块硬盘,而不是我们手动去添加. 实验目的: 让zabbix能够自动发现Linux服务器的磁盘,并能够监控磁盘IO且绘出图形 实验设备: zabbix-server: 172.17.5.230 zabbix-client:  182.17.5.219 实验环境: linux centos 6.6 zabbix-2.4.6 实验步骤 1. 在zabbix客户端的安装目录,如/usr/local/zabb

zabbix 自动发现端口服务监控教程

目录 创建数据表(收集haproxy服务的信息) 针对生成的数据表做监控 在haproxy服务机器上配置 在zabbix上添加监控 前言: 1.线上业务使用了几十上百台haproxy服务,需要针对这些服务做监控(包含haproxy端口对应的TCP连接数监控,haproxy服务监控等). 2.普通的在zabbix_agentd.conf里面配置"UserParameter"的方式太繁琐,这里使用建表(收集数据,汇总数据)的方式. 3.将数据汇总到表里面,通过第三方脚本对数据做一个处理,拿

zabbix 自动发现端口进行监控

zabbix 探索规则自带磁盘及网卡的,参照后整理探索端口并自动添加监控报警功能 : shell脚本: #!/bin/bash port_array=(`netstat -tnlp|egrep -i "$1"|awk {'print $4'}|awk -F':' '{if ($NF~/^[0-9]*$/) print $NF}'|sort |uniq   2>/dev/null`) length=${#port_array[@]} printf "{\n" p

zabbix自动发现window(阿里云),去除多余的监控项

1.问题点: 由于使用zabbix 自动发现去批量添加500台阿里云主机, 导致监控项多大120多项, 其中有大量的报警信息, 都是我不想要的,前期由于量太多, 不敢轻易的去删除,只做个在模板里面删除, 但是发现不管用.2.在模板里面删除不要监控项是多的,想法是对的, 但是操作过程有点问题3.正确的方式是:模板 4.将自动发现服务这个去掉, 应该他会自动发现windows(阿里云) 主机多余的监控项5.刚才我们已经禁用了多余监控项了, 现在需要把之前就已经加好的监控项都去掉(关键)6.批量去掉当

zabbix自动发现结合shell实现自动发现占用内存最大top10进程并监控其资源

最近在想一个问题,线上服务器跑的服务五花八门,可能这台跑的是nginx,另一台跑的是mysql,其他的跑的是nfs或者其他服务等等,通过某一个脚本中固定的写入一些服务来实现监控所有的服务器的进程占用资源情况占用zabbix服务器资源不说,假如该服务器跑的服务不在固定列表中,监控服务获取不到相应数据. 为了解决这个问题,最近在想通过zabbix的自动发现功能能不能实现自动发现占用服务器内存最大的N个进程,然后对这些进程占用内存和CPU的资源情况进行监控获取数据呢?于是就有了本篇文章的诞生. 首先,

zabbix自动发现监控mongo

1: zabbix自动发现mongo监控的端口,并返回zabbix_server需要的格式,脚本部署在zabbix_agent上,路径为/usr/local/zabbix/zabbix_discover_mongo.sh,脚本内容如下: #!/bin/sh #zhuangweihong 20160419 zabbix discover mysql res=`sudo ss -tulnp|grep mongo|grep -v 28107|awk '{print $(NF-2)}'|awk -F':

zabbix自动发现与监控内存和CPU使用率最高的进程

监控需求 某项目的应用服务器CPU和内存使用率的监控,通过zabbix系统监控记录应用服务器上进程的CPU和内存的使用情况,并以图表的形式实时展现,以便于我们分析服务器的性能瓶颈. 监控方式 利用zabbix监控系统的自动发现功能,首先编写shell脚本获取服务器的CPU和内存资源使用率最大的进程,以json的格式输出,然后对这些进程的CPU和内存资源使用情况进行监控.(本文监控的进程为Linux服务器中资源使用率最高的10个进程.) 缺点 不适用于监控固定的进程 首先使用top命令查看进程状态

zabbix自动发现oracle表空间并监控其使用率

监控需求 Oracle表空间使用率实时监控,当表空间使用率达到95%时触发告警机制.Oracle表空间分为系统默认表空间和用户创建的表空间,而表空间又有自动扩展和非自动扩展两种类型,用户(DBA)在创建表空间时可以根据应用需求指定是否开启表空间自动扩展.那么在这里我们需要分析一个监控策略,就是当zabbix监控到某个表空间使用率达到95%,那么就让触发器触发警告(Warning)信息,并发送邮件给DBA或管理者.当检测到表空间没有开启自动扩展时,则触发Information信息.说明一下:ora