别再说监控难搭了!手把手教你玩转Zabbix,从入门到放弃再到真香
之前有分享Beszel轻量监控,但是在使用过程中还是发现有些不足。多用户管理不方便,监控不够细致和灵活还有告警不支持钉钉!!!还是打算迁移到zabbix,顺便重温下zabbix!Zabbix这个老牌监控系统,虽然界面看起来有点"复古",但功能是真的强大。我记得刚开始用的时候还嫌弃它界面丑,现在用习惯了反而觉得挺顺手的,人就是这么奇怪。
为什么选择Zabbix
市面上监控系统那么多,Prometheus、Grafana、Nagios为啥偏偏选Zabbix?说白了就是因为它"傻瓜式"操作,而且免费。
Zabbix最大的优势就是开箱即用,安装完基本不用怎么配置就能跑起来。而且它的告警功能做得特别好,可以发邮件、短信,甚至还能调用API做一些自动化操作。
不过话说回来,Zabbix也不是完美的。界面确实有点老土,而且在处理大量数据时性能会有些吃力。但对于中小型企业来说,这些都不是问题。
文档地址:https://www.zabbix.com/documentation/current/zh/manual
安装
下载源码包,准备编译环境
[root@zabbixserver nginx-1.12.2]# yum install -y gcc pcre-devel openssl-devel
####安装nginx
##配置nginx支持https
[root@zabbixserver nginx-1.12.2]# ./configure --with-http_ssl_module
##编译安装
[root@zabbixserver nginx-1.12.2]# make && make install
###配置nginx支持php,配置php可以连接mysql
[root@web1 ~]# yum install -y php php-fpm php-mysql mariadb-server mariadb-devel
修改配置文件
[root@zabbixserver ~]# cat /usr/local/nginx/conf/nginx.conf
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
fastcgi_buffers 8 16k;
fastcgi_buffer_size 32k;
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
location ~ \.php$ {
root html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
include fastcgi.conf;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
# HTTPS server
#
#server {
# listen 443 ssl;
# server_name localhost;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
}
开启服务
[root@zabbixserver ~]# systemctl enable mariadb.service --now
Created symlink from /etc/systemd/system/multi-user.target.wants/mariadb.service to /usr/lib/systemd/system/mariadb.service.
###启动php
[root@zabbixserver ~]# systemctl enable php-fpm --now
Created symlink from /etc/systemd/system/multi-user.target.wants/php-fpm.service to /usr/lib/systemd/system/php-fpm.service.
###启动nginx
[root@zabbixserver ~]# /usr/local/nginx/sbin/nginx
[root@zabbixserver ~]# ss -antlp|grep "80"
LISTEN 0 128 *:80 *:* users:(("nginx",pid=14854,fd=6),("nginx",pid=14853,fd=6))
###设置开机自动启动
[root@zabbixserver ~]# echo '/usr/local/nginx/sbin/nginx' >> /etc/rc.d/rc.local
[root@zabbixserver ~]# chmod +x /etc/rc.d/rc.local
编译安装zabbix
###安装zabbixserver依赖包
[root@zabbixserver ~]# yum install -y net-snmp-devel curl-devel autoconf libevent-devel
###编译安装zabbix
[root@zabbixserver ~]# tar xf zabbix-3.4.4.tar.gz
[root@zabbixserver ~]# cd zabbix-3.4.4/
###生成安装配置文件
[root@zabbixserver zabbix-3.4.4]# ./configure --enable-server --enable-agent --with-mysql=/usr/bin/mysql_config --with-net-snmp --with-libcurl
##--enable-server 安装服务器端
##--enable-agent 安装被控端
##--with-mysql 指定mysql数据库配置程序
##--with-net-snmp 配置可以通过snmp收集数据
--with-libcurl 启用curl库,以便zabbix可以通过curl连接web服务
##--enable-proxy:启动proxy代理,不必安装
##
##make安装
[root@zabbixserver zabbix-3.4.4]# make && make install
创建存zabbix数据的数据库
[root@zabbixserver database]# mysql
###创建一个名为zabbix的数据库,
##default charset utf8 字符集utf-8
MariaDB [(none)]> create database zabbix default charset utf8;
##创建zabbix用户
MariaDB [(none)]> grant all on zabbix.* to zabbix@'%' identified by 'zabbix';
##本机ip加上访问权限
MariaDB [(none)]> grant all on zabbix.* to zabbix@'localhost' identified by 'zabbix';
##切换到zabbix数据库
MariaDB [(none)]> use zabbix;
#切换到mysql脚本目录
[root@zabbixserver mysql]# pwd
/root/zabbix-3.4.4/database/mysql
##执行zabbix创建数据库脚本,注意安装先后顺序
#执行schema.sql脚本
[root@zabbixserver mysql]# mysql -uzabbix -pzabbix zabbix< schema.sql
##执行images.sql脚本
[root@zabbixserver mysql]# mysql -uzabbix -pzabbix zabbix< images.sql
##执行data.sql脚本
[root@zabbixserver mysql]# mysql -uzabbix -pzabbix zabbix< data.sql
创建zabbix运行用户
##-s /sbin/nolog 设置不能登录
[root@zabbixserver zabbix-3.4.4]# useradd -s /sbin/nolog zabbix
启动zabbix服务器
[root@zabbixserver ~]# vim /usr/lib/systemd/system/zabbix_server.service
#####文件内容######
[Unit]
Description=zabbix server
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
PIDFile=/tmp/zabbix_server.pid
ExecStart=/usr/local/sbin/zabbix_server
ExecStop=/bin/kill ${MAINPID}
# We want systemd to give httpd some time to finish gracefully, but still want
# it to kill httpd after TimeoutStopSec if something went wrong during the
# graceful stop. Normally, Systemd sends SIGTERM signal right after the
# ExecStop, which would kill httpd. We are sending useless SIGCONT here to give
# httpd time to finish.
[Install]
WantedBy=multi-user.target
###############3
##重新加载systemct
[root@zabbixserver ~]# systemctl daemon-reload
##设置开机自启
[root@zabbixserver system]# systemctl enable zabbix_server.service
##启动
[root@zabbixserver system]# systemctl start zabbix_server.service
##查看服务状态
[root@zabbixserver system]# ss -tnlp|grep "10051"
配置agent,自己被监控
[root@zabbixserver system]# vim /usr/local/etc/zabbix_agentd.conf
配置被监控端server启动
##打开
[root@zabbixserver ~]# vim /usr/lib/systemd/system/zabbix_agentd.service
###########配置内容##########3
[Unit]
Description=zabbix agent
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
PIDFile=/tmp/zabbix_agentd.pid
ExecStart=/usr/local/sbin/zabbix_agentd
ExecStop=/bin/kill ${MAINPID}
# We want systemd to give httpd some time to finish gracefully, but still want
# it to kill httpd after TimeoutStopSec if something went wrong during the
# graceful stop. Normally, Systemd sends SIGTERM signal right after the
# ExecStop, which would kill httpd. We are sending useless SIGCONT here to give
# httpd time to finish.
[Install]
WantedBy=multi-user.target
####################################
##重新加载配置
[root@zabbixserver ~]# vim /usr/lib/systemd/system/zabbix_agentd.service
[root@zabbixserver ~]# systemctl enable zabbix_agentd.service
[root@zabbixserver ~]# systemctl start zabbix_agentd.service
[root@zabbixserver ~]# ss -tlnp|grep "10050"
LISTEN 0 128 *:10050 *:* users:(("zabbix_agentd",pid=1778,fd=4),("zabbix_agentd",pid=1777,fd=4),("zabbix_agentd",pid=1776,fd=4),("zabbix_agentd",pid=1775,fd=4),("zabbix_agentd",pid=1774,fd=4),("zabbix_agentd",pid=1773,fd=4))
Web界面配置
### 复制php web文件到nginx中的html目录,-r 递归复制,可复制文件夹,-f 强制覆盖,因为cp有别名,所以cp -rf还会有提示,需要绝对路径执行,注释别名
[root@zabbixserver ~]# /bin/cp -rf zabbix-3.4.4/frontends/php/* /usr/local/nginx/html/
##安装php,会自动创建apache账号
[root@zabbixserver ~]# id apache
uid=48(apache) gid=48(apache) 组=48(apache)
##修改所属组 权限
[root@zabbixserver ~]# chown -R apache:apache /usr/local/nginx/html/
###访问地址,打开安装页面
zabbix网页出现错误,需要修改php配置文件
需要做以下配置
[root@zabbixserver ~]# yum install -y php-gd php-xml php-bcmath php-mbstring
重启服务,页面正常
配置web1环境
上传zabbix源码包
配置编译安装环境
###配置编译安装环境
[root@web1 zabbix-3.4.4]# yum install -y gcc pcre-devel autoconf
###安装zabbix客户端
[root@web1 zabbix-3.4.4]# ./configure --enable-agent
####编译安装
[root@web1 zabbix-3.4.4]# make && make install
修改配置文件
##添加zabbix用户
[root@web1 zabbix-3.4.4]# useradd -s /sbin/nologin zabbix
###拷贝zabbix_agentd.service文件到被监控端
[root@zabbixserver ~]# scp /usr/lib/systemd/system/zabbix_agentd.service 192.168.4.100:/usr/lib/systemd/system/
#设置开机自启,并重启
[root@web1 zabbix-3.4.4]# systemctl enable zabbix_agentd.service --now
Created symlink from /etc/systemd/system/multi-user.target.wants/zabbix_agentd.service to /usr/lib/systemd/system/zabbix_agentd.service.
##检查是否运行成功
[root@web1 zabbix-3.4.4]# ss -tlnp|grep "10050"
LISTEN 0 128 *:10050 *:* users:(("zabbix_agentd",pid=9003,fd=4),("zabbix_agentd",pid=9002,fd=4),("zabbix_agentd",pid=9001,fd=4),("zabbix_agentd",pid=9000,fd=4),("zabbix_agentd",pid=8999,fd=4),("zabbix_agentd",pid=8998,fd=4),("zabbix_agentd",pid=8997,fd=4))
在zabbix web管理平台中配置监控
- 主机:安装了agent,被监控的主机
- 主机组:根据需求,将多台主机加入到一个主机组中,方便管理。系统默认已经创建了一些主机组。
- 模板:是监控项的集合。将模板应用到主机,主机就可以直接拥有模板中的所有监控项。系统中默认已经创建了一些模板
添加被监控的主机
常用的监控指标:
- CPU idle time:CPU空闲时间。不宜过低。
- Processor load(1 min average per core) / Processor load(5 min average per core) / Processor load(15 min average per core):每核心1分钟、5分钟、15分钟的平均负载。这个值不应长期大于1。
- Free disk sapce on /:根分区剩余的空间
- Free disk sapce on /(percentage):根分区剩余的空间百分比
- Available memory:可用内存
- Incoming network traffic on eth0:eth0网卡进入的流量
- Outgoing network traffic on eth0:eth0网卡外出的流量
- Maximum number of processes:系统最多运行的进程数
- Number of logged in users:已登陆的用户数
实现监控web1用户数量的监控项
- 在被控端创建key。被控端被监控的内容叫作key,可以理解为它就是一个变量名,具体的名字自己决定。
- 在web页面中创建监控项。监控项对应key值。
- 监控项存在应用集中。应用集就是相似监控项的集合。
- 应用集存在模板中。一个模板可以包含多个应用集。\
在被控端创建key
UserParameter=自定义key值,命令
# 命令的执行结果,是key的value
#####配置文件
###vim 后面+264 是直接跳到264
[root@zabbixserver ~]# vim +264 /usr/local/etc/zabbix_agentd.conf
###创建文件
[root@zabbixserver ~]# vim /usr/local/etc/zabbix_agentd.conf.d/conunt.line.passwd
###在文件中写入这一行
UserParameter=count.line.passwd,sed -n '$=' /etc/passwd
###改完重启服务
[root@web1 ~]# systemctl restart zabbix_agentd.service
###
###在被控端验证服务是否能正常获取数据
[root@web1 ~]# zabbix_get -s 127.0.0.1 -k count.line.passwd
22
###在监控端验证服务是否能正常获取数据
[root@zabbixserver ~]# zabbix_get -s 192.168.4.100 -k count.line.passwd
22
配置告警
- 默认情况下,监控项不会自动发送告警消息
- 需要配置触发器与告警,并且通过通知方式发送信息给联系人
- 触发器:设置条件,当条件达到时,将会执行某个动作
- 动作:触发器条件达到之后要采取的行为,比如发邮件或执行命令
用户超过35时,发送告警邮件
- 当web1的用户数超过35时,认为这是一个问题(Problem)
- 当出现问题时,将会执行动作。
- 执行的动作是给管理员发邮件。
- 给管理员发邮件,还要配置邮件服务器的地址,以及管理员的email地址
实施
配置-->模板-->触发器
表达式语法:
{<server>:<key>.<function>(<parameter>)}<operator><constant>
{<主机>:<key>.<函数>(<参数>)}<操作符><常量>
{count.line.passwd:count.line.passwd.last()}>35
# count.line.passwd是模板
# count.line.passwd是在被控端上定义的key
# last是函数,表示最近的一次取值
# > 是操作符
# 35 是常量
# 以上表达式的含义是:应用count.line.passwd模板的主机,它的count.line.passwd最近一次取值大于35,则状态为“问题”,即Problem
配置邮箱告警
模板的使用
Zabbix最强大的地方就是模板系统。官方提供了很多现成的模板,基本覆盖了常见的监控需求。
给主机关联模板很简单,编辑主机配置,在Templates标签页搜索并添加需要的模板。比如Linux主机可以添加"Linux by Zabbix agent"模板。
这个模板包含了CPU、内存、磁盘、网络等基础监控项,还有相应的触发器。添加后等几分钟就能看到监控数据了。
我记得第一次看到那些花花绿绿的图表时还挺兴奋的,感觉自己瞬间变成了运维大神。不过后来发现,看图表容易,分析问题才是真功夫。
自定义监控项
虽然模板很方便,但有时候还是需要自定义一些监控项。比如监控某个特定的进程或者自定义的脚本输出。
创建监控项的步骤:
- 进入Configuration -> Hosts
- 点击主机名进入详情
- 点击Items标签页
- 点击"Create item"
关键参数说明:
- Name: 监控项名称
- Type: 监控类型,常用的有Zabbix agent、SNMP、SSH等
- Key: 监控项的键值,这个很重要
- Type of information: 数据类型
- Update interval: 更新间隔
举个例子,监控系统负载:
Name: System load 1 minute
Type: Zabbix agent
Key: system.cpu.load[all,avg1]
Type of information: Numeric (float)
Update interval: 1m
Key是Zabbix预定义的,文档里有完整列表。也可以自定义Key,但需要在agent配置文件中定义相应的脚本。
分布式监控架构
如果监控的主机比较多,单台Zabbix server可能扛不住。这时候就需要用到Zabbix proxy了。
Proxy相当于一个中转站,负责收集一部分主机的数据,然后统一上报给Zabbix server。这样可以减轻server的压力,也能解决网络隔离的问题。
安装Proxy的步骤和Server类似,只是配置文件不同:
yum install -y zabbix-proxy-mysql
配置文件 /etc/zabbix/zabbix_proxy.conf
主要参数:
Server=zabbix-server-ip
Hostname=zabbix-proxy-01
DBHost=localhost
DBName=zabbix_proxy
DBUser=zabbix
DBPassword=password
Proxy需要单独的数据库,但不需要导入完整的数据结构:
zcat /usr/share/doc/zabbix-sql-scripts/mysql/proxy.sql.gz | mysql -uzabbix -p zabbix_proxy
在Zabbix server的Web界面添加proxy:Administration -> Proxies -> Create proxy。
然后在配置主机时选择对应的proxy就行了。
我之前在一个项目中用过这种架构,总共监控了200多台服务器,分布在3个机房。每个机房部署一个proxy,效果还不错。
常见问题排查
用Zabbix这么久,踩过的坑也不少。分享几个常见问题的解决方法:
Agent连接不上
这个最常见,一般是防火墙或者配置问题。先检查agent是否正常运行:
systemctl status zabbix-agent
然后检查端口是否监听:
netstat -tlnp | grep 10050
如果都正常,就检查防火墙设置。还有就是确认agent配置文件中的Server参数是否正确。
监控项变成不支持状态
这种情况通常是Key写错了,或者agent版本不支持某个Key。可以在agent主机上手动测试:
zabbix_get -s 127.0.0.1 -k system.cpu.load
如果返回错误信息,就知道问题出在哪了。
数据库连接失败
检查数据库服务是否正常,用户权限是否正确。还有就是确认配置文件中的数据库连接参数。
Web界面访问慢
通常是数据库查询慢导致的,可以开启慢查询日志分析一下。或者检查是否有大量历史数据没有清理。
高级功能探索
Zabbix还有一些高级功能,虽然平时用得不多,但关键时刻很有用。
网络发现
可以自动发现网络中的设备并添加监控。配置起来有点复杂,但对于大规模环境很有用。进入Configuration -> Discovery,创建发现规则。
低级发现
这个功能很强大,可以自动发现文件系统、网络接口等。比如自动监控所有挂载点的磁盘使用率,不用手动一个个添加。
Web监控
可以监控网站的可用性和响应时间,支持复杂的场景,比如模拟用户登录流程。
SNMP监控
对于网络设备监控很有用,交换机、路由器基本都支持SNMP。配置相对简单,主要是MIB的理解需要一些网络基础。
与其他工具的集成
现在很少有系统是完全独立的,Zabbix也需要和其他工具配合使用。
和Grafana集成
虽然Zabbix自带图形功能,但Grafana的展示效果确实更好。可以通过Zabbix插件让Grafana读取Zabbix的数据。
和自动化工具集成
可以通过Zabbix的API实现和Ansible、Puppet等工具的集成。比如发现问题后自动执行修复脚本。
和日志系统集成
虽然Zabbix不是专门的日志分析工具,但可以监控日志文件中的关键字。配合ELK这样的日志系统使用效果更好。
安全考虑
监控系统本身也需要考虑安全问题,毕竟它能看到整个基础设施的状态。
首先是访问控制,Zabbix支持用户组和权限管理。不同的人员应该只能看到相关的监控数据。
然后是网络安全,agent和server之间的通信可以配置加密。虽然会有一些性能损失,但在安全要求高的环境中是必要的。
还有就是定期更新,Zabbix的安全补丁还是比较及时的。我一般会关注官方的安全公告,有重要更新就及时升级。
数据库安全也很重要,不要用默认密码,定期备份数据。我见过有公司的监控数据被删了,几个月的历史数据全没了,那叫一个惨。
实际应用案例
说了这么多理论,来个实际案例。我之前负责一个电商网站的监控,大概50台服务器,包括Web服务器、数据库、缓存、消息队列等。
监控架构是这样的:
- 1台Zabbix server,配置比较高
- 2台Proxy,分别负责不同机房
- 所有服务器安装agent
重点监控项目:
- 基础资源:CPU、内存、磁盘、网络
- 应用服务:Nginx、PHP-FPM、MySQL、Redis
- 业务指标:订单量、支付成功率、页面响应时间
告警策略比较严格,CPU超过80%就告警,内存超过85%告警。磁盘空间低于20%就发短信,低于10%直接打电话。
效果还不错,基本能在问题影响用户之前发现并解决。有一次数据库主从同步出问题,通过监控及时发现,避免了数据不一致的问题。
当然也有翻车的时候,有次配置触发器时写错了表达式,结果半夜疯狂发告警短信,把整个技术团队都吵醒了。第二天被骂得狗血淋头,从此配置告警都格外小心。
如果这篇文章对你有帮助,别忘了点赞转发支持一下!想了解更多运维实战经验和技术干货,记得关注微信公众号@运维躬行录,领取学习大礼包!!!我会持续分享更多接地气的运维知识和踩坑经验。让我们一起在运维这条路上互相学习,共同进步!
公众号:运维躬行录
个人博客:躬行笔记