Centos 6.4 nagios搭建(三)之集群部署
第一篇文章:https://blog.51niux.com/?id=40 讲了nagios服务器与客户端之间不同的搭建过程,以及通过nrpe认证过程。
第二篇文章:https://blog.51niux.com/?id=78 对nagios服务器涉及到配置文件进行了详解,并简单阐述了各配置文件之间的调用过程。
这篇文章呢,主要是讲述一下线上应该怎么部署会更规范一点,以及一些其他的补充。
一、nagios规范的部署情况(只是个人觉得比较规范一点的,并不保证权威)
linux一切皆文件,nagios也是如此,我们的配置都写到文件里面,然后通过nagios服务去巡检我们的文件,根据我们设置的规则进行工作。机器少可能几个文件就可以轻松搞定了,但是如果机器多了,随着不同的服务,不同的监控项,显然我们应该考虑一个更好的管理方式,所以就应该采用目录和模板的方式来管理。
1.1 首先:我们应该有一个主机和主机组目录,专门用于存放我们这些主机配置文件的。
# cat /usr/local/nagios/etc/nagios.cfg
cfg_dir=/usr/local/nagios/etc/hosts #如果没有加上这句话,开启主机目录的形式
cfg_dir=/usr/local/nagios/etc/hostgroups #这句话就定义了我们主机组目录
#mkdir /usr/local/nagios/etc/{hosts,hostgroups} #如果目录不存在,重启服务会报错找不到目录
现在我们看一下我hosts的目录结构及文件定义:
[root@smaster hosts]# tree -L 2 /usr/local/nagios/etc/hosts/
/usr/local/nagios/etc/hosts/ #这是我定义的用语存放主机文件目录
|-- cache #首先定义了一个cache目录,这个目录的名称与一个叫做cache的主机组名称对应
| |-- bj_192.168.1.107.cfg #主机文件呢,以(机房简写_ip地址)来命名,又比如你要区分 物理机和虚拟机,可以用bjidc和jbkvm来区分。
| `-- bj_192.168.1.108.cfg
|-- mysql
| `-- sh_192.168.1.109.cfg
|-- proxy
| |-- tj_192.168.1.110.cfg
| `-- tj_192.168.1.111.cfg
`-- web
|-- jn_192.168.1.112.cfg
`-- jn_192.168.1.113.cfg
然后我们在来看一下我的主机文件是如何定义的:
# cat cache/bj_192.168.1.107.cfg #当然这种命名方式在多主机部署的时候是比较麻烦的,所以可以 以IP.cfg,里面的host_name也是以IP的形式来设置主机,当然可以采用其他的方式在报警的时候来显示主机名称,如:当然报警的时候可以通过nrpe里面的插件调用hostname的方式显示主机名。
define host{
use linux-server #使用模板里面的linux-server模板
host_name bj_cache_01 #主机名称,以(机房简写_服务类型/业务类型_服务编号)命名,这里自行制定
alias beijing_cacheserver_01 #这里可以不要的
hostgroups cache #属于哪个主机组
address 192.168.1.107 #主机IP
}
好了然后再让我们看看主机组的目录结构:
# tree -L 1 /usr/local/nagios/etc/hostgroups/ #可以看到每个主机组为一个配置文件
/usr/local/nagios/etc/hostgroups/
|-- cache.cfg
|-- mysql.cfg
|-- proxy.cfg
`-- web.cfg
那么让我们看看主机组配置文件怎么写的呢?
# cat /usr/local/nagios/etc/hostgroups/cache.cfg
define hostgroup{
hostgroup_name cache #就单纯的定义了一个主机组的名称
alias Cache Servers #这里还是要写上的,web页面会看到
}
注:主机组的另一种添加主机的形式(不推荐):
define hostgroup{
hostgroup_name cache
alias Cache Servers
members bj_cache_01,bj_cache_02 #看到这个members大家就熟悉了,网上的文章大多这么写,在主机组里面定义有哪些主机,但是机器少还好说,但是主机几百台,你要在这里写几百个主机吗,显然不现实,所以不推荐这种形式,推荐在主机配置文件里面就指定自己属于哪个组
}
下面让我们来看一下结果:
博文来自:www.51niux.com
1.2 再次:我们应该有一个服务和服务组目录,专门用于存放我们服务的配置文件和服务组的配置文件。
# cat /usr/local/nagios/etc/nagios.cfg
cfg_dir=/usr/local/nagios/etc/services
cfg_dir=/usr/local/nagios/etc/servicegroups
现在让我们看一下services的目录结果(我们定义了几个基本的nagios自带的插件):
# tree -L 2 /usr/local/nagios/etc/services/
/usr/local/nagios/etc/services/ #这是我们定义的服务目录
`-- BaseService #在下面我们又创建了一个以此服务所在的组命令的目录,从目录名称看这是一个主机应该最基本的监控项目,你再定义其他的服务组也创建目录,比如web服务组,在那个目录下面再创建对应的service文件,这样在维护的时候是相对比较清晰的。
|-- disk.cfg #监控磁盘的
|-- load.cfg #监控负载的
|-- swap.cfg #监控swap分区的
|-- total_procs.cfg #监控总进程数的
|-- users.cfg # 监控登录用户数的
`-- zombie_procs.cfg #监控僵尸进程数的
#当然还应该有监控服务器内存啊之类的其他一些监控,那个就属于自己编写插件的范畴了.
那么让我们查看一下其中一个service配置文件是如何编写的:
# cat /usr/local/nagios/etc/services/BaseService/disk.cfg
define service{
#host_name bj_cache_01 #也可以单加主机,多个主机之间用逗号隔开
#hostgroup_name web,mysql,proxy,cache #这里注释掉了,只是像说明一种形式,就是可以加组,多个组之间用逗号隔开。
hostgroup_name allhost #如果我们组分的特别细,那么我们这好几个service服务项都要加一堆用户组,如果再有新分组又要都加一遍,所以我们可以定义一个所有linux服务器的组,所有的机器都在这个组里面,基本基础服务这里是不用变动的,对维护会好很多,但是就是nagios得web维护界面哪里会多一个重复的大组,当然如果你不想web展示界面主机组重复的话,可以让一些特殊的服务单独几个组,剩余的机器在一个大组里面。
use generic-service
service_description CheckDisk #这个就是服务的描述,在web页面展示
servicegroups BaseService #这里定义了此服务属于哪个组,多组用逗号隔开
check_command check_nrpe!check_disk #这里是通过nrpe让远端执行我们发送过去的参数,这个参数就是check_disk
}
# cat /usr/local/nagios/etc/services/BaseService/zombie_procs.cfg
define service{
hostgroup_name allhost
use generic-service
service_description CheckZombieProcs #如果调用同一个插件,如(/usr/local/nagios/libexec/check_procs),这里千万不要重复
servicegroups BaseService
check_command check_nrpe!check_zombie_procs #就是把check_zombie_procs传到被监控端上面去
}
# cat /usr/local/nagios/etc/services/BaseService/total_procs.cfg
define service{
hostgroup_name allhost
use generic-service
service_description CheckTotalProcs #千万不要跟上面重复,不然下面这个在web页面上就显示不出来了
servicegroups BaseService
check_command check_nrpe!check_total_procs
}
下来我们看下服务组的定义:
# cat /usr/local/nagios/etc/servicegroups/BaseService.cfg
define servicegroup{
servicegroup_name BaseService #服务组名称
alias System Base Service #服务组的别名
}
注:服务组的另外一种格式,不好玩,不推荐,粘贴在下面:
# cat test.cfg #这里我们又定义了一个测试组
define servicegroup{
servicegroup_name TestService
alias Test Base Service
members sh_mysql_01,Check_Disk,bj_cache_01,Check_Swap #这里的格式为主机,服务的如果多个主机就主机,服务文件中service_description的定义,主机,服务文件中service_description的定义.......
}
下面是测试结果:
下面让我们看下远端的被监控主机的nrpe.cfg的设置
[root@master ~]# cat /usr/local/nagios/etc/nrpe.cfg |tail -6 #注意command[]中括号里面的内容,跟服务端service里面定义check_nrpe!后面参数
command[check_users]=/usr/local/nagios/libexec/check_users -w 5 -c 10
command[check_load]=/usr/local/nagios/libexec/check_load -w 15,10,5 -c 30,25,20
command[check_disk]=/usr/local/nagios/libexec/check_disk -w 20% -c 10% -p /
command[check_swap]=/usr/local/nagios/libexec/check_swap -w 20% -c 10%
command[check_zombie_procs]=/usr/local/nagios/libexec/check_procs -w 5 -c 10 -s Z
command[check_total_procs]=/usr/local/nagios/libexec/check_procs -w 150 -c 200
既然上面我们提出了所有的主机或者不是特殊服务的一大部分的主机在一个大的主机组里面的概念,那么我们下面主机配置文件那里就要发生变化:
# cat /usr/local/nagios/etc/hosts/cache/bj_192.168.1.107.cfg #以一个主机配置文件举例
define host{
use linux-server
host_name bj_cache_01
alias beijing_cacheserver_01
hostgroups allhost,cache, #就是这里,我们让这台主机从属于两个组,一个所有主机组,用来加载基本的BaseService服务,然后再属于cache主机组,我们就可以再定义一个cache的服务组,cache服务组里面定义一些特殊的监控来监控这个cache组内的主机。如果你特殊组比较少呢,这里就完全就属于cache组,然后BaseService下面的各个服务配置文件里面写成类似于:hostgroup_name allhost,cache 这样的形式,这样也不会造成主机组重复。
address 127.0.0.1
}
# cat /usr/local/nagios/etc/hostgroups/allhost.cfg #要定义一个主机组的配置文件
define hostgroup{
hostgroup_name allhost
alias All Host Servers
}
下面让我们看看效果图:
博文来自:www.51niux.com
1.3 巧用escalations限制Nagios报警次数
通过前面的知识我们看到nagios只能定义出现问题没有解决多长时间再次报警,显然不够灵活,可以用escalations来自动调节。
# vi /usr/local/nagios/etc/nagios.cfg #添加下面一行
cfg_file=/usr/local/nagios/etc/objects/escalations.cfg
添加配置内容:
# cat /usr/local/nagios/etc/objects/escalations.cfg
define hostescalation { #定义主机状态监控
#host_name bj_cache_01 #被监控主机名称
hostgroup_name allhost #被监控主机组名称
first_notification 4 #从四条信息起,改变发送通知频率间隔
last_notification 0 #从几条信息起,恢复频率间隔。0表示不恢复。
notification_interval 3 #通知间隔单位为分钟,这里一般尽量设置的大一点如240,我这里是为了测试效果
contacts dbaadmin #从第四条信息开始通知发送给谁,也可以定义联系人组
}
define serviceescalation { #这是关于服务的定义
hostgroup_name allhost #还是对哪些主机组进行设置 ,注意一点,这里设置的主机,一定要有下面设置的服务项,不然的话nagios启动是报错的,但是对于常规性的监控设置所有主机组就可以了。但是如果是特别的主机,如监控不同web服务器的url状态,或者ssd盘的性能啊等等这些不是统一的监控服务,这里要摸就是用单独设置的主机组,如果主机少的话,可以用逗号将多主机分开。
service_description CheckDisk,CheckSwap #被监控的服务名称,与我们之前定义的哪些服务.cfg里面一致,如disk.cfg里面service_description里面定义的名称CheckDisk,如果对所有的服务都运用这个规则可以用*代替。
first_notification 4
last_notification 0
notification_interval 3 #可以设置大一点480或者600,这样避免频繁的报警,因为毕竟我们一个问题已经报过几次了
contact_groups dbaadmins #对于我们定义的那些服务监控,第四次问题通知的时候,信息发送给哪个联系人组
}
#为了测试效果明显我讲服务监控改为了1分钟一报警,从上图可以看出我们定义的那两个服务在第四条信息的时候通知人已经发生了变化,然后再四条信息之后通知的时间间隔也变为了3分钟。
#但是存在一个问题,当问题解决,服务恢复的时候,通知并不会发到我们templates.cfg里面定义的联系人组nagiosadmin,而是通知escalation定义的联系人或者联系人组。
#用service_description *代表所有的服务监控。
博文来自:www.51niux.com
1.4 nagios的分级报警
这里说的分级报警主要说的是监控服务的分级报警,服务的警告主要分为w和c两种状态嘛,我们可以让w状态发送给一组人,c状态发送给另一组人如包含有领导的组,而r恢复状态可以让所有相关的人发送通知。
简单示例一:
第一步:在contacts.cfg配置文件定义不同联系人
define contact{ #先定义了一个联系人专门接受严重状态的报警,像这里的联系人一般级别高一点
contact_name cadmin #定义联系人的名称
alias CRITICAL Admin
service_notification_period 24x7
host_notification_period 24x7
service_notification_options c,r #定义接受哪种类型的通知
host_notification_options d,r #定义接受主机什么状态的通知
service_notification_commands notify-service-by-email
host_notification_commands notify-host-by-email
email 123456789@qq.com #定义接受联系人邮箱
}
define contact{ #再定义一个联系人负责接受警告状态的报警(这里是为了方便区分演示,其实应该连服务w状态都要接收的)
contact_name wadmin #定义联系人名称
alias WARNING Admin
service_notification_period 24x7
host_notification_period 24x7
service_notification_options w,u,r #接受服务w,u,r的通知,如果生产环境的话应该连c都加上。
host_notification_options d,u,r #接受主机d,u,r状态的通知
service_notification_commands notify-service-by-email
host_notification_commands notify-host-by-email
email test@51niux.com #定义接受联系人的邮箱
}
注:这里为了区分演示所以wadmin只接收了一部分报警类型而不是全部,一般应该是让wadmin这种类型的联系人接受全部的报警内容。的。那么定义就没有上面那么复杂,如下面的配置:
define contact{
contact_name wadmin
alias WARNING ANDCRITICAL Admin
use generic-contact
email test@51niux.com
}
第二步:修改组名为admins的联系人组
define contactgroup{
contactgroup_name admins #因为是为了简单演示,templates.cfg里面正好定义的这个联系人组,就在这里修改下此联系人组。
alias Nagios Administrators
#members nagiosadmin #将原来定义的联系人注释掉
members wadmin,cadmin #将定义的两个联系人添加到此
}
第三步:# /etc/init.d/nagios reload #重新加载配置文件
第四步:找一台nagios客户端进行阀值修改,查看分级通知机制是否生效。
下面我们查看一下测试的结果:
从上图中的测试结果可以看出,我们的目的已经达到,不同的通知类型已经发送到不同的联系人。
更进一步规范示例二:
如果我们联系人组还好,如果联系人很多的情况下,像示例一就不合适,应该引入模板的概念,下面简单举例一个:
第一步:在contacts.cfg配置文件定义不同联系人
# vi contacts.cfg
define contact{
contact_name cadmin
alias CRITICAL Admin
use cgeneric-contact #让其调用模板里面一个 cgeneric-contact模板
email 123456789@qq.com
}
define contact{
contact_name wadmin
use wgeneric-contact #让其调用模板里面一个 wgeneric-contact模板
alias WANGING Admin
email test@51niux.com
}
第二步:还是定义联系人组
# vi contacts.cfg
define contactgroup{
contactgroup_name admins #因为我们template模板里面服务信息发送的联系人组还是admins,所以这里先用这个联系人组测试。
alias Nagios Administrators
members wadmin,cadmin
}
第三步:定义联系人模板:
# vi templates.cfg
define contact{ #我们这个模板就算母模板吧,定义了大部分全局的东西
name generic-contact
service_notification_period 24x7
host_notification_period 24x7
service_notification_options w,u,c,r,f,s
host_notification_options d,u,r,f,s
service_notification_commands notify-service-by-email
host_notification_commands notify-host-by-email
register 0
}
define contact{ #这就相当于一个子模板
name cgeneric-contact
use generic-contact #继承 generic-contact 模板里面的东西
service_notification_options c,r #虽然这里定义的跟母模板冲突了,但是以子模板里面定义的值为准
host_notification_options d,r
register 0
}
define contact{
name wgeneric-contact
use generic-contact #继承 generic-contact 模板里面的东西
service_notification_options w,u,r #还是为了区分,我们让其接受w状态报警不接受c状态报警
host_notification_options d,u,r
register 0
}
第四步:# /etc/init.d/nagios reload #重新加载配置文件
第四步:找一台nagios客户端进行阀值修改,查看分级通知机制是否生效。
下面我们查看一下测试的结果:
再进一步规范示例三:
既然我们的联系人可以进行这种母模板,子模板继承的形式来进行通知信息等级区分,那么我们的service服务是不是也可以根据不同的状态如u,w,c是不是可以区别开来,采用各自的机制来进行状态监测并发送到对应的联系组呢。
先说一个错误的实验思路,但是能让我们理解一个东西:
在templates.cfg定义两个service,一个c状态报警,报警间隔为2分钟,一个为w状态报警,报警间隔为1分钟,报警联系人分别是联系人组
define service{
name c-service
use generic-service
notification_interval 2
notification_period 24x7
contact_groups cadmins
notification_options c,r
register 0
}
define service{
name w-service
use generic-service
notification_interval 1
notification_period 24x7
contact_groups wadmins
notification_options w,r
register 0
}
我们拿disk和user服务做实验,将里面use模板先改为:use w-service,c-service再改为:use c-service,w-service
我们找一台主机,估计将其user状态设置为w状态,让disk状态设置为c状态
通过上图可以看出,我们只有一种状态是可以成功的,所以可以深刻的理解,nagios的模板引用思想,这个use引用模板的使用,只能引用一个而不能引用多个,模板之间是层层垂直引用的关系,模板之间的变量是层层替换的关系,总是后面设置的值去替换成前面模板的值。
好,既然我们走出了一个误区,应该将前面的我们说的哪些详解的内容整合起来,做一个比较好一点的报警监控功能出来:
1.首先w状态和c状态邮件,要邮件分级发送到不同的联系人,还是要用上面提到的在收件人模板定义不同的联系人接收不同类型的邮件。
2.我们可以针对具体的服务配置文件,来定义具体的发送人,再次报警间隔等一些信息去替代引用模板里面定义的值。
3.我们可以定义一个w和c都要接收邮件的联系人,用在escalations里的联系人中,将再次报警的时间尽量调大,避免服务报警频率太快而形成邮件骚扰。
联系人的设置范例二里面已经举例了。
具体服务项监控以硬盘监控和用户监控举例:
# cat disk.cfg
define service{
name CheckDisk
hostgroup_name allhost #尽量是以组的形式,而不是以主机的形式,我们过多的引用主机,当我们主机设计到下架或者关机维护的时候,涉及到变动的地方有点多,而且当我们服务.cfg很多的情况下,可能涉及到去好几个配置文件里面去将对应的主机去删除掉。否则影响nagios服务重启。
use generic-service
service_description Check_Disk
servicegroups BaseService
check_command check_nrpe!check_disk
notification_interval 3 #我们这里定义再次报警间隔为3分钟,去替换掉 generic-service定义的值
contact_groups cadmins,wadmins #我们定义此服务要发送的联系人组,如果不是特殊服务,这里可以不指定就引用generic-service中的便可,这里是为了举例,因为有些服务是需要某些专门的人来收,如dba服务之类的。
contacts dbaadmin #可以定义联系人而非联系人组
}
# cat users.cfg
define service{
hostgroup_name allhost
use generic-service
service_description CheckUsers
servicegroups BaseService
check_command check_nrpe!check_users
notification_interval 1
contact_groups cadmins,wadmins
contacts nagiosadmin
}
下面是我们的测试结果:
#从上图中可以看出,我们在具体的服务监控里面定义的规则已经替换掉了全局模板里面定义的规则。
博文来自:www.51niux.com
二、nagiso通过shell自定义监控插件
nagios可以识别4中状态返回信息:
0(OK)表示状态正常/绿色
1(WARNING)表示为警告/黄色
2(CRITICAL)表示出现非常严重的错误/红色
3(UNKNOWN)表示未知错误/深黄色
nagios监控脚本就是通过命令的退出状态码来判断,服务的状态。
范例一:写一个简单的自定义监控Postfix服务的插件:
在客户端的操作:
#cd /usr/local/nagios/libexec
# vi check_postfix #定义一个监控插件的名称
#!/bin/bash
if [ `ps -aux|grep postfix|grep -v grep|grep root|wc -l` -ge 1 ];then
echo "OK - The postfix service is OK!"
exit 0
else
echo "CRITICAL - The postfix service is Down!"
exit 2
fi
# chmod +x check_postfix
# vi /usr/local/nagios/etc/nrpe.cfg
command[check_postfix]=/usr/local/nagios/libexec/check_postfix #加上这样一句话,每次nagios都会运行一下这个插件
在服务端的操作:
# vi /usr/local/nagios/etc/services/MailService/postfix.cfg #这里写一个比较简单的范式
define service{
name CheckPostfix
host bj_cache_02
use generic-service
service_description Check_Postfix
check_command check_nrpe!check_postfix
notification_interval 3
contact_groups cadmins,wadmins
contacts dbaadmin
}
服务端要重新加载下配置文件,客户端要重启下nrpe服务。
下面是效果图:
范例二:写一个稍微复杂点的自定义插件。自己写一个监控根分区大小的插件,nagios自带的是百分比,咱们写一个绝对值的。
通过范例一,我们应该已经清楚了nagios自定义插件调用的过程,就是通过nrpe远程让客户端执行我们定义好的脚本,然后输出信息返回结果。
# vi check_diskgen
#!/bin/bash
if [ "$1" = "-w" ] && [ $2 -gt 0 ] && [ "$3" = "-c" ] && [ $4 -gt 0 ]; then
diskfree="`df -h |grep "^/"|grep -v boot|awk {'print $4'}|sed 's#G##'`"
if [ `echo "$4 - $diskfree"|bc|grep "-"|wc -l` -eq 0 ];then #这里要注意一点[]里面不能比较小数,所以这里采取了这样一种形式
echo "Disk_free: CRITICAL Diskfree:${diskfree}G - free|diskfree=$diskfree;$2;$4;;" #只写入"|"之前的内容也行,"|"之后的的内容为可选见容。
$(exit 2)
elif [ `echo "$2 - $diskfree"|bc|grep "-"|wc -l` -eq 0 ];then
echo "Disk_free: WARNING Diskfree:${diskfree}G - free|diskfree=$diskfree;$2;$4;;"
$(exit 1)
else
echo "Disk_free: OK Diskfree:"$diskfree"G - free|diskfree=$diskfree;$2;$4;;"
$(exit 0)
fi
else
echo "check_diskgen"
echo "Usage:"
echo "check_diskgen -w <free num> -c <free num>"
exit
fi
注:
nagios会将"|"之后的内容作为性能数据输出。如可输出给pnp4nagios,性能数据格:'label'=value[UOM];[warn];[crit];[min];[max]。
需要注意的是:
1、性能数据的多个选项值之间用分号;分割
2、如果label中包含空格、等号、或者单引号,则label需要用单引号来括起来
3、warn/crit/min/max可以为null值,如果有值单位必须统一
4、如果UOM单位是%,则min和max不需要再指定
5、UOM单位可以是如下: 默认空,表示数量(用于用户数、处理器数等)
s 表示秒(也可以用us,ms)
% 表示百分比
B 表示字节(也可以用KB,MB,TB,GB)
c 一个连续的计数(如:接口传输的字节数)
在客户端执行以下查看下测试结果:
# /usr/local/nagios/libexec/check_diskgen
check_diskgen
Usage:
check_diskgen -w <free num> -c <free num>
# /usr/local/nagios/libexec/check_diskgen -w 5 -c 4
Disk_free: CRITICAL Diskfree:3.9G - free|diskfree=3.9;5;4;;
# /usr/local/nagios/libexec/check_diskgen -w 4 -c 3
Disk_free: WARNING Diskfree:3.9G - free|diskfree=3.9;4;3;;
# /usr/local/nagios/libexec/check_diskgen -w 3 -c 2
Disk_free: OK Diskfree:3.9G - free|diskfree=3.9;3;2;;
服务端查看结果:
博文来自:www.51niux.com
三、nagiso结合ganglia进行监控(这里是再另一个环境下测试的)
https://blog.51niux.com/?id=83
https://blog.51niux.com/?id=84
https://blog.51niux.com/?id=85
上面三篇文章已经对ganglia的部署做了详细的说明,这里就不多说了。
其实这个结合就有点向上面说的自定义插件的意思,就是用ganglia提供的一个py脚本,去调对应的值。
第一步:
#cp ganglia-3.7.2/contrib/check_ganglia.py /usr/local/nagios/libexec/ #将ganglia里面的插件拷贝到nagios的插件目录里面去
第二步:
根据自己节点的是单播还是组播,对应的端口是什么。一般不管是组播还是单播,最后给自己127.0.0.1,也就是本地一个通道,也就是发送一份出去,然后再发送一份到本地,这样py插件文本基本就不用该了。
$ vi /usr/local/nagios/libexec/check_ganglia.py
##############################################################
ganglia_host = '127.0.0.1' #这里设置要去采集数据的IP,如果是组播的话,自己本机也会有一份数据。如果是单播的话,就要设置成中心节点的IP。所以单播的话可以给自己设置一个本地通道,这里就不用改了。
ganglia_port = 8668 #gmond的端口
host = None
metric = None
warning = None
critical = None
第三步:测试(一般我们都是用普通用户启动gmond和nrpe)
$ /usr/local/nagios/libexec/check_ganglia.py -h 192.168.1.101 -m procstat_gmond_mem -w 2306867 -c 2516582
CHECKGANGLIA CRITICAL: procstat_gmond_mem is 5857280.00
$ /usr/local/nagios/libexec/check_ganglia.py -h 192.168.1.101 -m cpu_idle -w 10 -c 5
CHECKGANGLIA CRITICAL: cpu_idle is 99.50
$ /usr/local/nagios/libexec/check_ganglia.py -h 192.168.1.101 -m procstat_gmond_mem -m diskstat_sda_read_bytes_per_sec -w 350000000 -c 500000000
CHECKGANGLIA UNKNOWN: Error while getting value "Host/value not found" #注意下这里,这就是没有取到值,取不到值可能是我们check_ganglia.py我们没有定义好host或者port,当然也可能是没有这个指标,我这里就是拿了一个没有安装的扩展的指标来举例,因为我现在gmond里面没有这个指标。还有一种可能性就比较小了,就是权限问题了。
$ /usr/local/nagios/libexec/check_ganglia.py -h 192.168.1.101 -m disk_free -w 27 -c 13
CHECKGANGLIA CRITICAL: disk_free is 194.22
$ /usr/local/nagios/libexec/check_ganglia.py -h 192.168.1.101 -m swap_free -w 600000 -c 400000
CHECKGANGLIA CRITICAL: swap_free is 4296700.00
第四步:nrpe的设置
通过上面的测试你会发现一个问题,明明值应该是OK的但是全部都记为了CRITICAL,这是因为check_ganglia.py的判断还需要做些其他的配置,在尾部进行修改:
#vi /usr/local/nagios/libexec/check_ganglia.py
修改前:
if value >= critical:
print "CHECKGANGLIA CRITICAL: %s is %.2f" % (metric, value)
sys.exit(2)
elif value >= warning:
print "CHECKGANGLIA WARNING: %s is %.2f" % (metric, value)
sys.exit(1)
else:
print "CHECKGANGLIA OK: %s is %.2f" % (metric, value)
sys.exit(0)
修改后:
if critical > warning:
if value >= critical:
print "CHECKGANGLIA CRITICAL: %s is %.2f" % (metric, value)
sys.exit(2)
elif value >= warning:
print "CHECKGANGLIA WARNING: %s is %.2f" % (metric, value)
sys.exit(1)
else:
print "CHECKGANGLIA OK: %s is %.2f" % (metric, value)
sys.exit(0)
else:
if critical >= value:
print "CHECKGANGLIA CRITICAL: %s is %.2f" % (metric, value)
sys.exit(2)
elif warning >= value:
print "CHECKGANGLIA WARNING: %s is %.2f" % (metric, value)
sys.exit(1)
else:
print "CHECKGANGLIA OK: %s is %.2f" % (metric, value)
sys.exit(0)
就是我们经过第三步的测试,能取到值,我们又想监控上,就加到nrpe.cfg的配置里面
$ cat /usr/local/nagios/etc/nrpe.cfg #加上下面的配置
command[check_ganglia_gmond_mem]=/usr/local/nagios/libexec/check_ganglia.py -h 192.168.1.101 -m procstat_gmond_mem -w 2306867 -c 2516582
command[check_ganglia_cpu_idle]=/usr/local/nagios/libexec/check_ganglia.py -h 192.168.1.101 -m cpu_idle -w 10 -c 5
command[check_ganglia_disk_free]=/usr/local/nagios/libexec/check_ganglia.py -h 192.168.1.101 -m disk_free -w 27 -c 13
command[check_ganglia_swap_free]=/usr/local/nagios/libexec/check_ganglia.py -h 192.168.1.101 -m swap_free -w 600000 -c 400000
第五步:nagios服务器端的配置(这就相当于还是通过nrpe去调用节点自己的第三方插件check_ganglia.py去取值)
# vi /usr/local/nagios/etc/objects/commands.cfg #在尾部加上
define command{
command_name check_nrpe
command_line $USER1$/check_nrpe -H $HOSTADDRESS$ -c $ARG1$
}
# vi /usr/local/nagios/etc/host.cfg #简单找个主机测试一下
define host {
host_name 192.168.1.101
use linux-server
address 192.168.1.101
}
# vi /usr/local/nagios/etc/service.cfg #简单设置一下
define service {
use generic-service
service_description Cpu Idle
check_command check_nrpe!check_ganglia_cpu_idle
host_name 192.168.1.101
}
define service {
use generic-service
service_description Gmond Mem
check_command check_nrpe!check_ganglia_gmond_mem
host_name 192.168.1.101
}
define service {
use generic-service
service_description Disk Free
check_command check_nrpe!check_ganglia_disk_free
host_name 192.168.1.101
}
define service {
use generic-service
service_description Swap Free
check_command check_nrpe!check_ganglia_swap_free
host_name 192.168.1.101
}
查看结果:
另外还有一种形式是直接去gmetad节点采集数据就可以了:
# vi /usr/local/nagios/libexec/check_ganglia.py
##############################################################
ganglia_host = '192.168.1.102' #gmetad节点的IP,如果gmetad就是本地的就直接设置成127.0.0.1就可以了
ganglia_port = 8651 #gmetad对外的端口
另外:check_ganglia.py下方的那些关于阀值的判断也是要更改的(if critical > warning:以及下面的那些)。
# vi /etc/ganglia/gmetad.conf #在gmetad服务器上面开启允许哪些IP来访问我们的8651端口
trusted_hosts 127.0.0.1 192.168.1.102 #我这里192.168.1.102既是gmetad节点又是nagios服务,可以直接调用本地的127.0.0.1就可以了
# vi /usr/local/nagios/etc/objects/commands.cfg #在尾部加上
define command {
command_name check_ganglia
command_line $USER1$/check_ganglia.py -h $HOSTNAME$ -m $ARG1$ -w $ARG2$ -c $ARG3$
}
# vi /usr/local/nagios/etc/service.cfg #简单设置一下
define service {
use generic-service
service_description Cpu Idle
check_command check_ganglia!cpu_idle!10!5 #这种定义方式,在我们定义主动监控的时候,就是这种!后面跟要执行的参数!后面是-w后面的值!后面是-c后面的参数,因为前面我们commands.cfg定义了-m后面跟一个指标数值,所以这里第一个!后面的就是我们要对哪个指标取值。跟上面那种nrpe的方式是有一些不同的。
host_name 192.168.1.101,192.168.1.103 #我又多定义了一个主机192.168.1.103
}
define service {
use generic-service
service_description Gmond Mem
check_command check_ganglia!procstat_gmond_mem!2306867!2516582
host_name 192.168.1.101,192.168.1.103
}
define service {
use generic-service
service_description Disk Free
check_command check_ganglia!disk_free!27!13
host_name 192.168.1.101,192.168.1.103
}
define service {
use generic-service
service_description Swap Free
check_command check_ganglia!swap_free!600000!400000
host_name 192.168.1.101,192.168.1.103
}
#重启相关服务gmetad服务,nagios服务,查看效果:
注:
这就是两种nagios和ganglia结合的形式,一种是通过nrpe调用本地的py脚本去gmond里面去取相关的值,这种方式呢可能比较麻烦一点需要每个被监控节点都要部署nrpe服务,但是呢就算gmetad服务挂掉了,一般我们gmond都会丁一个本地通道,所以值一样是可取出来的,跟ganglia的耦合性没有太高。另外呢就是因为我们各个节点可以在自己的nrpe里面定义不同的阀值,如load_one来说不同的CPU阀值肯定不一样,这样呢再灵活性方面也是比较高的。
另外一种呢,就是nagios直接调用汇聚节点gmetad里面以-h 主机的方式,这种就跟gmetad的耦合性比较大了,如果gmetad出问题的话,将是大范围节点取不到监控值,从上面的例子也可以看出,在配置文件的阀值上面灵活性不够大,如果节点的配置不同,那么配置文件要配置好多冗余性比较高。
所以个人觉得还是第一种结合方式比较好,生产环境中用的也是第一种。
注:上传一个比较规范的插件,供参考一下,里面有很多代码重复的地方没有去掉,没有太详细的去优化。当然用的都是最简单的逻辑,为了就是逻辑简单能够迅速出值。
load_one_check.txt :因为load_one是根据实际CPU的核心数,这样我们在部署的时候可能要-w和-c后面的值要设置不同的值,为了解决部署麻烦的问题,写了一个小插件,直接-w -c后面输入的数值为cpu的倍数,如-w 1 -c 2,就是-w CPU数量的1倍, -c CPU数量的两倍,脚本内部再去进行换算,这样我们再部署的时候就会比较简单。当然-v -w 4 -c 6,就是以value绝对值的方式来设置,也就是4是表示数量4,6是表示数字6.这样可以适应不同的场景。同时还调用gmond的插件取值,如果取不到值再用系统查值的方式来返回结果,这样防止误报。
注:一般使用邮箱服务器发送邮件,所以一般要#yum install mailx -y
#cat /etc/mail.rc
set from=nagios@51niux.com set smtp=smtp.51niux.com set smtp-auth-user=nagios@51niux.com set smtp-auth-password=www.51niux.com set smtp-auth=login
#第一行是发件人,第二行是smtp服务器地址,第三行是邮箱的登录用户,第四行是邮箱的登录密码,第五行是login操作。这样再本地执行mail,就不是找本地的25端口发送邮件,而是通过远端的邮件服务器发送邮件了。
注:清空邮件队列里面的邮件(有的时候要批量添加主机监控或者维护主机监控不希望报警出来,将mail.rc里面的配置文件去掉,但是出问题了还是会发邮件的只不过存在本机的邮件队列里面了,所以要清空邮件队列)
第一种呢:for num in `mailq -v|awk {'print $1'}|grep -v @|grep -v "^$"`;do postsuper -d $num;done #这种比较没效率。mailq -v主要是查看当前队列里面有没有邮件,postsuper -d主要是用来删除指定的某封邮件
第二种呢:postsuper -d ALL #当前邮件队列里面的邮件全干掉。