思考:

1. 我们需要知道我们的业务跑了哪些端口,比如:前置机跑在什么端口上面,交易核心跑在什么端口上面等等,总之,对我们要监控的端口进行汇总。

2.采用什么形式去监控端口呢?

  我能想到的是:

    a.从zabbix服务器端去做简单探测(simple check),这种方法就像我们的telnet,不需要去客户端做事情,看似简单;但是,问题来了,我要去自定义模板(template,每个host会去关联它),每个模板上要制作items,这样会产生大量的手工操作,如果说,我们线上总共用了1000个端口,我就需要在template里面添加一千项,每项上还要添加监控项,纯手工加! 这是其一,还要给每项添加告警,如果端口宕了得让它告警;再者,每台服务器所跑的端口不尽相同,当你把模板关联到其中一台服务器的时候会发现,大部分都是不需要监控的端口(因为机器本身就没启用)。所以,这种方法不可取!

   b.在zabbix客户端上下功夫,让客户端去抓取我们要监控的端口,然后反馈给服务器端。这样貌似不错,那么我就去每个客户端的配置文件里面加监控脚本,每台服务器上跑的端口不一样,所以呢,每台服务器上的监控脚本不一样;这样,问题又来了,那么多服务器,总不能一台台加,对了,咱们有自动化工具啊,可是,每个服务器上要跑的脚本又不一样,不能统一分发,这也是个问题!此外,在zabbix服务器的web端,我还是需要去做上面一点里面提到的模板,工作量太大,不行!

  c.综合上面两点,我发现,要克服的困难有两点:首先,我们制作模板不能全靠手工,其次,客户端上监控脚本必须一样,不然怎么批量分发?

既然如此,为何不这样:

让zabbix服务器自己去生成items!通过脚本扫描每台机器的端口,再通过对比,筛选出我们想要的端口,而不是去 每台服务器上一个个改脚本!就这么干!


监控过程描述:

1.让zabbix服务器自己生成items没那么神秘,因为zabbix从2.0版本之后开始支持discovers功能了,它可以自动发现服务器的分区,网卡这些不固定的监控项,默认情况下,网卡、分区的自动发现功能是内置的,所以不需要额外部署脚本;而端口监控,我写了一个脚本,结合discover功能,可以实现定期扫描服务器上的监听端口,自动添加、删除监控端口。

  脚本如下:         

#!/bin/bash
local_path=/usr/local/zabbix/etc/monitor_scripts
portarray=(`netstat -tnlp|egrep -i "$1"|awk {'print $4'}|awk -F':' '{if ($NF~/^[0-9]*$/) print $NF}'|sort |uniq   2>/dev/null`)
length=${#portarray[@]}
printf "{\n"
printf  '\t'"\"data\":["
for ((i=0;i<$length;i++));do
     for j in $(<$local_path/portlist.txt);do
        if [ $j -eq ${portarray[$i]} ];then
        printf '\n\t\t{'
        printf "\"{#TCP_PORT}\":\"$j\"},"
         fi
     done
done
printf "\n\t\t{\"{#TCP_PORT}\":\"22\"}"
printf  "\n\t]\n"
printf "}\n"


这个脚本的意思是,将系统中所有的监听端口都扫描出来,然后再去和我事先准备好的业务端口表进行比对,发现相同端口,则打印出来,这样就能说明,我某一台服务器上运行的所有端口中,哪些是业务在用的。


好了,端口是扫出来了,它是怎么把值反馈给服务器端的呢?

我们先看看这段脚本输出的东西吧!

{
        "data":[
                {"{#TCP_PORT}":"18016"},
                {"{#TCP_PORT}":"28080"},
                {"{#TCP_PORT}":"28088"},
                {"{#TCP_PORT}":"29088"},
                {"{#TCP_PORT}":"38080"},
                {"{#TCP_PORT}":"443"},
                {"{#TCP_PORT}":"80"},

                {"{#TCP_PORT}":"22"}

        ]
}

这其实是一段json格式的数据数据格式有很多种,比如xml格式、yml格式等等,每种格式的数据表达值的方式都不太一样,这段json中,{#TCP_PORT} 其实是个变量,后面的数字,就是咱们取出来的端口号,那么,如果我们在服务器端调用{#TCP_PORT}这个变量,那么它返回的值应该是什么呢?当然是所有的端口号啦!就这么简单!。为什么要用json?因为zabbix的discover是用json来返回变量的!


2. 好了,我们再去服务器端看看!

首先,我们去创建模板吧,在模板的后半部分,有个Discovery选项,点进去,这里我们就要创建discover rule了,顾名思义,就是”搜索规则“,我们按照什么规则去搜索要监控的端口咧?

zabbix针对业务端口的监控_客户端

再往下看,除了name之外,有个Key选项,这个Key就是我们自己定义Key,写在哪里呢,在zabbix_agentd.conf 里面UserParameter 参数。通过这个Key值,服务器就知道,去客户端查找哪个监控项,也就是说,跟谁去要返回值,我们在此可以去服务器端试一下,看下客户端究竟返回什么 ?./zabbix_get -s 192.168.117.21 -k tcpportlisten;

zabbix针对业务端口的监控_simple_02


返回值看到了,但是,怎么通过这些返回值,形成具体监控项呢?这里就是最关键的地方,通过jason变量! 首先,找到Item prototypes(创建监控项):

zabbix针对业务端口的监控_simple_03

上图中,$1 表示的就是我们jason返回值中的端口。这里的Key值,前半部分是zabbix内置的,用来Checks if this port is in LISTEN state. 0 - it is not, 1 - it is in LISTEN state.

后半部分的{#TCP_PORT},很眼熟吧!对,他就是我们返回的端口!如果客户端返回6个端口,这里将会产生6个监控项(items),懂了吧!如果返回一个80端口,net.tcp.listen[{#TCP_PORT}]的返回值是1,说明端口存活, 0表示端口不存在了。

最后,设置告警规则。

zabbix针对业务端口的监控_服务器_04

告警条件解释下:最后三次探测中,等于0的情况出现一次,则触发告警;如果其中某个端口,在最近的三次探测中,有一次不存在,则触发告警。

3.最后,看看效果吧!

  在web端host中,找到我们受控端的服务器,添加template,然后点开它的items,你会发现:

zabbix针对业务端口的监控_客户端_05

每个扫描到的端口都出现了,形成了一个监控项,并且告警项也生成了,这个告警项是统一的。

4.说说部署。

部署非常的简单,目前我们已经有自动化工具ansible,只需要把客户端的监控脚本和我们的端口表分发上去,再修改一下agent的配置文件,重启agent,一切就ok了~ 这个过程,只要一个命令!