7.2 Zabbix 监控部署文档


7.2.1 Zabbix架构图

zabbix 的使用架构主要有两种,如果你的监控环境比较单一,可以使用简单的Server -> Agent,由zabbix-agent 直接上报给 zabbix-server。

image0

如果监控的环境比较复杂,就比如我们的线上的生产环境是分布式集群,最好使用的 Server-> Proxy -> Agent

image1

Zabbix Proxy 可以代替 Zabbix Server 检索客户端的数据,然后把数据汇报给 Zabbix Server, 并且在一定程度上分担了 Zabbix Server 的压力。Zabbix Proxy 可以非常简便的实现了集中式、分布式监控。 Zabbix Proxy 使用场景:

  1. 监控远程区域设备

  2. 监控本地网络不稳定区域

  3. 当 Zabbix 监控上千设备时,使用它来减轻 Server 的压力

  4. 简化 Zabbix 的维护

Zabbix Proxy 仅仅需要一条 TCP 连接到 Zabbix Server,所以防火墙上仅仅需要加上一条规则即可。 Zabbix Proxy 数据库必须和 Zabbix Server 分开,否则数据会被破坏,毕竟这两个数据库的表大部分都相同。 总之记住,数据库分开即可。如果在同一机器上,库名要更改,如果不在同一机器,就不用关心了。 Zabbix Proxy 收集到数据之后,首先将数据缓存在本地,然后在一定的时间之后传递给 Zabbix Server。 这个时间由 Zabbix Proxy 配置文件中参数 ProxyLocalBufferProxyOfflineBuffer 决定。

Zabbix Proxy 是一个数据收集器,它不计算触发器、不处理事件、不发送报警。

7.2.2 安装部署环境

7.2.2.1 安装 Server 端

安装MySQL

在此以 CentOS 7.2 为例

$ yum -y install mysql mysql-server mysql-devel
$ systemctl start mysql

# 首次登陆,密码为空
$ mysql -uroot -p

# 可以直接修改密码
$ mysqladmin -uroot password '123456'

由于监控数据比较多,而且只会越来越多,所以最好指定一个分区为 MySQL 专用。

# 建立分区 vdb1
$ fdisk /dev/vdb

# 格式化
$ mkfs -t xfs /dev/vdb1

# 查看分区的uuid
$ blkid /dev/vdb1
/dev/vdb1: UUID="ef289d30-44b4-4b1f-9cae-2f4f11cd9fc5" TYPE="xfs"

# 在 /etc/fstab 下添加
UUID=ef289d30-44b4-4b1f-9cae-2f4f11cd9fc5 /var/lib/mysql          xfs     defaults        0 0

# 开始挂载
cd /var/lib
mkdir mysql-bak

mv mysql/* mysql-bak/
mount -a
chown -a
chown mysql:mysql mysql/
mv mysql-bak/* mysql/
rm -rf mysql-bak/

安装 Zabbix Server

一切准备好,就可以开始安装 zabbix-server

rpm -i https://repo.zabbix.com/zabbix/4.0/rhel/7/x86_64/zabbix-release-4.0-1.el7.noarch.rpm
yum install -y zabbix-server-mysql zabbix-web-mysql zabbix-agent

修改配置

/etc/zabbix/zabbix_server.conf

DBName=zabbix
DBUser=zabbix
ListenIP=0.0.0.0

# 添加
DBPassword=<password>

创建数据库

$ mysql -uroot -proot12#$
MariaDB [(none)]> create database zabbix character set utf8 collate utf8_bin;
MariaDB [(none)]> grant all privileges on zabbix.* to zabbix@localhost identified by 'zabbix12#$';
MariaDB [(none)]> quit;

# 导入数据
$ cd /usr/share/doc/zabbix-server-mysql-4.0.1/ ;gzip -d create.sql.gz
$ mysql -uroot -p<password> zabbix < *.sql

# 若要导出数据库
$ mysqldump -P $port -u zabbix -h $host -p'$passwd' zabbix > zabbix.sql

修改完成后,重启服务

systemctl start zabbix-server

配置 HTTP

配置8080端口,vim /etc/httpd/conf/httpd.conf

# 可改可不改,不改就是80
Listen 0.0.0.0:8080

修改时区,/etc/httpd/conf.d/zabbix.conf

php_value date.timezone Asia/Shanghai

修改完成后,重启 http

systemctl restart httpd

访问:http://<ip>:8080/zabbix/,进行界面安装配置。

注意数据库,这里不要选localhost,使用vip,或者使用vip绑定的域名。

用默认密码进行登陆(Admin/zabbix)。 登陆之后,马上修改密码。

安装调试工具

# 调试所有agent
$ yum install zabbix-get -y
$ zabbix_get -s 172.20.20.202 -p 10050 -k "net.tcp.service[http]"

# 调试本机
$ zabbix_agentd -t net.tcp.service[http]

7.2.2.2 部署 Proxy 端

安装MySQL

同 Server 端 安装方法

安装 Zabbix Proxy

rpm -i https://repo.zabbix.com/zabbix/4.0/rhel/7/x86_64/zabbix-release-4.0-1.el7.noarch.rpm
yum install -y zabbix-proxy zabbix-proxy-mysql

# 记得删除zabbix-proxy-pgsql
yum remove -y zabbix-proxy-pgsql-4.0.1-1.el7.x86_64

创建数据库

$ mysql -uroot -pgp9XDoGNohM7jwlB
MariaDB [(none)]> create database zabbix_proxy character set utf8 collate utf8_bin;
MariaDB [(none)]> grant all privileges on zabbix_proxy.* to zabbix@172.20.20.201 identified by 'm3O5utXSN^7j';
MariaDB [(none)]> grant all privileges on zabbix_proxy.* to zabbix@172.20.20.202 identified by 'm3O5utXSN^7j';
MariaDB [(none)]> grant all privileges on zabbix_proxy.* to zabbix@172.20.20.203 identified by 'm3O5utXSN^7j';

# 导入数据
$ cd /usr/share/doc/zabbix-proxy-mysql-4.0.1;gzip -d schema.sql.gz
$ mysql -uroot -pgp9XDoGNohM7jwlB zabbix_proxy < schema.sql

# 这一步可不要:因为proxy没有导入 data.sql,所以需要插入密码:zabbix12#$
MariaDB [(none)]>insert into users(userid,alias,surname,passwd,autologin,lang,refresh,type,theme,rows_per_page,name) values(1,"Admin","Administrator","73eb31de7a1f65e72b3a819853011344",1,"en_GB",30,3,"default",50,"Zabbix");

然后修改下proxy的配置(现在的配置已经生成)

Server=xxx.com               # server端的公网vip,或者域名
Hostname=xx.xx.xx.xx         # 和server端添加proxy_name一样

DBName=zabbix_proxy
DBUser=zabbix
DBPassword=xxxx

然后记得启动服务

$ systemctl start zabbix-proxy

一般我们不需要访问 zabbix-proxy 的前端,因为不需要配置什么,前端也展示不了什么数据。这里就不安装zabbix-web-mysql,也不配置httpd了。

在使用 Proxy 的时候,需要在 Server 端的web 界面上,先注册一下。

image2

7.2.2.3 部署 Agent 端

zabbix-agent 可以安装在所有需要被监控的机器上。

$ rpm -i https://repo.zabbix.com/zabbix/4.0/rhel/7/x86_64/zabbix-release-4.0-1.el7.noarch.rpm
$ yum install -y zabbix-agent

修改配置:/etc/zabbix/zabbix_agentd.conf

DebugLevel=1
EnableRemoteCommands=1       # 允许远程执行脚本
ListenIP=172.20.20.203       # 指定本机的ip
Server=172.20.20.201         # proxy 的ip,确认了不能是内网/公网vip
ServerActive=172.20.20.200   # proxy 的ip,用内网和公网vip都可以

# Hostname=ws_controller01     # 这个在proxy模式中没用,测试过可以不指定。

7.2.3 如何监控主机

在 zabbix 中,有几个概念,需要你在配置前要有所了解。

  • item :监控项,指的是你要监控什么指标;

  • template:模板,一系列item的集合;

  • trigger:触发器,指的是你监控的指标达到什么条件要触发告警事件;

  • host:监控主机,指的是你要监控哪个机器

  • action:动作,指的是你触发告警事件,你要让zabbix做些啥,常规的有发邮件,执行命令等

7.2.3.1 注册主机

要监控主机,当然首先要将机器注册到 Zabbix Server上,才能被管理。

你可以通过手动添加的方式来注册,但是这种方式太过去笨重,这里不推荐,我是使用自动注册的方式,只要机器上安装并正确了Zabbix Agent 就会发送心跳到 Proxy ,再转到Zabbix Server上,Server 上收到了后,我们可以自定义一系列动作(新增一个Host,然后将模板链接到该Host)

那么这一系列动作如何定义呢?

按照如下图点击,Event source注意选择Auto registration

image3

image4

7.2.3.2 配置监控项

一般情况下,我们的监控项,不会独立存在,而是依托于模板而存在。所以我们在创建监控项前,要首先创建一个模板。

image5

创建完模板后,点进模板的 items 按钮,正常情况下,这里会有很多监控项,但由于我们还没有创建,所以现在一个也没有。现在你可以自己点右上角(Create Item)自己创建一个,创建界面是这样的

image6

这里说一下,zabbix 自带有许多的模板,其实对于一些党规的监控项(说白了,就是zabbix给我们造好了轮子),这些模板已经足够了。这边只截了一小部分。

image7

如果以上这些不能满足你的需要,也没有关系,你也可以自己写脚本获取监控数据。

具体如何做呢,你需要自己定义一个 userparameter 的配置文件。这些文件统一要放在 agent 端的/etc/zabbix/zabbix_agentd.d 目录之下。

比如我为 OpenStack 相关的写了一个 userparameter_openstack.conf,其中一条内容是

UserParameter=openstack.service.status[*],sh /usr/lib/zabbix/externalscripts/isActive.sh $1

那我在 web 界面上配置 监控项,就可以这样写

image8

openstack-nova-api 是一个服务名,它将作为一个参数,传递给isActive.sh 这个脚本。

isActive.sh 就可以写我们的代码逻辑,服务如何监控服务是好的。只要我们在脚本里将不同的状态 输出就可以,比如,服务异常 print 1(echo 1),服务正常 print 0(echo 0)

更多内容,你可以通过官网来了解:https://www.zabbix.com/documentation/3.0/manual/config/items/userparameters

7.2.3.3 配置触发器

有了监控项后,我们的Zabbix Agent 会开始收集数据了,并上报给 Proxy,然后由Proxy上报Server。

你可以通过点击下图的操作,查看最近上报的数据(我这里选择value直接查看值,你可以选择Graph,按图表的形式查看)

image9

数据是这样的。

image10

7.2.3.4 配置动作

假如,我们要监控当 CPU 使用率超过90% 就发个通知邮件,那我们就要新增一个发邮件的动作。

image11

然后点击 Operations, 添加触发的动作类型,比如发邮件

image12

其中的HTML样式,也是我网上找来的,我觉得还挺不错,这里也贴出来

<table border=\"1\"  bordercolor=\"black\" cellspacing=\"0px\" cellpadding=\"4px\">
<tr >

<td>告警主机</td>
<td>{PROXY.DESCRIPTION} 节点:&nbsp;{HOSTNAME1}</td>
</tr>

<tr>
<td>告警时间</td>
<td>{EVENT.DATE} {EVENT.TIME}</td>
</tr>

<tr>
<td bgcolor=\"{$COLOR_DISASTER}\">告警等级</td>
<td bgcolor=\"{$COLOR_DISASTER}\">{TRIGGER.SEVERITY}</td>
</tr>

<tr >
<td>问题详情</td>
<td>{TRIGGER.DESCRIPTION}</td>
</tr>
<tr>
<td>处理方法</td>
<td>{ITEM.DESCRIPTION}</td>
</tr>

</table>

你有没有看到,旁边有个Recovery operation 按钮,它是说当我们的问题解决后,要让zabbix做些什么,比如我想让 当CPU的使用率降下来后,发一个邮件通知一下。

image13

邮件的 HTML 样式

<table border=\"1\"  bordercolor=\"black\" cellspacing=\"0px\" cellpadding=\"4px\">
<tr >

<td>主机信息</td>
<td>{PROXY.DESCRIPTION} 节点:&nbsp;{HOSTNAME1}</td>
</tr>

<tr>
<td bgcolor=\"{$COLOR_OK}\">告警等级</td>
<td bgcolor=\"{$COLOR_OK}\">Information</td>
</tr>

<tr >
<td>信息详情</td>
<td>问题已修复</td>
</tr>

<tr>
<td>修复时间</td>
<td>{DATE} &nbsp;{TIME}</td>
</tr>

<tr >
<td>原告警问题</td>
<td>{TRIGGER.DESCRIPTION}</td>
</tr>
</table>

上面邮件中,有设置了一些颜色的自定义宏,我是在这里设置的。

image14

上面的动作,都是写的发邮件,也可以远程执行脚本,比如,我们监控服务,当服务被人为关闭了,我们可以让Zabbix Agent执行重启服务的命令。

注意: 仅有 zabbix 4.0 和 3.4 的才支持远程执行命令。

道德要修改agent 的配置 /etc/zabbix/zabbix_agentd.conf ,让其允许远程执行命令

EnableRemoteCommands = 1

然后检查或创建该目录

mkdir -p /usr/local/zabbix-agent/scripts
chown -R zabbix:zabbix /usr/local/zabbix-agent/zabbix-agent

在 /etc/sudoers.d/ 新增文件:zabbix,让zabbix 可以获取root执行权限

# allows 'zabbix' user to run all commands without password.
Defaults:zabbix !requiretty
zabbix ALL=NOPASSWD: ALL

那在ACTION 里如何配置呢,看下图。你可以选择在 agent或者proxy,或者server执行都可以,非常灵活。

image15

7.2.3.5 配置发件人

Zabbix 要能发送邮件,需要配置邮箱发送方。这里以163邮箱为例(可自行调整)

vim /etc/mail.rc

image16

配置完成后,可用以下命令测试一下配置是否有效,若 yyy@163.com 能收到一条来自xxx@163.com 的邮件,则说明配置成功。

echo "zabbix test mail" |mail -s "zabbix" yyy@163.com

如果标题和正文有中文,发送的邮件可能会出现乱码或者正文会在outlook里会以 outlook 的形式展现。

为了解决这个问题,可以使用下面这个 sendmail.sh

#!/bin/bash
touch /tmp/mailtmp.txt
FILE=/tmp/mailtmp.txt
echo "$3" >$FILE
dos2unix -k $FILE
mailx -s "$2" "$1" < $FILE
rm -rf /tmp/mailtmp.txt

7.2.3.6 配置收件人

上面我们一直说发邮件,那发给谁呢?这个需要我们来配置一下。

先添加媒介:Administration - Media Types - Create media type

image17

上面用到 sendmail.sh 是一个脚本,需要我们来自己写,内容就是如何将我们的告警内容发送出去。

这个脚本可以接收参数(接收方,邮件标题,邮件内容),就是我们上处的 Script parameters。

按照zabbix的习惯,默认的告警脚本都存放在 /usr/lib/zabbix/alertscripts下(这个在/etc/zabbix/zabbix_server.conf中有配置)。

写好后,刻添加执行权限

cd /usr/lib/zabbix/alertscripts
chown zabbix:zabbix sendmail.sh
chmod +x sendmail.sh

然后再创建用户,并添加邮箱:Administration - Users - Admin - Media

image18

在创建用户的时候,要指定用户组,要注意这个用户组的权限一定要有相应主机组的权限,否则无法发送告警邮件。

image19

配置好收件人后 ,发件人呢?

发件人需要你在 Zabbix Server 所在的服务器上安装并正确配置好 smtp 服务器。

yum -y install sendmail
yum -y install mailx

systemctl enable sendmail
service postfix stop

具体你可以参考这篇文章:zabbix 服务器设置邮件报警

7.2.4 监控数据库

zabbix 自带 mysql 的监控模板,监控项不多,只有 14 项。

image20

这个模板在使用前,需要进行两个配置。

一个数据库的连接配置,一个是 userparameter_mysql.conf 的修改。

首先是数据的连接配置。

需要我们在 /etc/zabbix/ 目录下新建一个 .my.cnf 的文件(最好是隐藏文件),以下是模板,根据你的实际情况修改即可。

[mysql]
host=localhost
user=zabbix
password=<password>
port=<port>

[mysqladmin]
host=localhost
user=zabbix
password=<password>
port=<port>

其实这个.my.cnf文件 可以放在任何地方,只要你在 userparameter_mysql.conf 能够及时将配置文件路径修改过来就行。如下图所示,你只要修改下方 HOME 变量值。

image21

然后记得去 web界面在 该host主机上link到 Template DB MySQL 这个模板上。

最后,可以用 zabbix_agentd -t 'mysql.ping' 测试下,没有问题的话就可以重启下 zabbix-agent 服务了使之生效了。

7.2.5 关键问题记录

7.2.5.1 agent失联的问题

agent 失联的问题,使用默认的监控项会有不少问题。

为此我自己写了一个:

第一个条件:5分钟没有数据,第二个条件:上一次有数据

{$host:agent.ping.nodata(5m)}=1 and {$host:agent.ping.prev()}=1

7.2.5.2 库表占用情况

# 查询各监控项的占用情况
select items.name,history.count from (select itemid,count(itemid) as count from history_uint group by itemid) as history,items where items.itemid=history.itemid;

# 查询zabbix库表的占用情况
SELECT CONCAT(table_schema,'.',table_name) AS 'Table Name',
 CONCAT(ROUND(table_rows/1000000,4),'M') AS 'Number of Rows',
 CONCAT(ROUND(data_length/(1024*1024*1024),4),'G') AS 'Data Size',
 CONCAT(ROUND(index_length/(1024*1024*1024),4),'G') AS 'Index Size',
 CONCAT(ROUND((data_length+index_length)/(1024*1024*1024),4),'G') AS 'Total'
FROM information_schema.TABLES
WHERE table_schema LIKE '%zabbix%' ORDER BY Total desc;

以下物理计算,都是按 30 天的存量计算,磁盘占用除了数据本身存储之外,还有索引,其占用空间大概为数据本身的一半。

一条 uint 类型的数据 大概约占用 90 字节,实际监控除了 uint 之外还有 float ,log, text 等,所以计算存在一定的误差,需留有冗余,定为30%。

当前使用量(截止到 2019年4月11日:100个集群,1560个计算节点,300台控制节点,100台nfs),单位:G

select sum(total*ratio*90/1024/1024/1024 * 30 * 3/2 * 1.3) as sum from
(select host, sum(number) as total,
case host
    when 'OpenStack_Common' then 1960
    when 'OpenStack_Compute' then 1560
    when 'OpenStack_Controller' then 300
    when 'OpenStack_NFS' then 100
    else 0
end ratio
from
(select h2.host,h1.hostid, h1.ws_delay, h1.count, (86400/h1.ws_delay*h1.count) as number from
((select hostid,SUBSTRING_INDEX(delay,"s",1) as ws_delay,count(*) as count from items where hostid in (select hostid from hosts where name like '%OpenStack%')  group by hostid,delay) as h1
join
(select hostid,host from hosts where host like '%OpenStack%') as h2 on h1.hostid = h2.hostid)) as mytable2
group by host) as mytable3;

新增一个集群,会增加多少数据库负载,可以根据以下sql语句进行计算。

执行前,请先修改第一行 node 的值:新集群的计算节点数量,这里以10台为例

set @node := 10;

select sum(total*ratio*90/1024/1024/1024 * 30 * 3/2 * 1.3) as sum from
(select host, sum(number) as total,
case host
    when 'OpenStack_Common' then @node+4
    when 'OpenStack_Compute' then  @node
    when 'OpenStack_Controller' then 3
    when 'OpenStack_NFS' then 1
    else 0
end ratio
from
(select h2.host,h1.hostid, h1.ws_delay, h1.count, (86400/h1.ws_delay*h1.count) as number from
((select hostid,SUBSTRING_INDEX(delay,"s",1) as ws_delay,count(*) as count from items where hostid in (select hostid from hosts where name like '%OpenStack%')  group by hostid,delay) as h1
join
(select hostid,host from hosts where host like '%OpenStack%') as h2 on h1.hostid = h2.hostid)) as mytable2
group by host) as mytable3;

7.2.5.3 批量更新操作

# 批量修改数据保存天数
select count(*) from items where hostid in (select hostid from hosts where host like '%OpenStack%');

update items set history='30d' where hostid in (select hostid from hosts where host like '%OpenStack%');