CentOS编译安装zabbix 3.2.7

修改/usr/local/apache/
修改php.ini 文件

[root@localhost zabbix-3.2.7]# groupadd zabbix

[root@localhost zabbix-3.2.7]# useradd -g zabbix zabbix
yum安装 net-snmp,net-snmp-devel,mysql(mariadb),mysql-devel(mariadb-devel),curl,curl-devel

进入zabbix安装目录

./configure --prefix=/usr/local/zabbix --enable-server --enable-agent --with-mysql --enable-ipv6 --with-net-snmp --with-libcurl --with-libxml2
make 
make install
systemctl start mariadb
mysql
create database zabbix character set utf8 collate utf8_bin;
grant all privileges on zabbix.* to zabbix@localhost identified by '123456';
---------------------
如果有如下报错
# MariaDB [(none)]> grant all on zabbix.* to zabbix@localhost identified by ‘123456‘;
#ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your #MariaDB server version for the right syntax to use near '‘123456‘' at line 1
修改‘’为英文状态
----------------------
flush privileges;
exit;
mkdir -p /usr/local/apache/htdocs/zabbix

[root@localhost zabbix-3.2.7]# cp -ra frontends/php/* /usr/local/apache/htdocs/zabbix

进入数据库文件目录,将相关数据导入数据库

[root@localhost mysql]# pwd
/usr/src/zabbix-3.2.7/database/mysql
root@localhost mysql]# mysql -uzabbix -p123456 zabbix < schema.sql 
[root@localhost mysql]# mysql -uzabbix -p123456 zabbix < images.sql
[root@localhost mysql]# mysql -uzabbix -p123456 zabbix < data.sql
chown zabbix:zabbix /usr/local/apache/htdocs/zabbix


cp /usr/local/zabbix/sbin/zabbix_server /etc/init.d/

编辑/usr/local/zabbix/etc/zabbix_server.conf

修改DBHost=localhost DBName=zabbix DBUser=zabbix DBPssword=123456

报错:PHP bcmath extension missing (PHP configuration parameter --enable-bcmath).
进入php安装目录 /usr/src/php-7.1.7/ext/bcmath
执行/usr/src/php-7.1.7/ext/bcmath
[root@localhost bcmath]# ./configure --with-php-config=/usr/local/php7/bin/php-config
[root@localhost bcmath]# make  &  make install
Installing shared extensions:     /usr/local/php7/lib/php/extensions/no-debug-non-zts-20160303/
[root@localhost bcmath]# cd /usr/local/php7/lib/php/extensions/no-debug-non-zts-20160303/

[root@localhost php7]# cp /usr/local/php7/lib/php/extensions/no-debug-non-zts-20160303/bcmath.so /usr/local/php7/include/php/ext(这是默认路径,php.ini中可定义)

修改php.ini ,最后一行加

extension=bcmath.so

重启httpd zabbix服务

docker部署zabbix监控系统(nginx mysql)

本次使用docker搭建zabbix的组合是mysql+docker+zabix-server

1. 先安装数据库mysql

docker run --name zabbix-mysql-server --hostname zabbix-mysql-server 
-e MYSQL_ROOT_PASSWORD="123456" 
-e MYSQL_USER="zabbix" 
-e MYSQL_PASSWORD="123456" 
-e MYSQL_DATABASE="zabbix" 
-p 3306:3306  
-d 
mysql

2. 创建zabbix-server

docker run  --name zabbix-server-mysql --hostname zabbix-server-mysql 
--link zabbix-mysql-server:mysql 
-e DB_SERVER_HOST="mysql" 
-e MYSQL_USER="zabbix" 
-e MYSQL_DATABASE="zabbix" 
-e MYSQL_PASSWORD="123456" 
-v /etc/localtime:/etc/localtime:ro 
-v /data/docker/zabbix/alertscripts:/usr/lib/zabbix/alertscripts 
-v /data/docker/zabbix/externalscripts:/usr/lib/zabbix/externalscripts 
-p 10051:10051 
-d 
zabbix/zabbix-server-mysql

3. 最后web-nginx

最后安装zabbix-web-nginx
docker run --name zabbix-web-nginx-mysql --hostname zabbix-web-nginx-mysql 
--link zabbix-mysql-server:mysql 
--link zabbix-server-mysql:zabbix-server 
-e DB_SERVER_HOST="mysql" 
-e MYSQL_USER="zabbix" 
-e MYSQL_PASSWORD="123456" 
-e MYSQL_DATABASE="zabbix" 
-e ZBX_SERVER_HOST="zabbix-server" 
-e PHP_TZ="Asia/Shanghai" 
-p 8000:80 
-p 8443:443 
-d 
zabbix/zabbix-web-nginx-mysql

登录访问测试

浏览器访问ip:8000查看
默认登录
username:Admin
password:zabbix

这里说明下,mysql没做数据卷的映射,nginx也没做数据卷的映射,在实际生产环境下,最好做数据映射。防止数据丢失。

docker-zabbbix-agent的安装以及链接zabbix-server

docker run --name zabbix-agent --link zabbix-server-mysql:zabbix-server -d zabbix/zabbix-agent:latest

最后需要在web端将,zabbix-agent添加到zabbix-server的host列表里面。

监控

zabbix主动发现并监控磁盘IO性能

一. 基本概念

1. 读/写IO

最为常见说法,读IO,就是发指令,从磁盘读取某段扇区的内容。指令一般是通知磁盘开始扇区位置,然后给出需要从这个初始扇区往后读取的连续扇区个数,同时给出动作是读,还是写。磁盘收到这条指令,就会按照指令的要求,读或者写数据。控制器发出的这种指令+数据,就是一次IO,读或者写。

2. 大/小块IO

指控制器的指令中给出的连续读取扇区数目的多少,如果数目很大,比如128,64等等,就应该算是大块IO,如果很小,比如1, 4,8等等,就应该算是小块IO,大块和小块之间,没有明确的界限。

3. 连续/随机IO

连续和随机,是指本次IO给出的初始扇区地址,和上一次IO的结束扇区地址,是不是完全连续的,或者相隔不多的,如果是,则本次IO应该算是一个连续IO,如果相差太大,则算一次随机IO。连续IO,因为本次初始扇区和上次结束扇区相隔很近,则磁头几乎不用换道或换道时间极短;如果相差太大,则磁头需要很长的换道时间,如果随机IO很多,导致磁头不停换道,效率大大降底。

4. 顺序/并发IO

这个的意思是,磁盘控制器每一次对磁盘组发出的指令套(指完成一个事物所需要的指令或者数据),是一条还是多条。如果是一条,则控制器缓存中的IO队列,只能一个一个的来,此时是顺序IO;如果控制器可以同时对磁盘组中的多块磁盘,同时发出指令套,则每次就可以执行多个IO,此时就是并发IO模式。并发IO模式提高了效率和速度。

5. IO并发几率

单盘,IO并发几率为0,因为一块磁盘同时只可以进行一次IO。对于raid0,2块盘情况下,条带深度比较大的时候(条带太小不能并发IO,下面会讲到),并发2个IO的几率为1/2。其他情况请自行运算。

6. IOPS

即每秒进行读写(I/O)操作的次数,一个IO所用的时间=寻道时间+数据传输时间。 IOPS=IO并发系数/(寻道时间+数据传输时间),由于寻道时间相对传输时间,大几个数量级,所以影响IOPS的关键因素,就是降底寻道时间,而在连续IO的情况下,寻道时间很短,仅在换磁道时候需要寻道。在这个前提下,传输时间越少,IOPS就越高。

7. 每秒IO吞吐量

显然,每秒IO吞吐量=IOPS乘以平均IO SIZE。 Io size越大,IOPS越高,每秒IO吞吐量就越高。

8. 设磁头每秒读写数据速度为V,V为定值

则IOPS=IO并发系数/(寻道时间+IO SIZE/V),代入,得每秒IO吞吐量=IO并发系数乘IO SIZE乘V/(V乘寻道时间+IO SIZE)。我们可以看出影响每秒IO吞吐量的最大因素,就是IO SIZE和寻道时间,IO SIZE越大,寻道时间越小,吞吐量越高。相比能显著影响IOPS的因素,只有一个,就是寻道时间。

二. 监控磁盘IO的基本原理:通过分析/proc/diskstats文件,来对IO的性能进行监控。

1. 第一至第三个域

分别是主设备号,次设备号,设备名称

2. 第4个域

读完成次数 —– 读磁盘的次数,成功完成读的总次数。(number of issued reads. This is the total number of reads completed successfully.)

3. 第5个域

合并读完成次数, 第9个域:合并写完成次数。为了效率可能会合并相邻的读和写。从而两次4K的读在它最终被处理到磁盘上之前可能会变成一次8K的读,才被计数(和排队),因此只有一次I/O操作。这个域使你知道这样的操作有多频繁。(number of reads merged)

4. 第6个域

读扇区的次数,成功读过的扇区总次数。(number of sectors read. This is the total number of sectors read successfully.)

5. 第7个域

读花费的毫秒数,这是所有读操作所花费的毫秒数(用__make_request()到end_that_request_last()测量)。(number of milliseconds spent reading. This is the total number of milliseconds spent by all reads (as measured from __make_request() to end_that_request_last()).)

6. 第8个域

写完成次数 —-写完成的次数,成功写完成的总次数。(number of writes completed. This is the total number of writes completed successfully.)

7. 第9个域

合并写完成次数 —–合并写次数。(number of writes merged Reads and writes which are adjacent to each other may be merged for efficiency. Thus two 4K reads may become one 8K read before it is ultimately handed to the disk, and so it will be counted (and queued) as only one I/O. This field lets you know how often this was done.)

8. 第10个域

写扇区次数 —- 写扇区的次数,成功写扇区总次数。(number of sectors written. This is the total number of sectors written successfully.)

9. 第11个域

写操作花费的毫秒数 — 写花费的毫秒数,这是所有写操作所花费的毫秒数(用__make_request()到end_that_request_last()测量)。(number of milliseconds spent writing This is the total number of milliseconds spent by all writes (as measured from __make_request() to end_that_request_last()).)

10. 第12个域

正在处理的输入/输出请求数 — -I/O的当前进度,只有这个域应该是0。当请求被交给适当的request_queue_t时增加和请求完成时减小。(number of I/Os currently in progress. The only field that should go to zero. Incremented as requests are given to appropriate request_queue_t and decremented as they finish.)

11. 第13个域

输入/输出操作花费的毫秒数 —-花在I/O操作上的毫秒数,这个域会增长只要field 9不为0。(number of milliseconds spent doing I/Os. This field is increased so long as field 9 is nonzero.)

12. 第14个域

输入/输出操作花费的加权毫秒数 —– 加权, 花在I/O操作上的毫秒数,在每次I/O开始,I/O结束,I/O合并时这个域都会增加。这可以给I/O完成时间和存储那些可以累积的提供一个便利的测量标准。(number of milliseconds spent doing I/Os. This field is incremented at each I/O start, I/O completion, I/O merge, or read of these stats by the number of I/Os in progress (field 9) times the number of milliseconds spent doing I/O since the last update of this field. This can provide an easy measure of both I/O completion time and the backlog that may be accumulating.)

三. zabbix监控主动发现磁盘并监控其吞吐量与iops

1. 监控内容的json化脚本partition_low_discovery.sh

#!/bin/bash
# Author: guoxiangfu
# Email: [email protected]
#script name:partition_low_discovery.sh
#Fucation:zabbix low-level discovery
partition() {
            port=($(grep -E "(vd[a-z]$|sd[a-z]$)" /proc/partitions|awk '{print $4}'))
            printf '{n'
            printf 't"data":[n'
               for key in ${!port[@]}
                   do
                       if [[ "${#port[@]}" -gt 1 && "${key}" -ne "$((${#port[@]}-1))" ]];then
                          printf 't {n'
                          printf "ttt"{#PARTITIONNAME}":"${port[${key}]}"},n"
                     else [[ "${key}" -eq "((${#port[@]}-1))" ]]
                          printf 't {n'
                          printf "ttt"{#PARTITIONNAME}":"${port[${key}]}"}n"
                       fi
               done
                          printf 't ]n'
                          printf '}n'
}
$1

把此文件存放到scripts里,然后给与755权限,并修改用户与组为zabbix

2. 可运行脚本检测是否能成功运行,运行的结果类似如下:

监控

3. 同时允许zabbix用户无密码运行netstat

echo "zabbix ALL=(root) NOPASSWD:/bin/netstat">>/etc/sudoers
#Disable requiretty
sed -i 's/^Defaults.*.requiretty/#Defaults    requiretty/' /etc/sudoers

四. 修改zabbix_agentd配置

1. 在zabbix_agentd.conf中添加以下内容

#monitor process
UserParameter=process.nginx.memory,/etc/zabbix/scripts/processstatus.sh nginx
UserParameter=process.nginx.cpu,/etc/zabbix/scripts/processstatus.sh nginxcpu
UserParameter=custom.vfs.dev.read.ms[*],cat /proc/diskstats | grep $1 | head -1 | awk '{print $$7}'
UserParameter=custom.vfs.dev.write.ops[*],cat /proc/diskstats | grep $1 | head -1 | awk '{print $$8}'
UserParameter=custom.vfs.dev.write.ms[*],cat /proc/diskstats | grep $1 | head -1 | awk '{print $$11}'
UserParameter=custom.vfs.dev.io.active[*],cat /proc/diskstats | grep $1 | head -1 | awk '{print $$12}'
UserParameter=custom.vfs.dev.io.ms[*],cat /proc/diskstats | grep $1 | head -1 | awk '{print $$13}'
UserParameter=custom.vfs.dev.read.sectors[*],cat /proc/diskstats | grep $1 | head -1 | awk '{print $$6}'
UserParameter=custom.vfs.dev.write.sectors[*],cat /proc/diskstats | grep $1 | head -1 | awk '{print $$10}'
UserParameter=zabbix_partition_discovery[*],/bin/bash /etc/zabbix/scripts/partition_low_discovery.sh $1

2. 重启zabbix服务

/etc/init.d/zabbix-agent restart

五. 主机关联模板

1. 导入监控模板文件,

下载Template_partition_Auto_Discovery:
https://www.guoxiangfu.com/zb_users/upload/2017/07/201707141500004488508687.zip

1.1 导入模板

监控

监控

1.2 关联zabbix客户端主机

监控

监控

监控

2. 因为要监控特有的分区

需要使用zabbix正则表达式过滤,管理->一般->右侧下来条选择“正则表达式”->创建

3. 正则表达式:

名称:Partition regex
表达式:^(vda|vdb|vdc|vdd|vde|vdf|vdg|sda|sdb|sdc|sdd|sde|sdf|sdg|xvda|xvdb|xvdc|xvdd|xvde|xvdf|
xvdg|xvdh|xvdi|xvdj|xvdk|xvdq|xvdl)$
期望的结果:结果为真

监控

监控

监控

3.1 打开主机监控的图形

监控

Zabbix 3.2.6配置ODBC监控MySQL和Oracle

一、总览

ODBC的监控和在Zabbix前端配置数据库监控条目类型基本一致。

ODBC是用C语言编写的用于连接数据库管理系统的一个中间件,最初有微软公司研发,后来发展到各大平台。

有了ODBC的支持,Zabbix可以查询很多种数据库,因为Zabbix自己不直接去连接数据库,而是通过ODBC的接口和驱动,因此可以更加高效的去监控不同的数据库。

二、安装配置

1、编译Zabbix server

要支持ODBC功能,在编译的时候需要加上--with-unixodbc,解决依赖需要安装如下软件包,
yum -y install unixODBC unixODBC-devel

2、安装unixODBC驱动

驱动是用于ODBC连接数据库用的,他可以支持各式各样的驱动,在大部分的Linux发行版中的仓库中,都有这些驱动,我们安装一个MySQL的驱动,用来监控MySQL数据库。
yum install mysql-connector-odbc

3、配置unixODBC

ODBC的配置主要是通过修改odbcinst.ini和odbc.ini两个文件,可以通过下面的命令去指定配置文件的位置。

# odbcinst -j
unixODBC 2.2.14
DRIVERS............: /etc/odbcinst.ini
SYSTEM DATA SOURCES: /etc/odbc.ini
FILE DATA SOURCES..: /etc/ODBCDataSources
USER DATA SOURCES..: /root/.odbc.ini
SQLULEN Size.......: 8
SQLLEN Size........: 8
SQLSETPOSIROW Size.: 8

odbcinst.ini主要是配置安装的ODBC数据库驱动,如MySQL,oracle,各字段含义我不再介绍。

[MySQL]                      # 驱动名称,在数据库文件中需要
Description     = ODBC for MySQL
Driver          = /usr/lib/libmyodbc5.so
Setup           = /usr/lib/libodbcmyS.so
Driver64        = /usr/lib64/libmyodbc5.so
Setup64         = /usr/lib64/libodbcmyS.so
FileUsage       = 1

odbc.ini主要是配置数据源。

[test]                        # 数据源名称Data source name,在zabbix前端配置需要
Description = MySQL test database
Driver      = mysql           # 从驱动文件odbcinst.ini获取
Server      = 127.0.0.1
User        = zabbix
Password    = zabbix
Port        = 3306
Database    = zabbix

我们可以通过在安装unixODBC的时候附带安装的一个命令isql来判断我们是否可以成功的连接数据库。

# isql test
+---------------------------------------+
| Connected!                            |
|                                       |
| sql-statement                         |
| help [tablename]                      |
| quit                                  |
|                                       |
+---------------------------------------+
SQL>

4、配置Zabbix前端web

首先创建一个监控条目。

监控

这几个条目是必填的,具体解释如下:

  • Type 这里我们选择Database monitor
  • Key 选择db.odbc.select[unique_description,data_source_name]
    unique_description将会用于触发器中的条目
    data_source_name填写在odbc.ini中的test
  • User name 输入在odbc.ini中的用户名
  • Password 输入在odbc.ini中的密码
  • SQL query 输入SQL查询语句
  • Type of information 需要我们之前查询的返回值是什么,正确的选择才会被支持

5、注意事项

  • 查询语句执行时间不能超过配置的超时时间

  • 查询只允许返回一个值.

  • 如果查询语句返回了多个列,它只读取第一列

  • 如果查询语句返回了多行,它读取第一条

  • SQL语句必须是 select开头,只能是查询语句.

  • SQL语句不能包含换行符

6、错误消息

从zabbix 2.08开始ODBC提供如下详细的错误信息:
Cannot execute ODBC query:[SQL_ERROR]:[42601][7][ERROR: syntax error at or near ";"; Error while executing the query]|
-------------------------  ---------   -----  |  ------------------------------------------------------------------- |
            |                  |         |    `- Native error code            `- error message.                      `- Record separator
            |                  |         `-SQLState
            `- Zabbix message  `- ODBC return code
错误消息最长不能超过128字节,因此错误消息太长会被截断。

三、验证

因为我们没有创建图像,可以从最新数据库里面查看我们创建的条目。

监控

你可以写更加复杂的SQL查询语句,以及制作触发器来对数据库更加详细的监控。

附录:

以上是对监控MySQL做的监控,下面我主要简要对Oracle的监控做下介绍。

1、下载oracle客户端

http://www.oracle.com/technetwork/topics/linuxx86-64soft-092277.html

官网下载速度比较慢,也可以到我上传到51CTO下载中心的地方下载。

http://down.51cto.com/data/2328882

oracle-instantclient11.2-basic-11.2.0.3.0-1.x86_64.rpm
oracle-instantclient11.2-devel-11.2.0.3.0-1.x86_64.rpm
oracle-instantclient11.2-odbc-11.2.0.3.0-1.x86_64.rpm
oracle-instantclient11.2-sqlplus-11.2.0.3.0-1.x86_64.rpm

2、安装

yum localinstall oracle-instantclient11.2-*

3、创建本地监控

安装的默认位置分别在
/usr/share/oracle/11.2/client64
/usr/include/oracle/11.2/client64
/usr/lib/oracle/11.2/client64
 设置环境变量之前,在/usr/lib/oracle/11.2/client64下创建network/admin文件夹,
mkdir  -p  /usr/lib/oracle/11.2/client64/network/admin
在此文件夹下创建tnsnames.ora,其内容入下:
test_oracle=
   (DESCRIPTION =
     (ADDRESS = (PROTOCOL = TCP)(HOST = 10.0.1.14)(PORT = 1521))
     (CONNECT_DATA =
        (SERVER = DEDICATED)
        (SERVICE_NAME = basicdb)
     )
    )

    在/usr/lib/oracle/11.2/client64/network/admin文件下创建sqlnet.ora,输入:

NAME_DIRECTORY_PATH=(TNSNAMES,EZCONNECT)

4、配置环境变量

export ORACLE_HOME=/usr/lib/oracle/11.2/client64
export LD_LIBRARY_PATH=$ORACLE_HOME/lib:/usr/lib64:$LD_LIBRARY_PATH
export TNS_ADMIN=$ORACLE_HOME/network/admin
export PATH=$PATH:$ORACLE_HOME/bin:$HOME/bin

5、配置需要的库

chmod +x /usr/lib/oracle/11.2/client64/lib/libsqora.so.11.1
cd /usr/lib64/
ln -s libodbcinst.so.2.0.0  libodbcinst.so.1

6、添加oracle驱动

# vim  /etc/odbcinst.ini
[oracle]
Description     = Oracle ODBC driver for Oracle 11g
Driver          = /usr/lib/oracle/11.2/client64/lib/libsqora.so.11.1

7、添加oracle数据源

# vim  /etc/odbc.ini  
[test1]
Driver= oracle
DSN= test_oracle
ServerName= yourname
UserID= basicdb
Password= yourpasswd

8、sqlplus测试连接

# sqlplus yourname/yourpasswd@test_oracle

SQL*Plus: Release 11.2.0.3.0 Production on Wed Jul 19 11:39:18 2017

Copyright (c) 1982, 2011, Oracle.  All rights reserved.


Connected to:

Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL&gt; exit

9、配置zabbix前端

参考文档:https://www.zabbix.com/documentation/3.2/manual/config/items/itemtypes/odbc_checks

配置zabbix使用mailx实现邮件报警

说明:

Zabbix监控服务端、客户端都已经部署完成,被监控主机已经添加,Zabiix监控运行正常。

实现目的:

在Zabbix服务端设置邮件报警,当被监控主机宕机或者达到触发器预设值时,会自动发送报警邮件到指定邮箱。

具体操作:

以下操作在Zabbix监控服务端进行

备注:Zabbix监控服务端

操作系统:CentOS

使用外部邮箱账号发送报警邮件设置:

一、关闭sendmail或者postfix

service sendmail stop #关闭

chkconfig sendmail off #禁止开机启动

service postfix stop

chkconfig postfix off

备注:

使用外部邮箱账号时,不需要启动sendmail或者postfix

如果在sendmail或者postfix启动的同时使用外部邮箱发送报警邮件,首先会读取外部邮箱

配置信息。

二、安装邮件发送工具mailx

yum install mailx #安装

CentOS 5.x 编译安装mailx,直接yum安装的mailx版本太旧,使用外部邮件发送会有问题。

yum remove mailx #卸载系统自带的旧版mailx

下载mailx:

http://nchc.dl.sourceforge.net/project/heirloom/heirloom-mailx/12.4/mailx-12.4.tar.bz2

tar jxvf mailx-12.4.tar.bz2 #解压

cd mailx-12.4 #进入目录

make #编译

make install UCBINSTALL=/usr/bin/install #安装

ln -s /usr/local/bin/mailx /bin/mail #创建mailx到mail的软连接

ln -s /etc/nail.rc /etc/mail.rc #创建mailx配置文件软连接

三、配置Zabbix服务端外部邮箱

vi /etc/mail.rc #编辑,添加以下信息

set [email protected]

smtp=smtp.163.com   //添加发送人、发送服务器

set [email protected]

smtp-auth-password=123456   //添加发送人的邮箱和登录密码。

set smtp-auth=login  

:wq! #保存退出

echo "zabbix test mail" |mail -s "zabbix" [email protected]

#测试发送邮件,标题zabbix,邮件内容:zabbix test mail,发送到的邮箱:[email protected]或者[email protected],发送短信的时候要在139邮箱上面开启短信提醒。这里我就不说了,自己百度去。

#这时候,邮箱[email protected]会收到来自[email protected]的测试邮件

四、配置Zabbix服务端邮件报警

1、打开Zabbix

管理-示警媒介类型-创建媒体类型

监控

名称:Sendmail

类型:脚本

脚本名称:sendmail.sh

已启用:勾选

2、设置Zabbix用户报警邮箱地址

可以添加163邮箱也可以添加139邮箱。

监控

监控

类型:Sendmail

收件人:[email protected]

其他默认即可,也可
以根据需要设置

状态:已启用

存档

3、设置Zabbix触发报警的动作

组态-动作-创建动作

监控

名称:Action-Email

默认接收人:故障{TRIGGER.STATUS},服务器:{HOSTNAME1}发生: {TRIGGER.NAME}故障!

默认信息:

  • 告警主机:{HOSTNAME1}

  • 告警时间:{EVENT.DATE} {EVENT.TIME}

  • 告警等级:{TRIGGER.SEVERITY}

  • 告警信息: {TRIGGER.NAME}

  • 告警项目:{TRIGGER.KEY1}

  • 问题详情:{ITEM.NAME}:{ITEM.VALUE}

  • 当前状态:{TRIGGER.STATUS}:{ITEM.VALUE1}

  • 事件ID:{EVENT.ID}

  • 恢复信息:打钩

  • 恢复主旨:恢复{TRIGGER.STATUS}, 服务器:{HOSTNAME1}: {TRIGGER.NAME}已恢复!

  • 恢复信息:

  • 告警主机:{HOSTNAME1}

  • 告警时间:{EVENT.DATE} {EVENT.TIME}

  • 告警等级:{TRIGGER.SEVERITY}

  • 告警信息: {TRIGGER.NAME}

  • 告警项目:{TRIGGER.KEY1}

  • 问题详情:{ITEM.NAME}:{ITEM.VALUE}

  • 当前状态:{TRIGGER.STATUS}:{ITEM.VALUE1}

  • 事件ID:{EVENT.ID}

  • 已启用:打钩

监控

切换到操作选项

新的

操作类型:送出信息

送到用户:添加

默认信息:打钩

选择用户:Admin

选择

仅送到:Sendmail

存档

4、添加Zabbix服务端邮件发送脚本

cd /usr/local/zabbix/share/zabbix/alertscripts #进入脚本存放目录

vi sendmail.sh #编辑,添加以下代码

#!/bin/sh

echo "$3" | mail -s "$2" $1

:wq! #保存退出

chown -R zabbix.zabbix /usr/local/zabbix/share/zabbix/alertscripts/*

zabbix_server.conf 文件中加入脚本的相对路径

AlertScriptsPath=/usr/local/zabbix/share/zabbix/alertscripts

#设置脚本所有者为zabbix用户

chmod +x /usr/local/zabbix/share/zabbix/alertscripts/sendmail.sh

#设置脚本执行权限

五、测试Zabbix报警

关闭Zabbix客户端服务

service zabbix_agentd stop

查看你的[email protected]邮箱,会收到报警邮件

再开启Zabbix客户端服务

service zabbix_agentd start

查看你的[email protected]邮箱,会收到恢复邮件

使用外部邮箱账号发送报警邮件设置完成。

至此,Zabbix邮件报警设置完成。

使用zabbix自动发现自动监控多tomcat实例

说明

何为自动发现?首先我们监控多tomcat实例,如果一个个实例地添加或许可以完成当前需求。但是日后随着实例的增多,再手动一个个去添加就十分不方便了。这时候需要自动发现这个功能,来帮助我们自动添加监控tomcat实例。本文就以监控tomcat线程为例,来实现这个自动发现的功能。这里zabbix版本为3.0。

监控

创建自动发现脚本

可以理解为这个脚本能够打印出当前服务器上所有的tomcat实例名称。zabbix会定期执行这个脚本,做到自动发现当前所有的tomcat实例,脚本放在zabbix-agent安装路径的scripts目录下。而下一步就是给找到的tomcat实例添加所需要监控的值。下面先看脚本:

# cat discover_jvm.py
#!/usr/bin/python2.7 
#Usage: discover tomcat_app
#Last Modified:

import subprocess
import json

#args为自己定义查找项目名字的方式,由于各自部署方式的不同,这里需要根据实际情况来写命令。
args="find /opt/app/applications -name 'catalina.properties' | sort -n | uniq | awk -F'/' '{print $5}'"
t=subprocess.Popen(args,shell=True,stdout=subprocess.PIPE).communicate()[0]

apps=[]

for app in t.split('n'):
    if len(app) != 0:
        apps.append({'{#APP_NAME}':app})

打印出zabbix可识别的json格式

print json.dumps({'data':apps},indent=4,separators=(',',':'))

执行打印结果如下所示:

# chmod a+x discover_jvm.py 赋予执行权限
# chown zabbix:zabbix discover_jvm.py 添加属主为zabbix用户
# ./discover_jvm.py 
{
    "data":[
        {
            "{#APP_NAME}":"app1"
        },
        {
            "{#APP_NAME}":"app2"
        }
    ]
}
这里打印出app1、app2两个实例,以后要是有其他实例,也能够同样打印出来。

创建监控项脚本

这个脚本的作用是打印出tomcat实例需要监控的项,本例为线程数。该脚本执行需要两个参数,$1为实例名,$2为监控项名。打印的结果为一个整型的数字。记得跟上面的脚本放在同样的位置,并赋予执行权限和正确的属主。

# cat app_status.sh 
#!/bin/bash
#Usage: tomcat_app status
#Last Modified:

app=$1
status=$2
pid=`ps -ef | grep "$app" | grep -v grep | grep -v "$0"| awk '{print $2}'`

case $status in
    thread.num)
        /opt/programs/jdk1.7.0_67/bin/jstack "$pid" | grep http | wc -l
        ;;
    *)
        echo "Usage:$0 {app_name status[thread.num]}" 
        exit 1
        ;;
esac

#执行
#./app_status.sh app_name thread.num

日后如果需要添加新的监控项,只需修改上面的脚本,改变$2的选择即可。

zabbix客户端配置

在客户端配置文件中添加自定义监控的key,其实就是给我们监控选项取个名字,然后如何获取这个值。示例如下:

#变量1的key为custom.discover.jvm_app,为自动发现的tomcat实例名,获取方式即为执行dicover_jvm脚本
UserParameter=custom.discover.jvm_app,/opt/programs/bd-zabbix-agentd_3.0.4/scripts/discover_jvm.py
#变量2的key为custom.app.thread_num,[*]表示需要变量支持,这里即为$1、$2(本例中$2的意义不同,监控项就不同)获取方式为执行app_status.sh脚本
UserParameter=custom.app.thread_num[*],/opt/programs/bd-zabbix-agentd_3.0.4/scripts/app_status.sh $1 $2

修改完后重启zabbix客户端。然后在服务端进行验证:

#验证获取custom.discover.jvm_app的key值
zabbix-server_3.0.4/bin/zabbix_get -s 10.205.51.22 -p 20050 -k custom.discover.jvm_app
#验证获取custom.app.thread_num的key值
./zabbix_get -s 10.205.51.22 -p 20050 -k custom.app.thread_num[app1,thread_num]
如果正确的话,就会返回在客户端执行脚本一样的结果。

zabbix界面添加自动发现模版

为了便于后面更多的主机添加此监控,这里就创建一个模板来进行配置。首先创建一个发现规则,该规则就是用来自动发现tomcat实例的:

监控

取一个名字,并填上我们之前定义的key,然后保存即可:

监控

然后创建一个监控项:

监控

取一个名字,也填上我们之前定义的key,注意这里的#APP_NAME为之前脚本输出的变量,要填写一致:

监控

然后我们创建一个图像来观察数据:

监控

同样取名字的变量要跟之前一致,并添加数据源为刚刚我们定义的监控项:

监控

最后可以观察到图像:

监控

当然我们还可以定义一个触发器,比如大于多少线程就告警,这里就不一一赘述了。

使用Nagios中监控进程最大线程数

最近在刚好一些业务经常把线程跑满,导致服务器资源用完,所以就写了一个脚本用于Nagios下相关进程的最大线程数的监控,Unix的服务器上最大的线程数默认的是1024,当然在业务繁忙的服务器中这样肯定是不够用的,当然在实际生产环境中做初始化调优时一般都会有做过修改,如开启打开文件的最大句柄数等等,一般情况下我们都是修改/etc/security/limits.conf文件,但是要修改最大线程数就要修改/etc/security/limits.d/90-nproc.conf文件了,修改就和修改limits.conf文件文件的方式一样,在此就不做过多的解释,我一般把所有用户的最大的线程数都调大

*          soft    nproc     65535

在调整好后线程数的预警值可以根据实际情况调整,脚本实现也很简单,如下:

#!/bin/bash
#check_pstree.sh
#Used for pstree process monitoring
#writer jim
#history 2017.07.01

# Nagios 返回值
STATE_OK=0
STATE_WARNING=1
STATE_CRITICAL=2
STATE_UNKNOWN=3
#对传递进来的参数判断
if [ $# -lt 1 ];then
    echo "Please enter the process string"
    echo "ex> $0 java"
    exit $STATE_UNKNOWN
fi

if [ $# -gt 1 ]; then
        echo "The input parameters are too much"
    echo "ex> $0 java"
    exit $STATE_UNKNOWN
fi

reg_name=$1
process_pid=$(ps -ef | grep "$reg_name " | grep -v grep | awk '{print $2}')
declare -i max_process_num=$(ulimit -an | grep "max user processes" | awk '{print $5}')
declare -i warning_num=$max_process_num/2
#在此预警值取最大线程数的50%,具体可以根据实际生产环境修改
pstree_num=$(pstree -p $process_pid | wc -l)

if [ $pstree_num -le $warning_num ];then
        echo "$reg_name pstree number is:$pstree_num;warning_num is:$warning_num;max user processes is:$max_process_num,OK"
        exit $STATE_OK
else 
        echo "error!!!The number of pstree is too much.the number is:$pstree_num"
        exit $STATE_CRITICAL
fi

当然在这个脚本也可以修改后用cron任务中做定时检查,不过在Nagios中不知为何线程数的值在Nagios的监控页面下显示总有异常,不过直接执行是没有问题的。

Ganglia监控Hadoop集群 使用Nagios发送告警邮件

基本介绍

Ganglia:是UC Berkeley发起的一个开源集群监视项目,设计用于测量数以千计的节点。Ganglia的核心包含gmond、gmetad以及一个Web前端。主要是用来监控系统性能,如:cpu 、mem、硬盘利用率, I/O负载、网络流量情况、系统负载等,通过曲线很容易见到每个节点的工作状态,对合理调整、分配系统资源,提高系统整体性能起到重要作用。
更重要的是,HDFS、YARN、HBase等已经支持其守护进程的资源情况发送给Ganglia进行监控。

Nagios:是一款开源的电脑系统和网络监视工具,能有效监控Windows、Linux和Unix的主机状态,交换机路由器等网络设置,打印机等。尤其有用的是,在系统或服务状态异常时发出邮件或短信报警第一时间通知网站运维人员,在状态恢复后发出正常的邮件或短信通知。

我们这次的架构设计:

  1. Ganglia的优势在于监控数据的实时性和丰富的图形化界面,同时对Mobile端支持的很好,但是在出现问题的时候报警提示功能,相对较弱。

  2. Nagios的优势在于出现问题和问题恢复时可以提供强大的报警提示功能,但是在实时监控和图形化展示上功能较弱,对大规模集群支持较差。

  3. 要对数据平台中支持的Hadoop集群(HDFS、YARN)对资源的使用情况进行监控。

所以我们将3者结合起来,架构如下:

监控

相关版本:Ubuntu 16.04 LTS、Ganglia 3.6.1、Nagios 4.1.1、Hadoop 2.7.3

部署Ganglia:

在需要进行Web展示的节点上安装:

sudo apt-get update
sudo apt install apache2 php libapache2-mod-php 
sudo apt-get install rrdtool
sudo apt-get install gmetad ganglia-webfrontend
#过程中出现apache2重启的对话框,选择yes即可

在需要被监控的节点上安装:

sudo apt-get update
sudo apt install php libapache2-mod-php 
sudo apt-get install ganglia-monitor
#过程中出现apache2重启的对话框,选择yes即可

下述操作过程,在主节点上进行:

#复制 Ganglia webfrontend Apache 配置:
sudo cp /etc/ganglia-webfrontend/apache.conf /etc/apache2/sites-enabled/ganglia.conf

#编辑gmetad配置文件 
sudo vi /etc/ganglia/gmetad.conf
#更改数据源 data_source “my cluster” localhost 修改为:
data_source "bigdata cluster" 10  wl1:8649 wl2:8649 wl3:8649
setuid_username "nobody"
gridname "bigdata cluster"
case_sensitive_hostnames 1
all_trusted on

#主节点上执行:
sudo ln -s /usr/share/ganglia-webfrontend/ /var/www/ganglia

下述操作过程,在所有被监控节点上进行:

#编辑gmond配置文件 
sudo vi /etc/ganglia/gmond.conf
globals {
  daemonize = yes
  setuid = yes
  user = ganglia
  debug_level = 0
  max_udp_msg_len = 1472
  mute = no
  deaf = no
  host_dmax = 0 /*secs */
  cleanup_threshold = 300 /*secs */
  gexec = no
  send_metadata_interval = 10
}
/* If a cluster attribute is specified, then all gmond hosts are wrapped inside
 * of a <CLUSTER> tag.  If you do not specify a cluster tag, then all <HOSTS> will
 * NOT be wrapped inside of a <CLUSTER> tag. */
cluster {
  name = "bigdata cluster"
  owner = "ganglia"
  latlong = "unspecified"
  url = "unspecified"
}

/* The host section describes attributes of the host, like the location */
host {
  location = “wl1"  #每个节点写自己的主机名
}

/* Feel free to specify as many udp_send_channels as you like.  Gmond
   used to only support having a single channel */
udp_send_channel {
  #mcast_join = 239.2.11.71
  host = wl1  #每个节点都指向gmetad主机
  port = 8649
  ttl = 1
}

/* You can specify as many udp_recv_channels as you like as well. */
udp_recv_channel {
  #mcast_join = 239.2.11.71
  port = 8649
  #bind = 239.2.11.71
}


/* You can specify as many tcp_accept_channels as you like to share
   an xml description of the state of the cluster */
tcp_accept_channel {
  port = 8649
}

收集Hadoop集群的HDFS、YARN metric源:

下述操作过程,在所有Hadoop集群节点上进行:

#编辑hadoop-metrics2.properties
vi hadoop-2.7.3/etc/hadoop/hadoop-metrics2.properties
#注释掉所有原来的内容,增加如下内容:
*.sink.ganglia.class=org.apache.hadoop.metrics2.sink.ganglia.GangliaSink31
*.sink.ganglia.period=10

*.sink.ganglia.slope=jvm.metrics.gcCount=zero,jvm.metrics.memHeapUsedM=both
*.sink.ganglia.dmax=jvm.metrics.threadsBlocked=70,jvm.metrics.memHeapUsedM=40

namenode.sink.ganglia.servers=wl1:8649
resourcemanager.sink.ganglia.servers=wl1:8649

datanode.sink.ganglia.servers=wl1:8649
nodemanager.sink.ganglia.servers=wl1:8649

jobhistoryserver.sink.ganglia.servers=wl1:8649

maptask.sink.ganglia.servers=wl1:8649
reducetask.sink.ganglia.servers=wl1:8649

重启Hadoop集群、重启gmond、gmetad、gweb:

hadoop-2.7.3/sbin/stop-all.sh
hadoop-2.7.3/sbin/start-all.sh
sudo /etc/init.d/ganglia-monitor restart (所有节点) gmond服务 
sudo /etc/init.d/gmetad restart    (gmetad节点)   gmetad服务
sudo /etc/init.d/apache2 restart  (gweb节点)    web服务(包含gweb服务)

然后在安装了gweb的节点上使用主机ip/ganglia即可登录Web:

监控

选择某个Node具体观察,可以看到已经收集到了HDFS和YARN的度量数据:

监控

监控

选择Mobile标签页,可以看到对移动终端的展示支持的很好:

监控

部署Nagios:

  • 为了Nagios能正常发送告警邮件,先要安装sendmail工具:
sudo apt-get install sendmail  
sudo apt-get install sendmail-cf
sudo apt-get install mailutils  
sudo apt-get install sharutils
#终端输入命令:
ps aux |grep sendmail
#输出如下:说明sendmail 已经安装成功并启动了
root     20978  0.0  0.3   8300  1940 ?        Ss   06:34   0:00 sendmail: MTA: accepting connections          
root     21711  0.0  0.1   3008   776 pts/0    S+   06:51   0:00 grep sendmail
  • 配置sendmail:
#打开sendmail的配置文件 /etc/mail/sendmail.mc
vi  /etc/mail/sendmail.mc
#找到如下行:
DAEMON_OPTIONS(`Family=inet,  Name=MTA-v4, Port=smtp, Addr=127.0.0.1')dnl
#将Addr=127.0.0.1修改为Addr=0.0.0.0,表明可以连接到任何服务器。
DAEMON_OPTIONS(`Family=inet,  Name=MTA-v4, Port=smtp, Addr=0.0.0.0')dnl

#生成新的配置文件:
cd /etc/mail  
mv sendmail.cf sendmail.cf~      #做一个备份  
m4 sendmail.mc &gt; sendmail.cf  #&gt;的左右有空格
#修改sendmail.cf
vi /etc/mail/sendmail.cf
#新增
Dj$w. #注意最后面有一个点

#修改hosts,否则发送邮件的过程会非常慢,因为sendmail
#以wl1作为域名加到主机名wl1后组成完整的长名wl1.wl1来访问,
#会提示找不到域名
vi /etc/hosts
x.x.x.x       wl1 wl1.localdomain wl1.wl1
#重启sendmail服务:
service sendmail restart
#测试发送邮件,看看能否收得到:
echo "test" | mail -s test [email protected]
  • 安装Nagios:

参考Ubuntu 16.04 安装 Nagios Core:

Ubuntu 16.04 安装 Nagios Core

其中下载Nagios插件那一步时,nagios-plugins-2.1.1官网下载太慢,先从下面的链接下载好,然后编译安装

nagios-plugins-2.1.1下载:
http://download.csdn.net/download/u014722463/9288011

使用http://主机IP/nagios/ 登录,需要输入安装时设置的用户名nagiosadmin及其密码,然后就可以看到主页了:

监控

  • 主要说一下如何用Nagios监控Ganglia数据,并根据阀值发出告警:
#新生成一个监控ganglia的插件check_ganglia.py
cd /usr/local/nagios/libexec
vi check_ganglia.py #内容如下:
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
import sys
import getopt
import socket
import xml.parsers.expat

class GParser:
  def __init__(self, host, metric):
    self.inhost =0
    self.inmetric = 0
    self.value = None
    self.host = host
    self.metric = metric

  def parse(self, file):
    p = xml.parsers.expat.ParserCreate()
    p.StartElementHandler = parser.start_element
    p.EndElementHandler = parser.end_element
    p.ParseFile(file)
    if self.value == None:
      raise Exception('Host/value not found')
    return float(self.value)

  def start_element(self, name, attrs):
    if name == "HOST":
      if attrs["NAME"]==self.host:
        self.inhost=1
    elif self.inhost==1 and name == "METRIC" and attrs["NAME"]==self.metric:
      self.value=attrs["VAL"]

  def end_element(self, name):
    if name == "HOST" and self.inhost==1:
      self.inhost=0

def usage():
 print """Usage: check_ganglia 
-h|--host= -m|--metric= -w|--warning= 
-c|--critical= [-o|--opposite=] [-s|--server=] [-p|--port=] """
 sys.exit(3)

if __name__ == "__main__":
##############################################################
 ganglia_host = 'x.x.x.x'  #修改为你的gmetad主机的ip
 ganglia_port = 8651
 host = None
 metric = None
 warning = None
 critical = None
 opposite = 0  ##增加一个参数,表示设定值取反,也就是当实际值小于等于设定值报警

 try:
   options, args = getopt.getopt(sys.argv[1:],
     "h:m:w:c:o:s:p:",
     ["host=", "metric=", "warning=","critical=","opposite=", "server=","port="],
     )
 except getopt.GetoptError, err:
   print "check_gmond:", str(err)
   usage()
   sys.exit(3)

 for o, a in options:
   if o in ("-h", "--host"):
      host = a
   elif o in ("-m", "--metric"):
      metric = a
   elif o in ("-w", "--warning"):
      warning = float(a)
   elif o in ("-c", "--critical"):
      critical = float(a)
   elif o in ("-o", "--opposite"):
      opposite = int(a)
   elif o in ("-p", "--port"):
      ganglia_port = int(a)
   elif o in ("-s", "--server"):
      ganglia_host = a


 if critical == None or warning == None or metric == None or host ==None:
   usage()
   sys.exit(3)

 try:
   s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
   s.connect((ganglia_host,ganglia_port))
   parser = GParser(host, metric)
   value = parser.parse(s.makefile("r"))
   s.close()
 except Exception, err:
   #import pdb
   #pdb.set_trace()
   print "CHECKGANGLIA UNKNOWN: Error while getting value"%s"" % (err)
   sys.exit(3)

 if opposite == 1: ###根据传入参数做判断,等于1时,表示取反,等于0,不取反
      if value &lt;= critical:
        print &quot;CHECKGANGLIA CRITICAL: %s is %.2f&quot; % (metric, value)
        sys.exit(2)
      elif value = critical:
        print "CHECKGANGLIA CRITICAL: %s is %.2f" % (metric, value)
        sys.exit(2)
      elif value &gt;= warning:
          print "CHECKGANGLIA WARNING: %sis %.2f" % (metric, value)
          sys.exit(1)
      else:
        print "CHECKGANGLIA OK: %s is %.2f" % (metric, value)
        sys.exit(0)

修改该脚本为可读写、操作权限:

 chmod 755 check_ganglia.py

在如下目录,新建文件:(注意啊,里面最好不要有注释,可能会引起功能不可用,原因我没时间去分析)

#在/usr/local/nagios/etc/objects/下新建一个services.cfg
cd /usr/local/nagios/etc/objects/
vi services.cfg #内容如下:
define host {
    use linux-server
    host_name wl1
    address   x.x.x.1
}

define host {
    use linux-server
    host_name wl2
    address   x.x.x.2
}

define host {
    use linux-server
    host_name wl3
    address   x.x.x.3
}

define hostgroup {
    hostgroup_name ganglia-servers
    alias   nagios server
    members *
}

define servicegroup {
  servicegroup_name ganglia-metrics
  alias Ganglia Metrics
}

define command {
  command_name check_ganglia
  command_line $USER1$/check_ganglia.py -h $HOSTNAME$ -m $ARG1$ -w $ARG2$ -c $ARG3$ -o $ARG4$
}

define service {
    use generic-service
    name ganglia-service
    hostgroup_name ganglia-servers
    service_groups ganglia-metrics
    notifications_enabled 1
    notification_interval 10
    register  0
}

define service{
        use                             ganglia-service
        service_description             内存空闲
        check_command                   check_ganglia!mem_free!200!50!1
        contact_groups admins
}

define service{
        use                             ganglia-service
        service_description             load_one
        check_command                   check_ganglia!load_one!4!5!0
        contact_groups admins
}
define service{
        use                             ganglia-service
        service_description             disc_free
        check_command                   check_ganglia!disk_free!40!50!0
        contact_groups admins
}
define service{
        use                             ganglia-service
        service_description             yarn.NodeManagerMetrics.AvailableGB
        check_command                   check_ganglia!yarn.NodeManagerMetrics.AvailableGB!8!4!1
        contact_groups admins
}

需要注意的是,这个services.cfg文件就是用来你的Nagios自动去Ganglia里面取数据的,里面定义的需要关注的Ganglia的项目越多,Nagios里面显示的越多,我这里仅仅是一个范本,只举例了几个简单的数据,如果有需要,请自行增加。

修改该配置文件为可读写、操作权限:

chown nagios:nagios services.cfg
chmod 664 services.cfg

修改Nagios主配置文件:

vi /usr/local/nagios/etc/nagios.cfg
#cfg_file=/usr/local/nagios/etc/objects/localhost.cfg

#add by wangliang for ganglia
cfg_file=/usr/local/nagios/etc/objects/services.cfg

修改和发送告警邮件相关的配置:

vi /usr/local/nagios/etc/objects/commands.cfg
#将其中的/bin/mail替换为mail
# '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$nState: $HOSTSTATE$nAddress: $HOSTADDRESS$nInfo: $HOSTOUTPUT$nnDate/Time: $LONGDATETIME$n" | mail -s "** $NOTIFICATIONTYPE$ 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: $SERVICEDESC$nHost: $HOSTALIAS$nAddress: $HOSTADDRESS$nState: $SERVICESTATE$nnDate/Time: $LONGDATETIME$nnAdditional Info:nn$SERVICEOUTPUT$n" | mail -s "** $NOTIFICATIONTYPE$ Service Alert: $HOSTALIAS$/$SERVICEDESC$ is $SERVICESTATE$ **" $CONTACTEMAIL$
        }

#修改发送的邮件地址和收件人:
vi /usr/local/nagios/etc/objects/contacts.cfg
###############################################################################
# CONTACTS.CFG - SAMPLE CONTACT/CONTACTGROUP DEFINITIONS
#
#
# NOTES: This config file provides you with some example contact and contact
#        group definitions that you can reference in host and service
#        definitions.
#
#        You don't need to keep these definitions in a separate file from your
#        other object definitions.  This has been done just to make things
#        easier to understand.
#
###############################################################################



###############################################################################
###############################################################################
#
# CONTACTS
#
###############################################################################
###############################################################################

# Just one contact defined by default - the Nagios admin (that's you)
# This contact definition inherits a lot of default values from the 'generic-contact'
# template which is defined elsewhere.

define contact{
        contact_name                    nagiosadmin        ; Short name of user
    use                generic-contact        ; Inherit default values from generic-contact template (defined above)
        alias                           Nagios Admin        ; Full name of user

        email                           [email protected]    ; &lt;&lt;***** CHANGE THIS TO YOUR EMAIL ADDRESS ******
        }

define contact{
        contact_name                    nagiosadmin2           ; Short name of user
        use                             generic-contact         ; Inherit default values from generic-contact template (defined above)
        alias                           Nagios Admin2            ; Full name of user

        email                           [email protected]     ; &lt;&lt;***** CHANGE THIS TO YOUR EMAIL ADDRESS ******
        }

define contact{
        contact_name                    nagiosadmin3             ; Short name of user
        use                             generic-contact         ; Inherit default values from generic-contact template (defined above)
        alias                           Nagios Admin3            ; Full name of user

        email                          [email protected]     ; &lt;&lt;***** CHANGE THIS TO YOUR EMAIL ADDRESS ******
        }
###############################################################################
###############################################################################
#
# CONTACT GROUPS
#
###############################################################################
###############################################################################

# We only have one contact in this simple configuration file, so there is
# no need to create more than one contact group.

define contactgroup{
        contactgroup_name       admins
        alias                   Nagios Administrators
        members            *
        }

利用如下命令,判断修改是否成功:

/usr/local/nagios/bin/nagios -v /usr/local/nagios/etc/nagios.cfg
Total Warnings: 0
Total Errors:   0

按顺序重启相关服务:

sudo /etc/init.d/ganglia-monitor restart  (所有节点)
sudo /etc/init.d/gmetad restart       (gmetad节点)
sudo /etc/init.d/apache2 restart      (gweb节点)
service nagios restart    (nagios节点)
service sendmail restart  (nagios节点)

最后的效果图如下:
(nagios采集数据的过程略慢,有的时候会短暂的显示service status是unknown或者pending,过一会就会好的,不用着急)

监控

收到的邮件告警的图示:

监控

下一步工作是把这几个组件做成docker镜像,用k8s调度,具体过程不在详述,参考我前面的文章就可以完成。

需要注意的地方:

  1. 如果你想在Ganglia Web上显示各节点的主机名,则需要提前在
    gmetad节点的/etc/hosts里面配置好ip和hostname的映射关系,ganglia会在收到各节点数据时,先按照ip查找hosts里面的hostname,如果没有,则rrd中就按照ip存储;如果有,则rrd中按照查到的名字存储,Web显示数据时,是根据rrd中的记录的名字或者Ip来显示的。

  2. 如果你以前是按照ip显示,后来想改成hostname,则先要把rrd的内容清空,反之亦然。

  3. 记得rrd的权限是:
    drwxr-xr-x nobody nogroup rrds/
    否则网页会提示拒绝连接

  4. 由于sendmail使用的是smtp协议,而有的公司用的是esmtp协议的服务器,所以用本文描述的sendmail发送告警邮件可能邮箱会收不到。后来我使用了sendEmail的工具,它可以使用esmtp协议,如下格式:sendEmail -f [email protected] -t [email protected] -s smtp.exmail.qq.com -xu [email protected] -xp xxx -m “test”
    进行测试,就可以发送成功啦,
    安装很简单,参考此处:http://www.linuxidc.com/Linux/2011-12/49699.htm
    需要同步修改nagios的/usr/local/nagios/etc/objects/commands.cfg

define command{
        command_name    notify-host-by-email
        command_line    /usr/bin/printf &quot;%b&quot; &quot;***** Nagios *****nnNotification Type: $NOTIFICATIONTYPE$nHost: $HOSTNAME$nState: $HOSTSTATE$nAddress: $HOSTADDRESS$nInfo: $HOSTOUTPUT$nnDate/Time: $LONGDATETIME$n&quot; | /usr/local/bin/sendEmail -f [email protected] -t $CONTACTEMAIL$ -s smtp.exmail.qq.com -u &quot;** $NOTIFICATIONTYPE$ Host Alert: $HOSTNAME$ is $HOSTSTATE$ **&quot; -xu [email protected] -xp xxxx
        }

# 'notify-service-by-email' command definition
define command{
        command_name    notify-service-by-email
        command_line    /usr/bin/printf &quot;%b&quot; &quot;***** Nagios *****nnNotification Type: $NOTIFICATIONTYPE$nnService: $SERVICEDESC$nHost: $HOSTALIAS$nAddress: $HOSTADDRESS$nState: $SERVICESTATE$nnDate/Time: $LONGDATETIME$nnAdditional Info:nn$SERVICEOUTPUT$n&quot; | /usr/local/bin/sendEmail -f [email protected] -t $CONTACTEMAIL$ -s smtp.exmail.qq.com -u &quot;** $NOTIFICATIONTYPE$ Service Alert: $HOSTALIAS$/$SERVICEDESC$ is $SERVICESTATE$ **&quot; -xu [email protected] -xp xxx
        }

RedHat6.5安装配置Cacti监控工具

Cacti 在英文中的意思是仙人掌的意思,Cacti是一套基于PHP、MySQL、SNMP及RRDTool开发的网络流量监测图形分析工具。它通过snmpget来获取数据,使用 RRDtool绘画图形,它的界面非常漂亮,能让你根本无需明白rrdtool的参数能轻易的绘出漂亮的图形。而且你完全可以不需要了解RRDtool复杂的参数。它提供了非常强大的数据和用户管理功能,可以指定每一个用户能查看树状结 构、host以及任何一张图,还可以与LDAP结合进行用户验证,同时也能自己增加模板,让你添加自己的snmp_query和script!功能非常强大完善,界面友好。可以说,Cacti将rrdtool的所有“缺点”都补足了!

官方网站:http://www.cacti.net。好了,Cacti的简单介绍我们就说到这里了,下面我们来看一下Cacti的工作流程。

  • 主机环境 RedHat6.5 64位
  • 实验环境 服务端1 ip 172.25.25.1
    服务端2 ip 172.25.25.2
  • 安装包 cacti-0.8.8h.tar.gz
    php-snmp-5.3.3-26.el6.x86_64.rpm
    cacti-spine-0.8.8g.tar.gz
  • 防火墙状态:关闭
  • Selinux状态:Disabled

1.配置安装cacti及测试

A)配置安装cacti

[root@sever1 Asia]# yum install rrdtool mysql-server php httpdphp-mysql php-xml net-snmp net-snmp-utils- y                        #安装cacti之前要安装的包

[root@sever1 Asia]# cd /mnt/

[root@sever1 mnt]# ls

cacti-0.8.8h.tar.gz php-snmp-5.3.3-26.el6.x86_64.rpm

cacti-spine-0.8.8g.tar.gz

[root@sever1 mnt]# rpm -vih php-snmp-5.3.3-26.el6.x86_64.rpm

[root@sever1 mnt]# vim /etc/php.ini

946 date.timezone =Asia/Shanghai

[root@sever1 mnt]# tar zxf cacti-0.8.8h.tar.gz -C/var/www/html/  #解压到/var/www/html/目录

[root@sever1 mnt]# cd /var/www/html/

[root@sever1 html]# ls

cacti-0.8.8h

[root@sever1 html]# ln -s cacti-0.8.8h/ cacti          #作软链接

[root@sever1 html]# ls

cacti cacti-0.8.8h

[root@sever1 include]# /etc/init.d/mysqld start        #开启数据库

[root@sever1 include]# mysql_secure_installation

初始化,默认没密码,这里将密码设置成了redhat

[root@sever1 html]# cd cacti/                 

[root@sever1 cacti]# mysql -predhat -e "create databasecacti"      #创建名为cacti的数据库

[root@sever1 cacti]# mysql -predhat cacti < cacti.sql              #将cacti.sql文件导入到cacti数据库中

[root@sever1 cacti]# mysql -predhat -e "grant all oncacti.* to cacti@localhost identified by 'redhat'"                #创建本地cacti用户,并将cacti数据库的所有权限给cacti用户

[root@sever1 html]# cd include/               

[root@sever1 include]# vim config.php                  #修改配置文件
 29 $database_username ="cacti";                        #刚创建的cacti数据库的用户名

 30 $database_password ="redhat";                      #用户cacti的密码

 39 $url_path ="/cacti/";

 42 $cacti_session_name ="Cacti";
[root@sever1 cacti]# useradd -u 1000 cacti              #在系统中创建cacti用户

[root@sever1 cacti]# ll

total 1068

-rw-rw-r– 1 cacti cacti 5860 Feb 8 2016 about.php

-rw-rw-r– 1 cacti cacti 5348 Feb 8 2016 auth_changepassword.php

-rw-rw-r– 1 cacti cacti 14690 Mar 7 2016 auth_login.php

-rw-rw-r– 1 cacti cacti 178349 Apr 10 2012 cacti.sql

-rw-rw-r– 1 cacti cacti 20257 Feb 8 2016 cdef.php

[root@sever1 cacti]# su - cacti                        #切换到cacti用户

[cacti@sever1 ~]$ crontab -e                            #创建定时任务

*/5 * * * * php /var/www/html/cacti/poller.php > /dev/null2>&1

[cacti@sever1 ~]$ logout

[root@sever1 ~]# /etc/init.d/httpd start                #开启httpd

Stopping httpd: [ OK ]

安装cacti 172.25.25.1/cacti

点击next

监控
点击next
监控
在测试之前,时间得同步

B)测试 172.25.25.1/cacti

登陆 用户名:admin 密码:admin
监控
第一次登陆,会提示修改密码
监控
登陆之后,如图:
监控
点击graphs,如图:
监控

[root@sever1 cacti]# cd rra        #采集数据存放的位置

[root@sever1 rra]# ls

等待5分钟之后

[root@sever1 rra]# ls                  #已经有数据了

localhost_load_1min_5.rrd localhost_mem_swap_4.rrd localhost_users_6.rrd

localhost_mem_buffers_3.rrd localhost_proc_7.rrd

查看图像,如图:
监控

zabbix监控k8s(kubernetes)pod到service的网络

最近k8s测试环境不时地出现无法访问一些service endpoint的问题。排查发现是某些节点的kube-proxy没有同步最新的service来配置iptables,至于为什么没有同步service,目前还不知道。不过现在先加对service的监控来及时发现问题,争取到更多时间排查吧。

部署sa-tool

sa-tool其实就是一个centos镜像容器,为了方便在上面执行一些检测网络的命令。我们这里使用daemonset来部署。

apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
  name: sa-tool
spec:
  template:
    metadata:
      labels:
        app: sa-tool
    spec:
      containers:
      - command:
        - /bin/sh
        - -c
        - while true; do sleep 3600; done
        name: sa-tool
        image: centos:7

      restartPolicy: Always
      nodeSelector:
        ibd/worktype: "true"

监控脚本

#!/bin/bash

cat /dev/null > /tmp/test-pod-network.tmp
for pod in `kubectl --request-timeout 5s get pod | awk 'NR>1{print $1}'`;do
    for addr in `kubectl --request-timeout 5s get service  --all-namespaces -o=custom-columns=NAME:metadata.name,NAMESPACE:metadata.namespace,PORT:spec.ports[0].port | awk 'NR>1{print ""$1"."$2".svc.ibd.lan/"$3}'`;do
        if ! kubectl --request-timeout 5s exec -i $pod -- timeout 3 bash -c 'exec 3<> /dev/tcp/'$addr 2>/dev/null;then
            echo "$pod $addr" >> /tmp/test-pod-network.tmp
        fi    
    done
done
cp /tmp/test-pod-network.tmp /tmp/test-pod-network.log

配置key

打开agent配置文件,加入如下key

UserParameter=pod.network, cat /tmp/test-pod-network.log

配置监控项

登录zabbix后台,添加如下监控项:

pod.network