zabbix添加对haproxy的监控
HAProxy提供高可用性、负载均衡以及基于TCP和HTTP应用的代理,支持虚拟主机,它是免费、快速并且可靠的一种解决方案。HAProxy本身提供一个web页面可以显示haproxy的各种信息,方便管理员查看系统状态等。此次我采用socat(socat是netcat的扩展实现)这款开源软件通过haproxy的socks配合zabbix实现haproxy系统的状态监控。
一、安装socat
wget http://www.dest-unreach.org/socat/download/socat-1.7.3.0.tar.gz
tar xzf socat-1.7.3.0.tar.gz
cd socat-1.7.3.0
./configure
make && make install
which socat #安装完自动会在/usr/local/bin 创建执行程序
/usr/local/bin/socat
二、开启haproxy sock
编辑haproxy配置文件在global下添加如下:
global
stats socket /tmp/haproxy.sock mode 600 level admin
# 重启haproxy
/etc/init.d/haproxy restart
Haproxy 信息
[root@sdtw02 socat-1.7.3.0]# echo "show info" |socat /tmp/haproxy.sock stdio
Name: HAProxy
Version: 1.5.19
Release_date: 2016/12/25
Nbproc: 1
Process_num: 1
Pid: 20816
Uptime: 1d 21h14m40s
Uptime_sec: 162880
Memmax_MB: 0
Ulimit-n: 400034
Maxsock: 400034
Maxconn: 200000
Hard_maxconn: 200000
CurrConns: 0
CumConns: 45
CumReq: 45
MaxSslConns: 0
CurrSslConns: 0
CumSslConns: 0
Maxpipes: 0
PipesUsed: 0
PipesFree: 0
ConnRate: 0
ConnRateLimit: 0
MaxConnRate: 2
SessRate: 0
SessRateLimit: 0
MaxSessRate: 2
SslRate: 0
SslRateLimit: 0
MaxSslRate: 0
SslFrontendKeyRate: 0
SslFrontendMaxKeyRate: 0
SslFrontendSessionReuse_pct: 0
SslBackendKeyRate: 0
SslBackendMaxKeyRate: 0
SslCacheLookups: 0
SslCacheMisses: 0
CompressBpsIn: 0
CompressBpsOut: 0
CompressBpsRateLim: 0
ZlibMemUsage: 0
MaxZlibMemUsage: 0
Tasks: 7
Run_queue: 1
Idle_pct: 100
node: 210-61-161-118.hinet-ip.hinet.net
description:
[root@sdtw02 socat-1.7.3.0]# echo "show stat" |socat /tmp/haproxy.sock stdio
# pxname,svname,qcur,qmax,scur,smax,slim,stot,bin,bout,dreq,dresp,ereq,econ,eresp,wretr,wredis,status,weight,act,bck,chkfail,chkdown,lastchg,downtime,qlimit,pid,iid,sid,throttle,lbtot,tracked,type,rate,rate_lim,rate_max,check_status,check_code,check_duration,hrsp_1xx,hrsp_2xx,hrsp_3xx,hrsp_4xx,hrsp_5xx,hrsp_other,hanafail,req_rate,req_rate_max,req_tot,cli_abrt,srv_abrt,comp_in,comp_out,comp_byp,comp_rsp,lastsess,last_chk,last_agt,qtime,ctime,rtime,ttime,
admin_stats,FRONTEND,,,0,1,10,13,619,2481,0,0,11,,,,,OPEN,,,,,,,,,1,2,0,,,,0,0,0,2,,,,0,0,0,11,2,0,,0,2,13,,,0,0,0,0,,,,,,,,
admin_stats,BACKEND,0,0,0,1,1,2,619,2481,0,0,,2,0,0,0,UP,0,0,0,,0,163002,0,,1,2,0,,0,,1,0,,1,,,,0,0,0,0,2,0,,,,,0,0,0,0,0,0,-1,,,0,0,0,0,
im_access_6666,FRONTEND,,,0,1,200000,31,6617,8443,0,0,0,,,,,OPEN,,,,,,,,,1,3,0,,,,0,0,0,1,,,,,,,,,,,0,0,0,,,0,0,0,0,,,,,,,,
im_access_6666,im01,0,0,0,1,100000,16,3473,4235,,0,,0,0,0,0,UP,1,1,0,0,0,163002,0,,1,3,1,,16,,2,0,,1,L4OK,,0,,,,,,,0,,,,2,0,,,,,4285,,,0,1,0,3116,
im_access_6666,im02,0,0,0,1,100000,15,3144,4208,,0,,0,0,0,0,UP,1,1,0,0,0,163002,0,,1,3,2,,15,,2,0,,1,L4OK,,0,,,,,,,0,,,,0,0,,,,,4885,,,0,1,0,3778,
im_access_6666,BACKEND,0,0,0,1,20000,31,6617,8443,0,0,,0,0,0,0,UP,2,2,0,,0,163002,0,,1,3,0,,31,,1,0,,1,,,,,,,,,,,,,,2,0,0,0,0,0,4285,,,0,1,0,6804,
看到这里大家都明白了,我们可以通过“show stat”返回的信息,过滤出我们想要得到的监控字段数据。这里我们主要取qcur(queue数量)、scur(session数量)、bin(入站流量)、bout(出站流量)、status(后端服务器状态)、downtime(宕机总时长)、check_status(健康检测状态),自定义key收集这些数据制作相应的item,如果你想监控更多信息可以取更多的字段数据。
大家看到这些字段数据使用”,”分隔,非常方便我们用awk来过滤数据,具体自定义key见代码。首先,我们需要建立一个HAProxy模版,然后建立发现规则,来发现这些后端服务器,这样每次haproxy添加服务的时候,zabbix就会自动发现这些后端服务器、自动建立item、自动建立Graph、自动建立Trigger,一切全部自动完成。
三、Step by Step
1、导入haproxy模版
2、添加.sh文件到/usr/bin目录下
# cd /usr/bin
# cat ckey.ha.bin.sh
#!/bin/bash
export PATH=/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
echo "show stat" |socat /tmp/haproxy.sock stdio|grep "\<$1\>"|grep -v "^FRONTEND"|grep -v "^BACKEND"|awk -F "," '{print $9}'
# cat ckey.ha.bout.sh
#!/bin/bash
export PATH=/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
echo "show stat" |socat /tmp/haproxy.sock stdio|grep "\<$1\>"|grep -v "^FRONTEND"|grep -v "^BACKEND"|awk -F "," '{print $10}'
# cat ckey.ha.downtime.sh
#!/bin/bash
export PATH=/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
echo "show stat" |socat /tmp/haproxy.sock stdio|grep "\<$1\>"|grep -v "^FRONTEND"|grep -v "^BACKEND"|awk -F "," '{print $25}'
# cat ckey.ha.lastchk.sh
#!/bin/bash
export PATH=/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
echo "show stat" |socat /tmp/haproxy.sock stdio|grep "\<$1\>"|grep -v "^FRONTEND"|grep -v "^BACKEND"|awk -F "," '{print $38}'
# cat ckey.ha.queue.sh
#!/bin/bash
export PATH=/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
echo "show stat" |socat /tmp/haproxy.sock stdio|grep "\<$1\>"|grep -v "^FRONTEND"|grep -v "^BACKEND"|awk -F "," '{print $3}'
# cat ckey.ha.session.sh
#!/bin/bash
export PATH=/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
echo "show stat" |socat /tmp/haproxy.sock stdio|grep "\<$1\>"|grep -v "^FRONTEND"|grep -v "^BACKEND"|awk -F "," '{print $5}'
# cat ckey.ha.status.sh
#!/bin/bash
export PATH=/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
echo "show stat" |socat /tmp/haproxy.sock stdio|grep "\<$1\>"|grep -v "^FRONTEND"|grep -v "^BACKEND"|awk -F "," '{print $18}'
# 建立发现规则
key shell如下:(这里有一点需要注意,就是haproxy.sock这个文件的权限问题,默认是644,单纯执行这个shell没问题,但如果需要zabbix用户去获取返回值的时候就会提示权限不足,所以我直接将haproxy.sock设置成了666,也可以设置visudo,我为了方便直接修改了这个文件权限)
# cat has.discovery.sh
#!/bin/bash
export PATH=/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
printf '{\n'
printf '\t"data":[\n'
export LINE=$(echo "show stat" |socat /tmp/haproxy.sock stdio|grep -v "^#"|grep -v "^admin_stats"|awk -F "," '{print $2}'|grep -v "^FRONTEND"|grep -v "^BACKEND"|grep -v "^$"|wc -l)
export N=0
#printf '\t\t{\n'
for i in $(echo "show stat" |socat /tmp/haproxy.sock stdio|grep -v "^#"|grep -v "^admin_stats"|awk -F "," '{print $2}'|grep -v "^FRONTEND"|grep -v "^BACKEND");
do printf "\t\t\t{\"{#SNAME}\":\"$i\"}";
N=$(($N+1))
if [ $N -eq $LINE ];
then
printf '\n'
else
printf ',\n'
fi
done;
printf ']}\n'
3、定义key配置文件
[root@sdtw02 src]# vim /etc/zabbix/zabbix_agentd.d/HaProxy_status.conf
UserParameter=has.discovery,/usr/bin/has.discovery.sh
UserParameter=ckey.ha.bin[*],/usr/bin/ckey.ha.bin.sh $1
UserParameter=ckey.ha.bout[*],/usr/bin/ckey.ha.bout.sh $1
UserParameter=ckey.ha.downtime[*],/usr/bin/ckey.ha.downtime.sh $1
UserParameter=ckey.ha.lastchk[*],/usr/bin/ckey.ha.lastchk.sh $1
UserParameter=ckey.ha.queue[*],/usr/bin/ckey.ha.queue.sh $1
UserParameter=ckey.ha.session[*],/usr/bin/ckey.ha.session.sh $1
UserParameter=ckey.ha.status[*],/usr/bin/ckey.ha.status.sh $1
重启zabbix客户端
# /etc/init.d/zabbix-agent restart
4.在web上操作主机添加模板
在zabbix-server端测试:
[root@u04zbx01 ~]# zabbix_get -s 1.1.1.1 -p 10050-k has.discovery
{
"data":[
2017/11/17 17:06:38 socat[8231] E open("/usr/local/haproxy/haproxy.sock", 02002, 0666): Permission denied
2017/11/17 17:06:38 socat[8241] E open("/usr/local/haproxy/haproxy.sock", 02002, 0666): Permission denied
]}
修改权限即可
[root@sdtw02 src]# chmod 666 /tmp/haproxy.sock
[root@u04zbx01 ~]# zabbix_get -s 1.1.1.1 -p 10050 -k has.discovery
{
"data":[
{"{#SNAME}":"im01"},
{"{#SNAME}":"im02"}
]}
sed -i "s#/usr/local/haproxy/haproxy.sock#/tmp/haproxy.sock#g" *.sh
监控模板zbx_haproxy_templates.xml
<?xml version="1.0" encoding="UTF-8"?> <zabbix_export> <version>3.0</version> <date>2017-11-17T06:48:38Z</date> <groups> <group> <name>Templates</name> </group> </groups> <templates> <template> <template>Template HaProxy Service</template> <name>Template HaProxy Service</name> <description/> <groups> <group> <name>Templates</name> </group> </groups> <applications> <application> <name>NetWork</name> </application> <application> <name>Status</name> </application> </applications> <items/> <discovery_rules> <discovery_rule> <name>ha.vserver.discovery</name> <type>0</type> <snmp_community/> <snmp_oid/> <key>has.discovery</key> <delay>1800</delay> <status>0</status> <allowed_hosts/> <snmpv3_contextname/> <snmpv3_securityname/> <snmpv3_securitylevel>0</snmpv3_securitylevel> <snmpv3_authprotocol>0</snmpv3_authprotocol> <snmpv3_authpassphrase/> <snmpv3_privprotocol>0</snmpv3_privprotocol> <snmpv3_privpassphrase/> <delay_flex/> <params/> <ipmi_sensor/> <authtype>0</authtype> <username/> <password/> <publickey/> <privatekey/> <port/> <filter> <evaltype>0</evaltype> <formula/> <conditions/> </filter> <lifetime>30</lifetime> <description/> <item_prototypes> <item_prototype> <name>ha.vserver.bps.in $1</name> <type>0</type> <snmp_community/> <multiplier>1</multiplier> <snmp_oid/> <key>ckey.ha.bin[{#SNAME}]</key> <delay>60</delay> <history>90</history> <trends>365</trends> <status>0</status> <value_type>0</value_type> <allowed_hosts/> <units>bps</units> <delta>1</delta> <snmpv3_contextname/> <snmpv3_securityname/> <snmpv3_securitylevel>0</snmpv3_securitylevel> <snmpv3_authprotocol>0</snmpv3_authprotocol> <snmpv3_authpassphrase/> <snmpv3_privprotocol>0</snmpv3_privprotocol> <snmpv3_privpassphrase/> <formula>6</formula> <delay_flex/> <params/> <ipmi_sensor/> <data_type>0</data_type> <authtype>0</authtype> <username/> <password/> <publickey/> <privatekey/> <port/> <description/> <inventory_link>0</inventory_link> <applications> <application> <name>NetWork</name> </application> </applications> <valuemap/> <logtimefmt/> <application_prototypes/> </item_prototype> <item_prototype> <name>ha.vserver.bps.out $1</name> <type>0</type> <snmp_community/> <multiplier>1</multiplier> <snmp_oid/> <key>ckey.ha.bout[{#SNAME}]</key> <delay>60</delay> <history>90</history> <trends>365</trends> <status>0</status> <value_type>0</value_type> <allowed_hosts/> <units>bps</units> <delta>1</delta> <snmpv3_contextname/> <snmpv3_securityname/> <snmpv3_securitylevel>0</snmpv3_securitylevel> <snmpv3_authprotocol>0</snmpv3_authprotocol> <snmpv3_authpassphrase/> <snmpv3_privprotocol>0</snmpv3_privprotocol> <snmpv3_privpassphrase/> <formula>8</formula> <delay_flex/> <params/> <ipmi_sensor/> <data_type>0</data_type> <authtype>0</authtype> <username/> <password/> <publickey/> <privatekey/> <port/> <description/> <inventory_link>0</inventory_link> <applications> <application> <name>NetWork</name> </application> </applications> <valuemap/> <logtimefmt/> <application_prototypes/> </item_prototype> <item_prototype> <name>ha.vserver.downtime $1</name> <type>0</type> <snmp_community/> <multiplier>0</multiplier> <snmp_oid/> <key>ckey.ha.downtime[{#SNAME}]</key> <delay>60</delay> <history>90</hi