☰
Zabbix 4.0在CentOS 7上源码编译安装全流程实战
2026/10/17 3:28:02 网站建设 项目流程

做监控这么些年,我很少上来就劝人源码安装,大多数场景下 yum 装个 rpm 包确实更快。但如果你也遇到过这几类环境:内网不通外网源、公司要求软件统一装到指定路径、需要在编译时把 SNMP、curl 这些能力按需编进二进制,那 Zabbix 4.0 的源码编译就绕不过去了。这篇记录以 CentOS 7 作为基础系统,完整走一遍 zabbix-4.0 从依赖准备、Server 编译、数据库初始化、Web 前端到 Agent 接入的流程,同时把那些只有动手编译过才看得见的坑都写出来,给要走离线交付或者想搞懂 Zabbix 底层结构的同行做个参考。

1. 为什么我坚持源码编译 Zabbix 4.0 而不是直接拉 yum 包

1.1 不是所有环境都适合 rpm 安装

很多人觉得 CentOS 7 上用 yum 装 Zabbix 是标准答案,官方确实维护了对应的 rpm 源,装上就能用。但在实际交付里,我碰到过几次必须源码编译的情况。

第一类是离线环境。某内网机群完全和外网隔离,yum 源要么没有,要么只能用内部镜像仓库,而内部仓库里不一定有官方 zabbix rpm 包。这时候手里一份源码包加一堆依赖库的 rpm,反而最可控。

第二类是目录和模块管控要求。源码编译可以用--prefix把 Zabbix 统一装进/usr/local/zabbix,后续升级、备份、迁移都只操作一个目录;而 rpm 安装会按照发行版的 FHS 把文件拆到/etc、/usr/sbin、/var/log多个位置,在安全审计比较严格的项目里,这种路径分散经常让交付很难受。

第三类才是最关键的原因:编译选项的灵活性。configure阶段可以自由组合 MySQL、PostgreSQL、SNMP、SSH 等支持,不需要的模块直接不编入二进制,既能减小体积,也能降低被外部攻击面覆盖的概率。相比之下,rpm 包是别人编好的,里面打包了哪些特性、链接了哪些依赖,你只能接受现状。

1.2 Zabbix 4.0 组件拆解与目录规划

Zabbix 4.0 在这个版本里,核心组件分得非常清楚:Zabbix Server 负责采集调度、历史数据存储和告警触发;Zabbix Agent 部署在被监控主机上采集指标;还有一个可选的 Zabbix Proxy,一般在跨机房的分层环境里才会用到。这次咱们一次性把 Server 和 Agent 都编出来,Proxy 先不碰。

目录规划我是这样做的:Server 和 Agent 使用同一套源码包,但为了防止以后客户端单独升级影响服务端,我给它们分配了不同的前缀,Server 装到/usr/local/zabbix,Agent 单独装到/usr/local/zabbix-agent。Web 前端是纯 PHP 代码,不跟编译产物混在一起,我习惯放到/var/www/zabbix,这样前端升级时不会动到二进制。

日志目录统一用/var/log/zabbix,服务运行账号单独建一个不能登录的zabbix用户。别图省事直接用 root 跑 Zabbix,一旦 web 被人传了个 webshell,root 权限的监控进程就是提权跳板。

组件安装位置说明
Zabbix Server 二进制/usr/local/zabbix/sbin/zabbix_serverconfigure 时 --prefix 决定
Zabbix Agent 二进制/usr/local/zabbix-agent/sbin/zabbix_agentd单独前缀方便独立升级
Server 配置/usr/local/zabbix/etc/zabbix_server.conf源码安装默认配置目录
Web 前端/var/www/zabbix拷贝源码里的 frontends/php
日志/var/log/zabbix预先创建并授权给 zabbix 用户

2. 编译依赖准备:先把这些装齐,configure 才不会半路报错

2.1 一次装齐 Server 端依赖链

源码编译最烦的不是 make,而是 configure 检查依赖时告诉你缺这个库缺那个头文件。我建议在 configure 之前就把编译链和核心开发包一次性装齐,省得来回折腾。

yum install -y gcc gcc-c++ make autoconf automake libtool yum install -y pcre-devel libxml2-devel libcurl-devel net-snmp-devel openssl-devel libevent-devel mariadb-devel

这些包不是拍脑袋装的,每一个都对应 configure 里的一个--with-选项。比如你要用 MySQL 作为后端数据库,就需要 mariadb-devel 提供 MySQL 客户端库和头文件;要支持 SNMP 监控网络设备,就需要 net-snmp-devel;要让 Web 监控里的 HTTP 请求能正常发出,需要 libcurl-devel;要解析 XML 类型的数据,需要 libxml2-devel。

如果你只编译 Agent,那依赖会少很多,通常只需要 pcre-devel。所以被监控机器上的依赖准备比 Server 端简单得多。这里也提醒一下,如果确认系统里已经装了 MySQL 而装了 mariadb-devel,二者偶尔会有头文件冲突,但 CentOS 7 默认源里的 MySQL 服务基本就是 MariaDB,所以直接用 mariadb-devel 不会出问题。

2.2 PHP 和 Web 前端环境准备

Zabbix 4.0 的前端不参与 C 编译,但它对 PHP 扩展有硬性要求,所以 web 环境要在向导之前搭好。CentOS 7 自带源里的 PHP 是 5.4 版本,Zabbix 4.0 官方是支持这个版本的,不需要为了前端非要去装 PHP 7。

yum install -y nginx php php-fpm php-mysqlnd php-gd php-bcmath php-mbstring php-xml

扩展对应关系很多人容易搞混:php-bcmath对应前端检查里的 bc math 选项,php-mbstring对应 mbstring,php-gd对应绘图功能,php-mysqlnd负责连接数据库。安装完之后顺手检查一下扩展加载情况:

php -m | grep -E 'gd|bcmath|ctype|curl|mbstring|mysqli|pcre|xml'

如果缺了某一个,先确认是不是 php 子包没装全。我见过不少人在向导页卡在某个扩展上,最后发现只是少装了一个php-xml,问题解决只需要一条 yum 命令。

2.3 运行用户、日志目录与安装目录规划

编译安装前,先把运行账号和目录建好。Zabbix 源码安装包里不会自动创建/var/log/zabbix,也不会替你建运行用户,这些前置工作漏了,后面服务根本起不来。

useradd -s /sbin/nologin zabbix mkdir -p /var/log/zabbix /var/www chown -R zabbix:zabbix /var/log/zabbix

这里我刻意让 PHP-FPM 和 Nginx 用各自默认的运行用户,而 Zabbix Server 用 zabbix 用户运行。web 目录/var/www/zabbix的属主后面拷贝前端文件时再处理,现在不用管。总之提前想清楚目录归属,比启动时权限报错再去排查舒服得多。

3. Server 编译安装:configure 到 make install 的具体操作

3.1 configure 参数逐个说明

解压 zabbix-4.0 源码后,进入目录,核心 configure 命令长这样:

./configure --prefix=/usr/local/zabbix \ --enable-server \ --enable-agent \ --with-mysql \ --enable-net-snmp \ --with-libcurl \ --with-libxml2 \ --with-openssl

一个个来说。--prefix是安装前缀,我不建议用默认的/usr/local,因为默认值会让 Zabbix 的二进制、配置和 sbin 散落在系统目录里,升级时不好识别。--enable-server编译 Zabbix Server,--enable-agent顺带把 Agent 也编出来,这样源码包一次搞定两端安装。--with-mysql是让 Server 使用 MySQL/MariaDB 客户端库,这里虽然指明了数据库类型,但只是让 zabbix_server 在运行时能通过 libmysqlclient 去连数据库,服务器本机不一定要装 MySQL 服务端。--enable-net-snmp对应 SNMP 监控,--with-libcurl和--with-libxml2分别为 HTTP 采集和 XML 解析提供支持,--with-openssl开启加密通信支持。

configure 跑完以后,末尾的 Summary 里会显示Server: yes、Agent: yes、Database: MySQL这些关键信息。如果你的环境还用到 SSH 远程监控或 LDAP 认证,可以再加--with-ssh2或--with-ldap,但前提是装好对应的开发包。我不建议把所有选项全部打开,依赖越多,编译和后续升级的潜在问题越多,按实际需求来即可。

3.2 make 过程中的常见失败原因

configure 通过以后,进入编译环节:

make -j4 make install

-j4表示用 4 个线程并行编译,具体数字看 CPU 核数,但不要盲目拉满,否则内存小的机器在链接阶段会直接 OOM。make 如果报错,绝大多数情况都是缺头文件,比如提示找不到mysql.h,就是 mariadb-devel 没装;提示找不到pcre.h,就是 pcre-devel 没装。这类问题在 configure 阶段其实已经暴露过一次,所以我在前面才会强调先把依赖装齐。

parallel 编译还有个不起眼的小坑:如果某一次 make 失败,你修好依赖后可以直接再次 make,一般能续上;但如果是源码目录被拷贝迁移过,配置缓存可能还是旧的,稳妥做法是make distclean清掉生成物,再重新 configure 一遍。

3.3 编译产物确认

make install 跑完,先别急着配置,确认一下产物是否完整:

ls -l /usr/local/zabbix/sbin/ /usr/local/zabbix/sbin/zabbix_server --version

正常情况下/usr/local/zabbix/sbin下会有zabbix_server和zabbix_agentd,etc 目录下会有zabbix_server.conf、zabbix_agentd.conf。如果这些文件都在,说明 Server 端的编译安装已经成功,接下来可以处理数据库了。

4. 数据库初始化:顺序、字符集与权限一个都不能错

4.1 建库、建用户和授权

Zabbix Server 的核心数据全部落在数据库里,所以数据库初始化是决定服务能否启动的关键步骤。在 MySQL/MariaDB 里先建一个独立的 zabbix 库:

CREATE DATABASE zabbix CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; CREATE USER 'zabbix'@'localhost' IDENTIFIED BY 'your_password'; GRANT ALL PRIVILEGES ON zabbix.* TO 'zabbix'@'localhost'; FLUSH PRIVILEGES;

字符集这里我直接用了 utf8mb4,比 utf8 多支持了 4 字节的字符,能避免以后写入 emoji 或生僻字时爆出Incorrect string value。排序规则选择 utf8mb4_general_ci 就够用,不需要追求高精度排序功能。

账号授权这里有个很多人踩过但没有意识到的问题:如果后续 zabbix_server.conf 里 DBHost 写的是127.0.0.1,而这里只创建了'zabbix'@'localhost'账号,Server 连接数据库时可能会因为账号 host 不匹配被拒绝。稳妥做法是同时创建 localhost 和 127.0.0.1 两个 host 的账号,或者统一用 localhost + socket 方式连接。真到服务启动时再发现连不上库,排查成本远高于一开始多建一个账号。

4.2 按照 schema -> images -> data 顺序导入

Zabbix 源码包里自带数据库初始化文件,在database/mysql/目录下,分别是 schema.sql、images.sql 和 data.sql。这三个文件有严格的导入顺序,千万不要乱。

mysql -uzabbix -p zabbix < database/mysql/schema.sql mysql -uzabbix -p zabbix < database/mysql/images.sql mysql -uzabbix -p zabbix < database/mysql/data.sql

schema.sql 是核心表结构,没有它后面两个文件就是无根之木;images.sql 装的是前端用到的图片数据;data.sql 灌入的是默认配置、模板和媒体类型等初始数据。顺序颠倒的话,最常见的报错就是Table 'xxx' doesn't exist。另外,导入时如果库是 utf8mb4,而 SQL 文件里某些地方指定了旧的 latin1 或 utf8 字符集,MySQL 有可能报Illegal mix of collations。遇到这种错误,就在 mysql 命令后面加--default-character-set=utf8mb4,保证客户端和库的字符集一致。

这三个文件体积不算小,尤其 data.sql 有几 MB,导入时不要像我第一次那样在终端里等半天还以为是卡死了,它在慢慢执行很正常。

4.3 导入后如何验证

数据导完,用几条 SQL 快速验证一下:

SHOW TABLES; SELECT COUNT(*) FROM users; SELECT COUNT(*) FROM hosts;

users 表里应该有初始的 Admin 用户,hosts 表里虽然现在没有实际主机,但会有模板关联的初始数据条目。如果 users 是空的,说明导入过程有问题,重新按顺序导一遍即可。确认无误后,数据库这一层的准备工作就算闭环了。

5. 服务配置与 systemd 托管:让 zabbix_server 稳定跑起来

5.1 zabbix_server.conf 关键项

编辑/usr/local/zabbix/etc/zabbix_server.conf,先把最核心的配置写上:

LogFile=/var/log/zabbix/zabbix_server.log PidFile=/var/run/zabbix/zabbix_server.pid DBName=zabbix DBUser=zabbix DBPassword=your_password DBHost=localhost DBPort=3306 ListenPort=10051 CacheSize=128M Timeout=4

LogFile 告诉 Server 日志写到哪里,PidFile 记录主进程 PID,这两个路径对应的目录必须存在且属主是 zabbix 用户,否则启动阶段就会报cannot create PID file。DBName、DBUser、DBPassword 要和第 4 章建库时的账号一致,DBHost 这里如果用 localhost,就对应数据库账号 host 为 localhost 的情况。CacheSize 是内存中的监控缓存大小,监控项少的时候默认值够用,但接入几百台主机后很容易出现 cache 不足的 warning,生产环境我一般直接调到 128M。Timeout 是采集超时时间,默认 4 秒对于大多数场景够用,如果有些业务接口响应慢,可以适当调大。

5.2 systemd 单元文件要注意 Type 和 PIDFile

源码安装不像 rpm 包那样自动注册 systemd 服务,需要自己写单元文件。这是一个很典型又容易忽视的坑:zabbix_server 启动后会 fork 出一个后台进程继续运行,所以Type必须写成forking,systemd 才会认为服务成功启动,同时 PIDFile 必须和 conf 里配置的路径完全一致。

[Unit] Description=Zabbix Server After=network.target mysqld.service [Service] User=zabbix Group=zabbix Type=forking PIDFile=/var/run/zabbix/zabbix_server.pid ExecStart=/usr/local/zabbix/sbin/zabbix_server -c /usr/local/zabbix/etc/zabbix_server.conf ExecStop=/bin/kill -SIGTERM $MAINPID Restart=on-failure [Install] WantedBy=multi-user.target

如果 PIDFile 的路径写错,systemd 会一直报Unit zabbix-server.service entered failed state,但你看 zabbix_server 的进程其实已经起来了,这种状态非常迷惑人。所以写完 unit 文件后先执行:

systemctl daemon-reload systemctl enable --now zabbix-server systemctl status zabbix-server

看到active (running)才算真正起来。

5.3 首次启动日志解读与防火墙放行

如果服务没有正常启动,第一时间看日志/var/log/zabbix/zabbix_server.log。常见的报错类型就几种:database is down说明连不上数据库,检查账号密码和 DBHost;cannot open /var/run/zabbix/...说明目录权限不对;No configuration file这种通常是指定了错误的-c路径。

服务起来之后,监听端口也要确认:

ss -lntp | grep 10051

Zabbix Server 默认监听 10051 端口,Agent 是 10050,Web 是 80。CentOS 7 默认开了 firewalld,需要把这些端口放出去:

firewall-cmd --permanent --add-port=10050/tcp --add-port=10051/tcp firewall-cmd --permanent --add-service=http firewall-cmd --reload

我在实际交付中见过不少案例:server 明明起来了,agent 数据也采集了,前端就是显示不了图形,最后发现是防火墙挡了 web 端口。监控系统本身的端口被防火墙掐住,说起来有点讽刺,但确实高发。

6. Web 前端接入:文件拷贝、Nginx 和安装向导

6.1 前端文件部署与权限

Zabbix 源码包里已经带了完整的 PHP 前端,路径是frontends/php,不需要单独下载。把它整个拷贝到规划好的 web 目录:

mkdir -p /var/www/zabbix cp -a /path/to/zabbix-4.0/frontends/php/* /var/www/zabbix/ chown -R nginx:nginx /var/www/zabbix

此时要注意 web 目录属主问题。如果 nginx 和 php-fpm 用的是 nginx 用户,那就把目录属主设为 nginx;如果 php-fpm 是单独的用户,则要保证 php-fpm 进程能读这些文件,否则打开首页会直接 403。

6.2 php-fpm 配置与 Nginx 站点

我在这里用 Nginx 加 PHP-FPM 的组合,比 Apache 轻一些。在/etc/nginx/conf.d/下建一个 zabbix 站点配置:

server { listen 80; server_name zabbix.example.local; root /var/www/zabbix; index index.php; location / { try_files $uri $uri/ =404; } location ~ \.php$ { fastcgi_pass unix:/run/php-fpm/www.sock; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; } }

这个配置里最容易踩坑的是fastcgi_pass后面的 socket 路径。CentOS 7 上 php-fpm 的 default pool 默认监听unix:/run/php-fpm/www.sock,但如果你改了 php-fpm.conf,路径可能就变了。路径对不上,访问 PHP 页面就会 502。遇到 502 先ls -l /run/php-fpm/看看 socket 到底在哪,再回头改 Nginx 配置。

PHP-FPM 自身的参数也需要调一下,编辑/etc/php.ini:

date.timezone = Asia/Shanghai max_execution_time = 300 post_max_size = 16M max_input_time = 300 memory_limit = 128M

date.timezone如果不设置,Zabbix 前端检查页会直接报时区错误;另外几个参数不达标,也会在向导页里红字提醒。改完systemctl restart php-fpm nginx。

6.3 向导参数与常见拦截点

浏览器打开http://你的IP/进入前端目录,会自动跳转到安装向导。整个向导流程大概四步:选择语言、检查 PHP 环境、配置数据库连接、配置 Zabbix Server 地址。

数据库连接信息要和 zabbix_server.conf 保持一致,Zabbix Server 地址和端口默认就是localhost:10051,如果 server 和 web 部署在同一台机器,保持默认即可。

向导最后一步会把配置写入/var/www/zabbix/conf/zabbix.conf.php,如果 web 目录属主不对或者 conf 目录没有写权限,这里会卡住。写进去之后,整个前端安装完成。默认管理员账号是 Admin,密码 zabbix,登录后第一件事是改密码,这不是废话——默认口令放到公门下等于没锁门。

7. Agent 编译安装与第一台主机接入

7.1 只编译 Agent 的轻量做法

Server 编译时用了--enable-agent,所以服务端这台机器上已经有一个 Agent 二进制了。但被监控的其他主机不需要跑 Server,单独编译一个轻量 Agent 更合适:

./configure --prefix=/usr/local/zabbix-agent --enable-agent make && make install

Agent 的依赖要少得多,configure 阶段只要 pcre-devel 在就行。安装完成后,配置文件在/usr/local/zabbix-agent/etc/zabbix_agentd.conf,核心参数如下:

Server=192.168.1.10 ServerActive=192.168.1.10 Hostname=web01 ListenPort=10050

Server表示只接受来自这个 IP 的被动查询,ServerActive表示 Agent 主动向这个地址建立连接上报数据,Hostname是 Agent 自己上报的主机名。这三个参数如果配置不一致,往往会出现主机出现在前端但一直无数据。

7.2 agent 主动/被动模式的关键区别

被动模式下,Zabbix Server 直接连 Agent 的 10050 端口取数据,这个前提是网络能打通,并且 Server 的 IP 在 Agent 配置的Server列表里。主动模式下,Agent 自己去连 Server 的 10051 端口上报数据,Server 端只需要允许端口放行即可,天然适合大量 Agent 到单一 Server 的场景。

需要特别强调:主动模式下Hostname必须和 Web 前端创建的主机名完全一致,否则 Server 收到数据后找不到对应主机,日志里会持续出现类似no host for hostname的报错。这个字符匹配问题是主动模式里最常见的故障点,没有之一。

Agent 启动同样可以用 systemd 管理,unit 文件参照 Server 那套写,PIDFile指向/var/run/zabbix/zabbix_agentd.pid,启动命令换成/usr/local/zabbix-agent/sbin/zabbix_agentd -c /usr/local/zabbix-agent/etc/zabbix_agentd.conf。

启动后检查端口:

ss -lntp | grep 10050

然后再到 Server 一侧用 zabbix_get 测一下连通性:

/usr/local/zabbix/bin/zabbix_get -s 192.168.1.20 -k system.uptime

能返回数值,说明 agent 到 server 的链路已经通了。

7.3 在 Web 前端创建主机

登录 Zabbix Web 界面,进入 Configuration -> Hosts -> Create host。主机名称要和 Agent 配置里的 Hostname 保持一致,填 Agent 的 IP,端口默认 10050,然后链一个模板,比如 Linux by Zabbix agent。

保存后等一两分钟,回到 Monitoring -> Hosts 里看主机状态,如果数据开始有图形,说明整个采集链路已经打通。如果状态一直显示Unreachable,优先查防火墙和代理进程;如果显示ZBX NOT SUPPORTED,重点查 Agent 版本是否和 Server 兼容,以及 key 有没有写错。Zabbix 4.0 这个版本对 agent 版本匹配比较敏感,服务端和客户端尽量都用同一个版本源码编译,能省掉一堆莫名其妙的问题。

8. 持续运行中的问题排查与几点维护建议

8.1 日志与状态检查三板斧

监控系统上线只是开始,真正花精力的是后续排查。我总结了三个最实用的检查手段。

第一看日志。Zabbix Server 日志在/var/log/zabbix/zabbix_server.log,Agent 端如果有问题要看被监控主机上的zabbix_agentd.log。日志里出现 warning 不要慌,先看是内存缓存不足还是 DB 连接抖动,按提示调整配置即可。

第二看端口。ss -lntp | grep 10051确认 Server 在听,ss -lntp | grep 10050确认 Agent 在听。很多看起来复杂的问题,最后都只是 agent 进程挂了或者防火墙没放行。

第三看前端状态。Web 界面里主机状态是最直观的入口,黄变红大概率是网络不可达,红变灰大概率是数据没有更新,结合日志定位就能把范围缩小很多。

8.2 生产环境维护建议

源码安装方式让我对二进制的构成有完全的控制,但代价是升级和备份都得手动做。数据库是 Zabbix 最核心的数据资产,建议每天 mysqldump 备份一次 zabbix 库,同时把/usr/local/zabbix/etc下的配置文件纳入版本管理。小版本升级时,编译完新版本替换 sbin 下的二进制重新启动即可;大版本升级必须认真阅读官方升级说明中的数据库变更步骤,直接跳版本升级很容易造成 schema 不兼容。

另外再分享一个运维中积累的小技巧:在 agent 配置里追加UserParameter=custom.check,echo ok这样的自定义键,可以通过 agent 的 10050 端口执行任意脚本。这个能力扩展性非常高,比如监控业务接口返回码、检查本地磁盘上的特殊文件、调用自定义脚本做故障自愈。但注意自定义键对应脚本的权限一定要严格控制,因为 agent 进程的权限直接影响脚本执行权限,这个入口如果被滥用,等于给了外部一个远程执行点。

从依赖准备到第一台主机正常出图,Zabbix 4.0 在 CentOS 7 上源码安装的完整链路到这里就算走通了一轮。这套流程跑过几次之后,你会发现源码安装没有想象中那么神秘,关键是每一步都弄清楚为什么这么做,以后不管换成 Zabbix 5.0 还是 6.0,原理都是相通的。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询