1. 版本历史

Revision    Author(s)    Date    Summary of activity
1.0            罗辉        2008-11-19    创建本文档

2. 参考文档

[1] http://www.nagiosexchange.org
[2] http://www.nagios.org/

3. 前言

做为系统管理员,管理着几十台或几百台服务器在运行。一个非常迫切的需求就是希望了解服务器及服务器上运行的服务的运行状况,在服务器或服务出现当机或停止的时候能够第一时间知道,及时处理。以便最小的减少由此带来的影响和损失。Nagios就是用来解决这个问题的,在目前的一些监控软件中,Nagios以其良好的稳定性,强大的功能等,已成为业界监控软件的首选。

Nagios官方网站的描述:
Nagios is an open source host, service and network monitoring program. Who uses it? Lots of people, including many big companies and organizations:Nagios是一个用来监控主机、服务和网络的开放源码软件,很多大的公司或组织都在使用它。

4. Nagios监控原理

上图为Nagios监控原理图。Nagios监控可以使用主动模式(Action)和被动模式 (Passive)。

主动模式主要是自身插件或结合Nrpe实现,由Nagios在定义的时间去主动监测被监控端的服务器或服务是否正常。被动模式结合Naca实现,由Nsca定时监控服务器或服务,再由Nasa把结果传至Nagios。

被动模式适合大规模服务器(一般在最少100台以上)需要监控的情况,可有效减少监控服务器的压力。在服务器数量比较少的情况下用主动模式比较方便,因为主要的配置在监控主机的设置就好了,无需在被监控端做过多设置。

我们的监控是使用Nagios结合Nrpe的主动模式。

5. Nagios的安装

5.1. YUM方式安装

我们的监控服务器是Centos linux 4.8,可用yum方式安装:

# wget http://dag.wieers.com/rpm/packages/rpmforge-release/rpmforge-release-0.3.6-1.el4.rf.i386.rpm
# rpm –ivh rpmforge-release-0.3.6-1.el4.rf.i386.rpm
# yum install nagios*
# chkconfig –level 2345 nagios on
# service nagios start

注:本文后面的配置都是按yum安装后的环境来配置的。

5.2. 源代码方式安装

1)安装Nagios

# wget http://jaist.dl.sourceforge.net/sourceforge/nagios/nagios-3.0.6.tar.gz
# tar zxvf nagios-3.0.6.tar.gz
# cd nagios-3.06
# ./configure -prefix=/usr/local/nagios
# make install                  //安装主要的程序、CGI及HTML文件
# make install-commandmode      //给外部命令访问nagios配置文件的权限
# make install-config           //把配置文件的例子复制到nagios的安装目录
# make install-init             //把nagios做成一个运行脚本,使nagios随系统开机启动
或者上面四步可用一行令代替:
# make all

2) 安装nagios的插件

# wget http://nchc.dl.sourceforge.net/sourceforge/nagiosplug/nagios-plugins-1.4.13.tar.gz
# cd nagios-plugins-1.4.13
# tar zxvf nagios-3.0.6.tar.gz
# ./configure -prefix=/usr/local/nagios
# make
# make install

6. Nagios配置文件

其实Nagios只有一个配置文件,就是/etc/nagios/nagios.cfg,其它的配置文件都是以include的方式包括进nagios.cfg的。如:
# You can specify individual object config files as shown below:
cfg_file=/etc/nagios/objects/commands.cfg
cfg_file=/etc/nagios/objects/contacts.cfg
cfg_file=/etc/nagios/objects/timeperiods.cfg
cfg_file=/etc/nagios/objects/templates.cfg

# Definitions for monitoring the local (Linux) host
cfg_file=/etc/nagios/objects/hosts.cfg
cfg_file=/etc/nagios/objects/services.cfg

commands.cfg是监控命令的配置文件,contacts.cfg是监控报警联系人的配置文件,timeperiods.cfg是时间定义配置文件,templates.cfg是模板配置文件,这里面定义了一些模板以方便用户使用。Hosts.cfg是被监控主机的配置文件,services.cfg是被监控服务的配置文件。
唯一的例外是cgi.cfg,这个文件是与WEB相关的。

6.1. Nagios的WEB配置

# htpasswd -c /etc/nagios/htpasswd.users nagiosadmin 123456
建一个WEB访问的用户之后,在浏览器输入http://ip/nagios/,输入相应的用户和密码就可以就看到Nagios的web界面了。

WEB用到的配置文件是/etc/nagios/cgi.cfg,更改配置可修改这个配置文件。
# vi /etc/nagios/cgi.cfg
use_authentication=1                         #使用用户认证
authorized_for_system_information=nagiosadmin
authorized_for_configuration_information=nagiosadmin
authorized_for_system_commands=nagiosadmin #多个用户之间用逗号隔开
authorized_for_all_services=nagiosadmin
authorized_for_all_hosts=nagiosadmin
authorized_for_all_service_commands=nagiosadmin
authorized_for_all_host_commands=nagiosadmin

6.2.  hosts.cfg

define host{            #这段是用来定义一个被监控的主机。
host_name             #这一项是用来定义标识主机的名字。我们用这个名字在host group和service里标识这个主机。一个主机能定义多个服务。使用适当时,宏$HOSTNAME$里存放了这一项的值。
alias                 #这一项用来定义主机的一个完整名字或描述。主要是和使你能理容易的标识一个主机。使用适当时,宏$HOSTALIAS$里存放了这一项的值。
address               #这一项是用来定义主机的地址。一般而言是主机的IP。当然,你也能够使用一个FQDN来标识你的主机,在没有可访问DNS服务器服务的情况下这种方法会引起问题。使用适当时,宏$ HOSTADDRESS $里存放了这一项的值。
max_check_attempts    #这一项用来定义在检测返回结果不是OK时,nagios重试检测命令的次数。设置这个值为1会导致nagios一次也不重试就报警。
check_period          #这一项用一个time period项的名字来定义在哪段时间内激活对这台主机的主动检测。time period是定义在别的文件里的配置项,我们可以在这里用名字来引用她。
contact_groups        #这是一个联系组列表。我们用联系组的名字来引用她们。多个联系组间用“,”来分隔。
notification_interval #这一项用来定义当一个服务仍然down或unreachable时,我们间隔多久重发一次通知给联系组。
notification_period   #这一项用一个time period定义来标识什么时间段内给联系组送通知。这里我们用time period定义的名字来引用她。
notification_options  #这一项用来决定发送通知的时机。选项有:d = 当有down状态时发送通知,u = 当有unreachable状态时发送通知, r = 当有服务recoveries时发送通知,f = 当主机启动或停机时发送通知。如果你给一个n选项,那么永远不会发送通知。
}

define hostgroup{     #这段是用来定义一个被监控的主机组。
hostgroup_name  #主机组名称,通常定义得较短
alias           #主机组别名,通常定义得较长
members         #主机组成员
}

6.3. services.cfg

define service{                      #这段是用来定义一个被监控的服务。
host_name             #主机名称
service_description   #服务描述
check_command         #执行命令
max_check_attempts    #最大失败尝试次数,值为1时只报警不重新检测
normal_check_interval #常规检测间隔时间,默认为60分钟(常规检测是指无论服务状态是否正常,检测次数达到“最大次数”时)
retry_check_interval  #失败尝试间隔时间,默认为60分钟(失败尝试是指服务状态不正常,检查次数达到“最大次数”时)
check_period          #检测时间段
notification_interval #当服务状态不正常时通知联系人的间隔时间,值为0时不通知联系人
notification_period   #通知联系人时间段
notification_options  #通知联系人选项,w警告,u未知,c危急,f启动和停止,n不发送通知
contact_groups        #联系人组
}

define servicegroup{                 #这段是用来定义一个被监控的服务组。
servicegroup_name     #服务组名称,通常定义得较短       
alias                 #服务组别名,通常定义得较长
members               #服务组成员
}

6.4. contacts.cfg

define contact{              #这段是用来定义一个联系人。
contact_name                 #这个指令用来定义一个联系人的简称。他会在定义contactgroup时被引用到。在相应的环境中,宏定义$CONTACTNAME$会包含这个值。
alias                        #这个指令是为了定义一个联系人的具体的描述。在相应的环境中,宏定义$CONTACTALIAS$会包含这个值。
host_notification_period     #这个指令是为了定义,能够通知Contact中定义的那个简称联系人,关于主机有问题或者恢复正常状态的时间段。你可以把他想象成能够通知Contact关于主机的在线时间。
service_notification_period  #这个指令是为了定义,能够通知Contact中定义的那个简称联系人,关于服务的问题或恢复正常的时间段。
host_notification_options    #这个指令为了定义主机在什么状态下会给联系人发通知。各个参数的描述如下:d=当主机的状态处于down时,发送通知;f=当主机状态处于stop时发送通知。r=当主机恢复up状态时发送通知。n=什么状态下都不发送通知(w-warning , u-unknown,c-critical,r-recovery;d-down,u-unreachable)。
service_notification_options #这个指令为了定义服务在什么状态下会给联系人发通知。各个参数的描述如下:w=当服务处于警告状态时发送通知 u=当服务的状态处于unknown时,发送通知;f=当服务状态处于启动和停止时发送通知。c=当服务处于Critical状态时发送通知。n=什么状态下都不发送通知。
host_notification_commands   #这个指令是为了定义一个通知联系人关于主机问题或恢复正常的联系手段的一个列表。多个手段之间用逗号隔开。
service_notification_commands#这个指令是为了定义一个通知联系人关于服务问题或恢复正常的联系手段的一个列表。多个手段之间用逗号隔开。
email                        #这个指令是为了定义联系人的email地址。这个将取决于你是如何定义你的notification commands.它可以用来给联系人发送紧急邮件。在相应的环境中。宏定义$CONTACTEMAIL$将会包含它的值。
}

define contactgroup{         #这段是用来定义一个联系人组。
contactgroup_name   #联系组名称,通常定义得较短
alias               #联系组别名,通常定义得较长
members             #联系组成员
}

6.5. timeperiods.cfg

define timeperiod{
timeperiod_name  #时间段名称,通常定义得较短
alias            #时间段别名,通常定义得较长
sunday           #星期日时间段
monday           #星期一时间段
tuesday          #星期二时间段
wednesday        #星期三时间段
thursday         #星期四时间段
friday           #星期五时间段
saturday         #星期六时间段
}

6.6. commands.cfg

define command{
command_name        #定义命令的简称
command_line        #定义当服务进行时Nagios要执行的动作。在命令执行以前,所有合法的宏都要被他们的值代替。
}

7. 用Nrpe监控Linux主机

7.1. 安装Nrpe

# wget http://dag.wieers.com/rpm/packages/rpmforge-release/rpmforge-release-0.3.6-1.el4.rf.i386.rpm
# rpm –ivh rpmforge-release-0.3.6-1.el4.rf.i386.rpm
# yum -y install nagios-nrpe
# chkconfig –level 2345 nrpe on
# service nrpe start

7.2. 配置Nrpe

修改Nrpe配置文件:

#  vi /etc/nagios/nrpe.cfg

command开头只保留两行:
command[check_load]=/usr/lib/nagios/plugins/check_load -w 15,10,5 -c 30,25,20
command[check_disk]=/usr/lib/nagios/plugins/check_disk -w 20 -c 10 -p /

第一行是监控系统负载,第二行是监控磁盘空间的。
command[check_load]内的check_load是定义的Nrpe命令,在监控端的Nrpe插件可用这个命令来取得执行结果。

7.3. 配置nagios

1) 增加nagios命令

# vi commands.cfg
最后增加:
define command{
command_name check_nrpe
command_line /usr/local/nagios/libexec/check_nrpe -H $HOSTADDRESS$ -c $ARG1$
}

2) 增加被监控服务器

# vi /etc/nagios/objects/hosts.cfg
define host{                   
use                     linux-server
host_name               mysql.server
alias                   10.11.12.80
address                 10.11.12.80
}

3) 增加被监控服务

# vi /etc/nagios/objects/services.cfg
define service{
use                     local-service
host_name               mysql.server
service_description     nrpe_disk
check_command           check_nrpe!check_disk
notifications_enabled   1
}

define service{
use                     local-service
host_name               mysql.server
service_description     nrpe_load
check_command           check_nrpe!check_load
notifications_enabled   1
}
上面配置内的check_load和check_disk是被监控端Npre的配置文件(command[check_load])内定义好的命令。最后使配置生效:
# nagios –v /etc/nagios/nagios.cfg  #配置文件的语法检查
# service nagios reload

8. 监控Web及Tomcat服务

监控Web用Tomcat服务可用nagios自带的插件check_http。
# vi commands.cfg
增加:
# ‘check_tomcat’ command definition
define command{
command_name    check_tomcat
command_line    $USER1$/check_http -I $HOSTADDRESS$ -p 8080 $ARG1$
}
# ‘check_http’ command definition
define command{
command_name    check_http
command_line    $USER1$/check_http -I $HOSTADDRESS$ -H $HOSTADDRESS$ $ARG1$
}

# vi services.cfg
增加:
define service{
use                     local-service
host_name               web1.ihompy.com
hostgroup_name          web-servers
service_description     check-http
check_command           check_http
max_check_attempts      3
normal_check_interval   3
retry_check_interval    1
check_period            24×7
notification_interval   60
notification_period     24×7
notification_options    w,u,c,r
}
define service{
use                     local-service
host_name               l7ejb,l7admin,l7web,l7ds
#        hostgroup_name          l7-servers
service_description     check-tomcat
check_command           check_tomcat
max_check_attempts      3
normal_check_interval   3
retry_check_interval    1
check_period            24×7
notification_interval   60
notification_period     24×7
notification_options    w,u,c,r
}
被监控端无需配置,让nagios使修改后的配置生效便可。


9. 监控squid

9.1. 下载squid检测脚本

# wget http://workaround.org/squid/nagios-plugin/check_squid
# chmod  755 check_squid
# cp check_squid /usr/lib/nagios/plugins/
这个脚本我用的时候有点问题,出现:
Parsing of undecoded UTF-8 will give garbage when decoding entities at /usr/lib/perl5/vendor_perl/5.8.5/LWP/Protocol.pm line 114.
原因是:
HTML::HeadParser模块在使用parse()方法时,对没有编码的UTF-8会弄混,要保证在传值之前进行适当的编码。
参考:http://www.xinjiezuo.com/blog/?p=43
解决方式是在my $ua = new LWP::UserAgent;下面加入一行:
$ua->parse_head(0);

跳过去就好了。

9.2. 修改配置文件

# vi commands.cfg
增加:
# ‘squid’ command definition
define command {
command_name check_squid
command_line $USER1$/check_squid ‘$ARG1$’ ‘$ARG2$’ ‘$ARG3$’ $HOSTADDRESS$ ‘$ARG4$’ ‘$ARG5$’ ‘$ARG6$’ ‘$ARG7$’
}

# vi services.cfg
增加:
define service {
use                     local-service
host_name               squid1.ihompy.com
service_description     check-squid
check_command           check_squid!http://www.ihompy.com!-!-!80!-!-!2
max_check_attempts      3
normal_check_interval   3
retry_check_interval    1
check_period            24×7
notification_interval   60
notification_period     24×7
notification_options    w,u,c,r
}
被监控端无需配置,让nagios使修改后的配置生效便可。

10. 监控mysql及mssql服务

监控mysql服务可用nagios自带的插件check_mysql。Nagios也带有一个check_mssql用来监控sql server,不过要先安装freetds。
# yum install freetds
# vi commands.cfg
增加:
# ‘mysql’  command definition
define command{
command_name check_mysql
command_line $USER1$/check_mysql -H $HOSTADDRESS$ -u $ARG1$ -p $ARG2$
}
# ‘check_mssql’ command definition
define command{
command_name    check_mssql
command_line    $USER2$/check_mssql.sh $HOSTADDRESS$ $ARG1$ $ARG2$ $ARG3$
}

# vi services.cfg
增加:

define service{
use                     local-service
host_name               mysql.ihompy.com
hostgroup_name          mysql-servers
service_description     check-mysql
check_command           check_mysql!root!1qaz2wsx
max_check_attempts      3
normal_check_interval   3
retry_check_interval    1
check_period            24×7
notification_interval   60
notification_period     24×7
notification_options    w,u,c,r
}
define service{
use                     local-service
host_name               sqlserver
#        hostgroup_name          backup-servers
service_description     check_sqlserver
check_command           check_mssql!sa!”!2000
notifications_enabled   1
}
被监控端无需配置,让nagios使修改后的配置生效便可。

11. 配置报警方式及联系人

Nagios可以有很多报警方式,比如:E-mail,短信,MSN等。
目前短信方式主要是用中国移动的飞信客户端及购买短信猫两种方式。前者目前是免费的,后者需一点费用买短信猫及手机卡,不过代价也不高,一共不到200RMB。
MSN因为其自身的原因,不太稳定。
我们使用的是一个折中的方式,在Nagios上配置的是E-mail方式,但使用的是中国移动的139邮箱,139邮箱在收到邮件后可免费发短信给用户。这样就邮箱和短信就都有了,目前观察下来稳定性还不错。

11.1. 配置联系人

# vi contacts.cfg
define contact{
contact_name                    luohui         
use                             generic-contact
alias                           Nagios Admin   
email                           farmer.luo@139.com 
pager                           13761802324324
address1                        huilinux@hotmail.com
}

define contact{
contact_name                    xuyong       
use                             generic-contact
alias                           Nagios Admin   
email                           xuyong76@139.com
pager                           133434323443
address1                        xuyong@newsky.sh
}
define contactgroup{
contactgroup_name       admins
alias                   Nagios Administrators
members                 luohui,xuyong
}
先定义两个联系人luohui和xuyong,再把它们加入到联系人组admins。

11.2 配置报警命令

默认已经配置好了,在command.cfg中的以下这几行:

# ‘notify-host-by-email’ command definition
define command{
command_name    notify-host-by-email
command_line    /usr/bin/printf "%b" "***** Nagios *****nnNotification Type: $NOTIFICATIONTYPE$nHost: $HOSTNAME$n
State: $HOSTSTATE$nAddress: $HOSTADDRESS$nInfo: $HOSTOUTPUT$nnDate/Time: $LONGDATETIME$n" | /bin/mail -s "** $NOTIFICATI
ONTYPE$ Host Alert: $HOSTNAME$ is $HOSTSTATE$ **" $CONTACTEMAIL$
}

# ‘notify-service-by-email’ command definition
define command{
command_name    notify-service-by-email
command_line    /usr/bin/printf "%b" "***** Nagios *****nnNotification Type: $NOTIFICATIONTYPE$nnService: $SERVIC
EDESC$nHost: $HOSTALIAS$nAddress: $HOSTADDRESS$nState: $SERVICESTATE$nnDate/Time: $LONGDATETIME$nnAdditional Info:nn
$SERVICEOUTPUT$" | /bin/mail -s "** $NOTIFICATIONTYPE$ Service Alert: $HOSTALIAS$/$SERVICEDESC$ is $SERVICESTATE$ **" $CONTAC
TEMAIL$
}

11.3. 在主机和服务中启用E-mail报警

因为我们配置的主机及服务都是使用了模板方式的,所以只要改了模板文件的配置,所有的主机和服务就都改了。
# vi templates.cfg
define contact{
name                            generic-contact          
service_notification_period     24×7               
host_notification_period        24×7                   
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                      
}

在主机及服务模板内,把contact_groups都改成联系人组admins:
contact_groups                  admins 

12. 结语

上面只列举了几个常用的服务做为例子说明。Nagios可监控的服务很多,如dns,pop,smtp等等。也可以自己写脚本检测一些特殊的服务。
目前用Nagios监控系统监控了近40台服务器,100多项服务。运行有半个月左右,已经成功报过几次警,用起来很顺手,非常不错。