目前开源网络监控系统Zabbix在不少企业得到了应用,但是Zabbix自身所能监控的粒度和深度都难以满足企业运维管理的深层次需求,特别是对于应用系统的可用性监控方面存在较大的缺陷。本文结合某公司的IT基础架构,通过对Zabbix监控系统实施二次开发和改造,实现了对部分应用系统可用性状态的实时监控;本文对具体的改造方法和思路进行了详细阐述,并给出了改造后的自动监控系统的运行效果,希望对各位同行在企业IT基础设施监控方面有所启发。
一.背景
Zabbix是一个较为成熟的基于WEB界面的提供分布式系统监控以及网络监视功能的企业级开源解决方案。相信了解Linux和开源监控系统的运维管理人员对Zabbix并不陌生,由于Zabbix部署的灵活性以及开源的特征,目前不少企业已经部署Zabbix来对自身的IT基础设施的运行状态进行实时监控;笔者所在的公司也不例外,两年前就已经尝试部署Zabbix,目前已经将公司大部分服务器和网络设备纳入了Zabbix监控范围,使Zabbix成为运维管理人员最为倚仗的故障监控利器。
但是目前Zabbix仅仅只能对一些比较常规的CPU利用率、端口状态、流量、进程使用等项目进行监控,难以针对应用和服务的可用性进行实时监控,即使是最新的2.2版本,面向应用的监控方面仍然没有大的改进。而当前随着各类应用复杂性的提高,导致各类应用出现故障的原因越来越难以排查,如果和过去一样,仅仅只是针对服务器的CPU、内存、进程等常规项目实施监控,在某些情况下就难以发现应用的异常,不能起到实时监控的效果;因为一个应用出现异常,很多时候并不是CPU、内存等一些常规问题所引起的,而是系统自身的BUG或负载有限等一些隐秘的原因所引起的,所以有时候Zabbix显示常规的监控项目状态都正常,但是应用实际已经不可用,这样就失去了自动监控的意义。
为了弥补Zabbix针对应用监控方面的不足,本文围绕Zabbix监控系统做了深入的研究,结合运维自动化的思想,开发出一套能够支持部分常见应用的自动监控系统;该系统是在已有Zabbix系统的基础上进行二次开发所形成的,并不影响之前针对服务器和网络设备的监控效果。该系统已经在本公司范围内得到应用,目前能够针对DHCP、Radius认证、Wins以及SSLVPN系统实施可用性的自动监控。
二.系统设计思路
既然传统的Zabbix监控项目难以反映出各类应用系统是否正常,只有亲自使用系统才能真正判断出应用系统是否可用,但是要做到实时监控,就必须用到运维自动化的相关技术了,否则单凭人工操作是无法保证监控的时效性的。本文正是利用运维自动化的核心技术-脚本编程技术来实现,我们采用脚本程序来模拟客户端或用户访问应用系统的流程,将该流程自动化、程序化,利用Zabbix监控系统的接口将系统状态传递给Zabbix,通过Zabbix系统的Trigger判断,将应用系统的可用状态的变更以页面、邮件或者短信的方式展示给运维管理人员,以达到实时监控的目的。
本监控系统可分为两大模块:模拟用户行为模块和应用状态感知模块。这两大模块彼此关联协作,由模拟用户行为模块不断循环获取应用的状态,然后将状态传递给应用状态感知模块,应用状态感知模块经过判断,将状态信息以多种方式展示给运维管理人员。下面将对这两大模块分别进行介绍。
1. 模拟用户行为模块
该模块会根据提取出的用户操作流程,将用户使用应用系统的一系列操作利用程序来自动实现,然后将程序的操作结果记录下来,提供给后续的应用状态感知模块进行判断,下图1为该模块的详细流程图:
图1 模拟用户行为模块流程图
2. 应用状态感知模块
该模块接受模拟用户行为模块所传递的应用系统状态的信息,分析该状态信息,然后将信息展示给运维管理人员;若出现服务状态的变更,还会以短信、邮件等多种方式实时通知管理员。该模块的功能均由Zabbix监控系统自身承担;下图2即为应用状态感知模块的详细流程图:
图2 应用状态感知模块流程图
三.系统的具体实现
本系统目前已经实现了对公司的DHCP、Radius认证、Wins服务及SSLVPN应用系统的可用性的实时监控,下面将分别进行阐述。
1. DHCP应用状态的监控
本公司所使用的DHCP服务是由Windows server 2003下提供的,自动实时监控DHCP服务的关键在于程序需要不停去模拟用户利用DHCP服务器获取IP地址的过程,这个过程可以利用两条BAT命令"ipconfig /release"和"ipconfig /renew"来表示,即释放IP和重新获取IP,如果DHCP应用出现故障,那么主机将无法通过上述两条命令获取IP地址,那么其他同网段的主机将无法ping通该主机。我们采用一台Windows server 2003的主机来作为运行脚本程序的测试主机,该程序采用BAT脚本实现,起到模拟用户行为的作用,具体BAT脚本程序如下所示:
- @echo off
- :des
- ipconfig /release
- ipconfig /renew
- echo "程序正在运行,勿关闭此窗口!"
- choice /c yn /n /t 10 /d y
- goto des
上述程序代码将每隔10秒循环执行"ipconfig /release"和"ipconfig /renew"去重新从DHCP服务器获取IP地址,那么测试主机能否获得正确的IP地址就代表了DHCP应用是否可用,下一步就需要将该状态信息传递给应用状态感知模块,即Zabbix监控系统。
在Zabbix监控系统中我们将会做如下几步工作:
(1)将DHCP服务器纳入监控,安装Zabbix agent,然后在DHCP server的items中添加一项监控项,各属性设置如下:Name为"DHCP service test",Key为"icmpping[测试主机的IP,3]",Interval设置为10秒,其他的时间属性可按照自己的需求进行设置,该监控项的意思是每隔10秒Zabbix服务器将会向测试主机发送3个icmpping包,以此来确认能否与该主机通讯,如果能够ping通,则返回值为1,否则返回值为0 ;这样就能判断该主机是否获得了正确的IP地址,也就实现了对于DHCP应用状态的实时监控。
(2)设置一个Trigger,用于判断DHCP应用状态是否发生变化,如果发生变化,将在页面展示报警信息;Trigger属性设置如下:Name为"DHCP service on DHCPSVR is down"Expression为"{DHCPSVR:icmpping[测试主机的IP,3].last(0)}=0&{DHCPSVR:icmpping[测试主机的IP,3].prev(0)}=0",表示如果程序连续两次探测DHCP应用均不可用的话,则可以判定DHCP应用出现故障,通过将两次检测结果进行与操作,可以有效减少误报的概率。
(3)设置一个Action,用于设置当event触发Trigger时,Zabbix应该做出的动作,包括给运维管理人员发送邮件、短信等。Action的主要属性设置如下:Name为"DHCP Service monitoring",触发条件Conditions为前面所设置的Trigger"DHCPSVR:DHCP service on DHCPSVR is down",Operations为"Send message to users:管理员",Delay为"Immediately"。该Action的意思是当触发对应Trigger时,立即向管理员发送报警短信,短信的内容也可以自己定制,在此不再赘述。
2.Radius认证应用状态的监控
Radius认证服务在很多公司有广泛应用,用于应用系统和设备登录的AAA认证;本公司的Radius服务的一项重要应用就是网络设备的登录认证。实现Radius认证应用状态的自动实时监控的关键点仍然是提取出用户使用Radius应用的流程,然后以脚本程序去实现该流程,然后将检测结果传递给Zabbix。本文采用基于SecureCRT平台的VBScript语言编写模拟用户登录Cisco交换机行为的脚本程序,登录后会先后出现输入username和password的提示,利用程序控制输入合法的用户名和密码,,然后回车,如果Radius应用正常,则会进入交换机的配置页面,如果Radius应用出现故障,则会在一段时间后出现"time out"的提示。我们仍然利用上述那台Windows server 2003的主机作为测试机,具体的VBScript脚本程序如下所示:
- # $language = "VBScript"
- # $interface = "1.0"
- '该脚本用于探测公司Radius服务的状态
- Sub Main
- Dim fso,f1
- Set fso=CreateObject("Scripting.FileSystemObject")
- Do While (1)
- crt.Screen.Synchronous=True
- crt.Session.Connect("/telnet 172.19.39.248")
- crt.Screen.WaitForString "Username:"
- crt.Screen.Send "ishare" & vbcr
- crt.Screen.WaitForString "Password:"
- crt.Screen.Send "123456" & vbcr
- crt.Screen.WaitForString ">",2
- judgeString=crt.Screen.Get(12,1,12,20)
- Set f1=fso.OpenTextFile("C:\Radius监控脚本\cosbulk\judge.txt",2,True)
- f1.writeline(judgeString)
- f1.Close()
- 'crt.sleep 500
- crt.Screen.Synchronous=False
- crt.Session.Disconnect
- crt.Sleep 5000
- Loop
- End Sub
上述程序中,172.19.39.248是测试交换机的管理IP,ishare和123456分别为测试用的用户名和密码;该脚本程序控制每隔5秒钟去telnet一下测试交换机,如果输入用户名和密码后能够正常进入交换机配置界面,那么说明Radius应用是可用的,将显示的交换机名称写入judge.txt文件中;反之,说明Radius应用出现故障,将"time out"信息写入judge.txt文件中。文件中不同的内容代表了Radius应用的状态。下一步就需要该状态信息传递给Zabbix监控系统。
在Zabbix监控系统中我们需要做如下几个方面的操作:
(1)在测试主机的items中加入一项监控项,各属性如下:Name为"Radius Service status",Key为"vfs.file.regmatch[judge.txt,测试交换机名称]",Interval为10秒,其他时间属性可以按照自己需求设置。该监控项的意思是每隔10秒去检测judge.txt中的内容,如果是测试交换机的名称,则返回值为1;否则返回0,这样就能判断Radius应用是否可用,实现了对其可用性的实时监控。
(2)创建一个Trigger,用于判断Radius应用状态是否发生变化,如果发生变化,将在页面展示报警信息;Trigger属性设置如下:Name为"Radius Service is down",Expression为"{vfs.file.regmatch[judge.txt,测试交换机名称].last(0)}=0&{vfs.file.regmatch[judge.txt,测试交换机名称].prev(0)=0",表示如果程序连续两次探测Radius应用均不可用的话,则可以判定Radius应用出现故障,通过两次检测结果的与操作,可以有效减少误报的概率。
(3)创建一个Action。Action的主要属性设置如下:Name为"Radius Service monitoring",触发条件Conditions为前面所设置的Trigger"Radius service is down",Operations为"Send message to users:管理员",Delay为"Immediately"。该Action的意思是当触发对应Trigger时,Zabbix将立即向管理员发送报警短信。
3.Wins应用状态的监控
本公司使用的Wins服务是由Windows server 2003提供的,可以通过"nblookup"这个BAT命令来测试Wins应用是否可用,如果Wins应用正常,则可以将主机名解析为正常的IP地址;反之,则会解析失败。本文首先将利用nblookup命令解析主机名的脚本程序嵌入Zabbix已有的脚本库中,以方便后面的调用;具体方式如下:在测试主机上打开Zabbix agent的配置文件"zabbix_agentd.conf",在文件最后加入"UnsafeUserParameters=1"和"UserParameter= service.wins,C:\WINDOWS\system32\nblookup /s Wins服务器IP netsqlsvr | find "主机netsqlsvr的IP"",这样就将对应的脚本程序以"service.wins"的形式嵌入Zabbix系统中了。在Zabbix系统中所需的设置如下:
(1)在测试主机的items中加入对应监控项,监控项的属性如下:Name为"Service Wins status",Key为"service.wins",Interval为15秒,其他时间属性可以按照自己需求设置。该监控项的意思是每隔15秒使用nblookup命令去测试Wins的应用状态,如果Wins应用状态正常,则返回netsqlsvr主机的正确IP,否则一段时间后会返回"time out"信息,这样就实现了对Wins应用状态可用性的实时监控。
(2)创建一个Trigger,用于判断Wins应用状态是否发生变化,如果发生变化,将在页面展示相应的报警信息;Trigger属性设置如下:Name为"Wins Service is down",Expression为"{service.wins.strlen(0)}=0",表示如果程序如果没有获得正确的解析IP,则判定Radius应用出现故障。
(3)创建一个Action。Action的主要属性设置如下:Name为"Wins Service monitoring",触发条件Conditions为前面所设置的Trigger"Wins service is down",Operations为"Send message to users:管理员",Delay设为"Immediately"。该Action的意思是当触发对应Trigger时,Zabbix将立即向管理员发送报警短信。
4.SSLVPN系统状态的监控
本公司所使用SSLVPN设备是Juniper SA 6500,该设备为外网用户提供远程接入内网办公的功能,是我司极为重要的网关设备。之前只能利用Zabbix系统对该设备的一些常规参数进行监控,无法获知该系统的真实可用状态;下面将介绍对SSLVPN应用系统实现可用性实时监控的方法,目前该方法已经在我司得到应用,收到了良好的效果。我们仍然采用脚本程序来模拟用户访问SSLVPN系统,访问流程如下图3所示:
图3 用户访问SSLVPN系统流程图
对于上述流程,本文采用VBScript脚本语言来实现,具体程序代码如下所示:
- Set WshShell=WScript.CreateObject("WScript.Shell") '创建对象,可以实现虚拟键盘
- Set fso=CreateObject("Scripting.FileSystemObject") '创建文件对象
- Set objWMIService = GetObject ("winmgmts:\\.\root\cimv2")
- Sub Close_Process(ProcessName) '强制结束进程函数
- Dim objShell
- Set objShell = wscript.CreateObject("wscript.shell")
- objShell.Run "ntsd -c q -pn " & ProcessName, 0, True
- End Sub
- On Error Resume Next
- Do while(1)
- Set ie=WScript.CreateObject("InternetExplorer.Application") '创建对象,打开IE
- ie.visible=true 'IE转至前台
- ie.navigate "http://192.168.103.1" '打开网页
- Wscript.Sleep 4000
- if ie.busy=false And ie.readystate = 4 then'如果页面加载成功,则可以进行下一步,
- '如果不能显示,说明出现问题
- Wscript.Sleep 1000
- WshShell.appactivate"Junos Pulse Secure Access Service"
- Wscript.Sleep 2000
- if instr(1,ie.document.body.innerText,"username",1)>0 Then '如果存在该标签,表明已经成功显示登录页面
- ie.document.getElementById("Username").value="ishare" '输入账号、密码
- ie.document.getElementById("Password").value="%rdx5tgB"
- Wscript.Sleep 3000 '等3s然后回车,虚拟触发。
- WshShell.SendKeys "{ENTER}"
- Wscript.Sleep 20000
- '搜索网页中是否存在内网主页关键字,判断是否登录成功
- if ie.busy=false And ie.readystate = 4 then '网页内容加载完毕
- WshShell.appactivate"Junos Pulse Secure Access Service - 主页"
- Wscript.Sleep 2000
- strContent=ie.document.body.innerText '读取网页内容
- if instr(1,strContent,"内网主页",1)>0 Then '如果存在该标签,表明已经成功登录
- '将1写入文件
- Set f1=fso.OpenTextFile("C:\SSLVPN监控脚本\cosbulk\judge.txt",2,True)
- f1.writeline(1)
- f1.Close()
- Wscript.Sleep 2000
- WshShell.appactivate"Junos Pulse Secure Access Service - 主页"
- Wscript.Sleep 2000
- WshShell.SendKeys "{TAB 9}"
- Wscript.Sleep 2000
- WshShell.SendKeys "{ENTER}"
- elseif instr(1,strContent,"已经有其它用户会话正在进行中:",1)>0 Then
- WshShell.SendKeys "{TAB 2}"
- Wscript.Sleep 2000
- WshShell.SendKeys "{ENTER}" '点击继续运行
- Wscript.Sleep 20000
- if ie.busy=false And ie.readystate = 4 then '网页内容加载完毕
- WshShell.appactivate"Junos Pulse Secure Access Service - 主页"
- Wscript.Sleep 2000
- strContent=ie.document.body.innerText '读取网页内容
- if instr(1,strContent,"内网主页",1)>0 Then '如果存在该标签,表明已经成功登录
- Set f1=fso.OpenTextFile("C:\SSLVPN监控脚本\cosbulk\judge.txt",2,True)
- f1.writeline(1)
- f1.Close()
- Wscript.Sleep 2000
- WshShell.appactivate"Junos Pulse Secure Access Service - 主页"
- Wscript.Sleep 2000
- WshShell.SendKeys "{TAB 9}"
- Wscript.Sleep 2000
- WshShell.SendKeys "{ENTER}"
- else
- '将0写入文件
- Set f1=fso.OpenTextFile("C:\SSLVPN监控脚本\cosbulk\judge.txt",2,True)
- f1.writeline(0)
- f1.Close()
- end if
- else
- Set f1=fso.OpenTextFile("C:\SSLVPN监控脚本\cosbulk\judge.txt",2,True)
- f1.writeline(0)
- f1.Close()
- end if
- else
- '将0写入文件
- Set f1=fso.OpenTextFile("C:\SSLVPN监控脚本\cosbulk\judge.txt",2,True)
- f1.writeline(0)
- f1.Close()
- end if
- else
- Set f1=fso.OpenTextFile("C:\SSLVPN监控脚本\cosbulk\judge.txt",2,True)
- f1.writeline(0)
- f1.Close()
- end if
- else
- Set f1=fso.OpenTextFile("C:\SSLVPN监控脚本\cosbulk\judge.txt",2,True)
- f1.writeline(0)
- f1.Close()
- end if
- else
- Set f1=fso.OpenTextFile("C:\SSLVPN监控脚本\cosbulk\judge.txt",2,True)
- f1.writeline(0)
- f1.Close()
- end if
- ie.quit
- Set ie=nothing
- Set colProcessList = objWMIService.ExecQuery("Select * from Win32_Process where Name='dsNcService.exe'")
- For Each objProcess In colProcessList
- Set list = GetObject("winmgmts:").execquery("Select * from Win32_Process where Name='dsNcService.exe'")
- if list.count > 0 then '检测进程是否存在
- Close_Process "dsNcService.exe"
- end if
- Next
- Wscript.Sleep 5000
- Loop
上述脚本程序将每次检测SSLVPN系统可用性的结果写入judge.txt中,1表示系统正常,0表示系统出现故障,下面需要将该状态信息传送给Zabbix,由Zabbix做出判断和展示;在Zabbix需要进行如下设置:
(1)在测试主机的items中加入对应监控项,监控项的属性如下:Name为"The availability of SSLVPN",Key为"vfs.file.regmatch[judge.txt,1]",Interval为30秒,其他时间属性可以按照自己需求设置。该监控项的意思是每隔30秒去检测judge.txt中的内容,如果文件内容是1,则返回值为1;否则返回0,这样就能判断SSLVPN系统是否可用,实现了对其可用性的实时自动监控。
(2)创建一个Trigger,用于判断SSLVPN应用状态是否发生变化,如果发生变化,将在页面展示报警信息;Trigger属性设置如下:Name为"SSLVPN Service is unavailable",Expression为"{vfs.file.regmatch[judge.txt,1].last(0)}=0&{vfs.file.regmatch[judge.txt,1].prev(0)=0";该Trigger表示如果程序连续两次检测SSLVPN系统为不可用状态,则判定SSLVPN应用出现故障。
(3)创建一个Action。Action的主要属性设置如下:Name为"The SSLVPN monitorning",触发条件Conditions为前面所设置的Trigger"SSLVPN Service is unavailable",Operations为"Send message to users:管理员",Delay为"Immediately"。该Action的意思是当触发对应Trigger时,Zabbix会立即向管理员发送报警短信。
四.成果展示
下面将对本系统对于DHCP、Radius认证、Wins和SSLVPN应用系统的自动监控效果进行展示:
(1)DHCP应用的自动监控测试
为测试需要,本文选择在非工作时间暂停一下DHCP应用,大约20秒以后,Zabbix监控页面就会出现如下图4所示的报警信息:
图4 DHCP应用故障的报警信息
同时,手机也会收到报警短信,但手机不方便截图,此处省略。然后再恢复DHCP应用,大约20秒后,Zabbix监控页面的报警信息就会消失,同时手机也会收到DHCP应用恢复的短信。
(2)Radius认证应用的自动监控测试
对于Radius认证应用的监控测试,本文采用同样的方式暂停一下Radius应用,大约15秒后,Zabbix监控页面会出现如下图5所示的报警信息:
图5 Radius应用故障的报警信息
同时手机也会收到Radius应用故障的报警短信。恢复Radius应用大约15秒后,Zabbix监控页面的报警信息会消失,手机同样也能收到Radius应用恢复正常的短信。
(3)Wins应用的自动监控测试
对于Wins应用的监控测试,暂停一下Wins应用后,大约15秒左右,Zabbix监控页面会出现如下图6所示的报警信息:
图6 Wins应用故障的报警信息
同时手机也会收到Wins应用故障的报警短信。恢复Wins应用大约15秒后,Zabbix监控页面的报警信息会消失,手机同样也能收到Wins应用恢复正常的短信。
(4)SSLVPN应用的自动监控测试
造成SSLVPN系统不可用的原因有很多,如网络不通、设备硬软件故障、Radius认证服务异常(本SSLVPN系统的用户认证方式采用的是Radius认证)等,本次测试采用模拟Radius认证服务异常来验证系统的监控效果。暂停一下Radius认证服务之后,大约30秒后,Zabbix监控页面会出现如下图7所示的报警信息:
图7 Radius应用故障和SSLVPN应用系统故障的报警信息
同时手机会收到Radius和SSLVPN应用故障的报警短信。待Radius应用恢复大约30秒后,Zabbix监控页面的报警信息会消失,手机同样也能收到Radius和SSLVPN应用恢复正常的短信。
五.总结与展望
本文介绍了开源网络监控系统Zabbix在应用监控方面的缺陷,结合某公司自身的Zabbix应用实践经验,给出了解决Zabbix应用监控方面缺陷的一套方案,即通过二次开发的方式对Zabbix原型系统进行改造,打造一套支持针对应用状态进行实时监控的自动监控系统。目前该自动监控系统已经在公司内部得到广泛应用,支持对DHCP、Radius认证、Wins及SSLVPN应用系统状态的实时监控,我们计划后期将持续改造该监控系统,尽可能将所有应用系统纳入实时监控的范围。本文重在思路,未来其他有需求的企业可以按照这个思路,结合自身的实际网络环境对Zabbix实施二次开发,形成符合自身需求的一体化自动监控系统。同时我们也应该持续关注Zabbix系统的版本变更,希望未来Zabbix能够在应用状态的实时监控方面有所突破。