☰
麒麟系统离线源码编译安装Zabbix Agent全攻略
2026/10/3 1:08:59 网站建设 项目流程

讲个实在的场景。单位新到一批基于麒麟系统的服务器,业务要求全部纳入现有Zabbix监控体系。这类机器十有八九在独立内网里,没外网、没镜像源、连个yum源都得现搭,偏偏还要装监控agent。常规的yum install直接洗洗睡,手里要是有rpm包还得看麒麟的版本和依赖链合不合拍,一不留神就是循环依赖死胡同。所以最终方案基本都是走源码编译。这篇文章就一步步记录麒麟linux离线源码编译安装zabbix-agent的完整过程,包括准备工作、configure参数选择、安装配置、排坑心得,照着抄能少走不少弯路。

先说结论:源码编译在国产化系统上不是闷头跑./configure && make && make install就完事的,真正的坑往往藏在依赖库、编译器版本、安全子系统(麒麟自带的kysec)还有systemd服务配置里。下面每个环节都会详细拆。

1. 思路拆解:为什么源码编译是离线监控的首选

1.1 麒麟系统的版本特性决定了包管理没那么省心

麒麟linux在国产服务器里占有率不低,常见的是银河麒麟V10系列,底子一般对齐到CentOS/RHEL的某个大版本。问题就出在这个“对齐”上:

  • 系统库的glibc版本、openssl版本和原生CentOS不完全一致,直接用CentOS的rpm包偶尔能装上,但启动时候崩的案例并不少。
  • 麒麟自带yum源往往是内网私有源,或者根本没配置,yum install大部分情况直接报找不到镜像源。
  • 即便有rpm包,依赖库比如pcre、libevent、libssl的版本偏差也会导致agent起不来。源码编译恰恰绕开了这些对系统包管理器的强依赖。

1.2 源码编译相比二进制包的核心优势

对比项二进制rpm包源码编译
依赖库管理依赖系统rpm库,版本冲突直接劝退只需编译时指定路径,灵活度极高
部署位置固定目录,改起来麻烦prefix参数可指定任意路径,方便统一管理
编译选项官方通用,不含特殊参数可按需开启或关闭功能模块
对系统改动可能覆盖既有库文件基本不碰系统原生库

做监控agent部署,最怕的是出了问题扯不清是agent的事还是系统的事。源码编译的路径完全由自己控制,二进制放哪、配置放哪、PID文件放哪都清清楚楚,排查问题的时候省心很多。

1.3 离线环境下源码编译的真正瓶颈是什么

离线环境编译最大的障碍不是代码本身,而是缺编译工具链和依赖头文件。很多运维同事一上手就发现gcc都不存在,make也没有,这才是第一道坎。所以准备工作里,构建环境需要的工具和头文件缺一不可,这步没做好,后面全是白搭。

另外源码编译对编译器版本也有一定要求。Zabbix 6.0之后的版本对C语言标准有了更高要求,老的gcc 4.8编译会告警甚至报错。麒麟V10如果默认带的是gcc 4.8.5,编译高版本zabbix会有麻烦,需要另想办法装新编译器。这块内容放到后面专门章节细讲。

2. 离线环境下的准备清单与工具链检查

2.1 在可联网机器上一次性下载所需源码包

我习惯的做法是找一台和麒麟同架构(x86_64或aarch64)且能联网的机器,把zabbix源码包、依赖库源码包全部下载好,然后通过内网拷到目标机器。这一步切记确认目标机的CPU架构,aarch64的机器用x86_64的包直接白搭。

需要准备的材料如下:

  • zabbix源码包。版本选择上,如果Zabbix服务端是6.0 LTS,那agent就用6.0的对应版本;如果服务端是7.0,就用7.0的对应版本。版本号差太多可能上报协议上有兼容性差异。
  • pcre源码包或pcre2源码包。zabbix老版本依赖pcre,6.4以上版本逐渐在向pcre2迁移,但传统agent的大部分版本仍编译依赖pcre。
  • libevent源码包。zabbix agent源码编译可选的依赖,实际需要处理定时任务、连接方式等会用到。
  • 可选依赖:openssl开发库(如果agent需要加密通信),zlib(某些场景)。

2.2 目标机上检查编译工具链是否齐备

在麒麟系统的目标机器上,先执行下面的检查:

gcc --version make --version ld --version

如果gcc或make缺失,离线环境怎么补工具链?常见方案有两个:

  • 用系统安装ISO里的rpm包。麒麟系统的镜像ISO里一般自带gcc、make、glibc-devel、kernel-headers这些安装包,把ISO挂载或解压之后,rpm -ivh按顺序安装。
  • 从联网机器下载rpm包,用yumdownloader配合--resolve选项把所有依赖一起拉下来,再拷贝到目标机用rpm -Uvh *.rpm安装。

注意:用yumdownloader --resolve拉依赖的时候,一定要用和麒麟系统底子对应的yum源。麒麟V10的gcc版本、内核版本和CentOS不是完全一样的,硬装CentOS的rpm包有很大概率模块版本不兼容。

2.3 需要确认的依赖库头文件

编译zabbix agent时,如果提示找不到某些头文件,比如pcre.h、event.h、openssl/ssl.h,就要检查这些开发包是否安装。源码编译用到的依赖库,编译阶段就需要对应的头文件。离线环境里,头文件只能通过rpm包或源码包自行编译安装。

以下包名是麒麟系统常见对应关系:

依赖库麒麟系统上的包名说明
PCREpcre-devel 或 libpcre3-dev正则表达式支持
libeventlibevent-devel网络事件库,agent需要
OpenSSLopenssl-develagent加密通信可选

若是rpm包装不上,更稳妥的方案是直接下载依赖库的源码包,在目标机上分别编译安装。比如pcre源码包编译:

tar -zxvf pcre-8.45.tar.gz cd pcre-8.45 ./configure --prefix=/usr/local/pcre make && make install

编译完之后要把/usr/local/pcre/lib加进ld.so.conf里,执行ldconfig刷新动态链接库缓存。

3. 麒麟系统上源码编译zabbix-agent的完整实操

3.1 创建用户与准备目录结构

编译之前,先规划好agent的安装目录。我习惯统一放在/opt/zabbix下,这样配置文件和二进制文件都在一个地方,后面做批量脚本也方便。

groupadd zabbix useradd -g zabbix -s /sbin/nologin zabbix mkdir -p /opt/zabbix/{sbin,etc,logs,run} chown -R zabbix:zabbix /opt/zabbix

用户的作用在于agent进程运行身份分离,避免用root跑监控进程带来的安全风险。zabbix agent通常只需要读取系统指标和执行指定脚本的权限,没必要给root。

3.2 configure参数选择与依赖指定

在zabbix源码根目录执行configure。这里有几个参数需要重点关注一下:

./configure \ --prefix=/opt/zabbix \ --enable-agent \ --sysconfdir=/opt/zabbix/etc \ --localstatedir=/opt/zabbix \ --with-libpcre=/usr/local/pcre \ --with-libevent=/usr/local/libevent

参数说明:

  • --prefix:指定安装根目录,后面make install会把二进制放在/opt/zabbix/sbin下。
  • --enable-agent:只编译agent,不编译server和proxy,大幅缩短编译时间和依赖范围。
  • --sysconfdir:配置文件目录,默认情况下如果不指定,会放在/usr/local/etc下,统一改到/opt/zabbix/etc更好管理。
  • --localstatedir:本地状态目录,PID文件和socket文件会放在这个目录下面。
  • --with-libpcre:指定pcre库的安装前缀。如果你把pcre直接装在系统默认路径,比如/usr下,这个参数可以省略;如果装在自定义路径,必须手动指定。
  • --with-libevent:同样指定libevent的位置。

configure最后如果出现config.status: executing libtool commands这类输出,大概率是参数通过了。不放心的话,可以等配置完成后执行echo $?确认结果为0。

3.3 make编译与安装过程分析

make -j$(nproc) make install

$(nproc)会自动取CPU核心数,多核机器编译速度会快不少。编译时间一般在几分钟到十几分钟,取决于机器性能。

编译过程出现warning是正常现象,但如果有error:字样就说明缺依赖或者编译器版本有问题。比如比较典型的报错:

checking for pcre_compile... no configure: error: unable to find pcre library

这说明pcre的头文件或库文件没有找到。解决思路是检查/usr/local/pcre/lib和/usr/local/pcre/include是否存在,以及configure参数里的路径是否和实际安装路径完全一致。

编译安装完成后,/opt/zabbix/sbin下会生成zabbix_agentd二进制文件。可以用下面的命令验证安装是否有效:

/opt/zabbix/sbin/zabbix_agentd --version

正常会输出类似Zabbix agent v6.0.x这样的版本信息。如果你特意编译过agent2,会发现同时有zabbix_agent2这个二进制,老牌agent和新版agent2是两套东西,部署时二选一即可。

4. Agent配置与服务化:让监控从装完变为跑起来

4.1 zabbix_agentd.conf核心配置项解析

编译安装完成之后,/opt/zabbix/etc下会有一个zabbix_agentd.conf默认配置。需要手动改下面几项:

PidFile=/opt/zabbix/run/zabbix_agentd.pid LogFile=/opt/zabbix/logs/zabbix_agentd.log Server=10.0.0.1 ServerActive=10.0.0.1 Hostname=Kylin-Server-01

配置项说明表:

配置参数含义补充说明
PidFilePID文件路径确保目录存在且有写权限,否则启动直接报错
LogFile日志文件路径没有这个目录agent会拒绝启动
Server允许主动拉取的Zabbix Server地址多个地址用逗号分隔
ServerActive允许agent主动上报的Server地址主动模式比被动模式数据时延更小
Hostnameagent在服务端显示的主机名必须和Zabbix Web端配置的主机名完全一致
UnsafeUserParameters是否允许用户自定义参数一般设1,但要严格控制脚本安全和执行权限
UserParameter自定义监控项键值格式:key,command

注意:被动模式和主动模式本质区别在于谁来发起连接。Server参数用于被动模式,Server定时来拉数据;ServerActive用于主动模式,agent自己连到Server提交数据。两种模式可以同时启用,建议都写上,便于Web端灵活切换。

4.2 配置防火墙与系统安全策略

麒麟系统默认开了firewalld还是iptables,不同版本不一样。需要在防火墙放行zabbix agent的端口。默认agent监听的端口是10050,agent2监听的也是10050。

firewall-cmd --permanent --add-port=10050/tcp firewall-cmd --reload

如果连firewall-cmd命令都不存在,大概率系统在用iptables,那就直接编辑/etc/sysconfig/iptables添加规则:

-A INPUT -p tcp --dport 10050 -j ACCEPT

这里额外提个麒麟的坑:系统自带的kysec(麒麟安全子系统)在某些版本上默认是Enforcing状态,会拦截agent去写日志或PID文件。遇到agent启动后立刻退出、日志目录无文件的情况,可以先查看内核日志:

dmesg | grep -i ksec dmesg | grep -i denied

如果有被拦截的记录,考虑把agent的可执行文件和配置目录加入白名单,或者临时将kysec切换到Permissive模式测试。具体操作方式因麒麟版本而异,但思路一致:先确认是不是安全模块拦截,再去改策略,别上来就怀疑agent代码有bug。

4.3 编写systemd服务实现开机自启

源码编译装完没有自启动脚本,所以systemd单元文件要自己写。在/etc/systemd/system/zabbix-agent.service里创建下面内容:

[Unit] Description=Zabbix Agent After=network.target [Service] Type=forking User=zabbix Group=zabbix ExecStart=/opt/zabbix/sbin/zabbix_agentd -c /opt/zabbix/etc/zabbix_agentd.conf ExecStop=/bin/kill -TERM $MAINPID PIDFile=/opt/zabbix/run/zabbix_agentd.pid Restart=on-failure [Install] WantedBy=multi-user.target

说明一下Type=forking的选择:zabbix_agentd启动后默认以守护进程模式在后台运行,父进程fork出子进程后自身退出,这是传统的初始化脚本行为,配合PIDFile指定路径,systemd才能准确识别主进程PID来管理服务。如果写Type=simple又不确认主进程PID,重启服务容易产生僵死进程。

单元文件写好后执行:

systemctl daemon-reload systemctl start zabbix-agent systemctl enable zabbix-agent systemctl status zabbix-agent

看到active (running)并且日志文件有正常输出,agent就算跑起来了。

5. 编译安装中的常见问题与排障经验

5.1 configure阶段报错:找不到pcre、libevent、openssl

这是离线编译里遇到最多的一个问题。现象很直接:configure执行到一半,红色大字报错说明缺某个库。核心原因是依赖库本身或者开发头文件没有装。

排障步骤可以按下面的顺序走:

  1. 先确认依赖库是否已经装在系统里:
    find / -name "pcre.h" 2>/dev/null find / -name "libpcre*" 2>/dev/null
  2. 如果pcre已经装自定义路径,configure时一定要用--with-libpcre=/自定义路径显式指定,光靠PKG_CONFIG_PATH有时候不够。
  3. 如果库里压根没有pcre,从源码重新编译一遍pcre到你指定的路径,再执行ldconfig。

我曾经在一台机器上把pcre编译到了/usr/local/pcre,configure始终报错找不到pcre,排查了半天发现是因为自定义lib目录没有写进动态链接库配置里。加上/etc/ld.so.conf.d/下的自定义conf文件并执行ldconfig之后再configure就通过了。

5.2 make阶段编译报错:gcc版本过旧不兼容

高版本zabbix(6.4及以上)要求编译器支持C99标准的部分特性,老gcc比如4.8.5会在编译时出现未知类型或隐式函数声明的报错。

解决办法有两条路:

  • 升级gcc到8以上版本。可以通过scl软件集(如果有镜像源或rpm包)实现。
  • 如果gcc版本实在无法升级,就退回使用旧版的zabbix agent,比如6.0 LTS早期版本对老gcc兼容性更好。

我的实际建议是升级gcc,别死磕旧版本agent。旧版本agent可能存在已知安全漏洞或bug,另外旧版对Server的连接协议兼容性也差,后续升级服务端时很可能需要同步升级agent,那是更大的工作量。

5.3 agent启动失败:PID文件目录不存在或无权限

启动后systemctl status显示failed,去查日志又发现日志文件根本没生成,这种问题多半出在路径和权限上。

典型原因就三类:

  1. PidFile和LogFile配置的目录没有提前创建。
  2. zabbix用户对目录没有写权限。
  3. kysec模块阻止了进程对指定目录的写操作。

处理方式:

mkdir -p /opt/zabbix/run /opt/zabbix/logs chown -R zabbix:zabbix /opt/zabbix chmod -R 755 /opt/zabbix

改完权限先手动启动一下agent,前台模式观察输出:

sudo -u zabbix /opt/zabbix/sbin/zabbix_agentd -c /opt/zabbix/etc/zabbix_agentd.conf

如果前台能跑起来,说明配置和权限都没问题,问题出在systemd服务配置或kysec策略上。如果前台也报错,输出信息才是最直接的排障依据。

5.4 Agent已运行,但Zabbix Server界面显示主机不可达

配置好服务端之后,Web界面却显示主机红色不可达,这种情况比编译问题出现得还频繁。可以从三个方向排查:

  1. 防火墙是否放行10050端口,用telnet或nc测试服务端到agent的连通性:

    nc -vz 10.0.0.101 10050
  2. Agent配置中的Hostname和Web端添加主机时填写的名称是否完全一致。大小写、空格、下划线的差异都会导致识别失败。

  3. 查看agent日志里是否有连接接收记录:

    tail -f /opt/zabbix/logs/zabbix_agentd.log

出现failed to accept an incoming connection多半是防火墙或安全策略的问题;出现not authorized则要重点检查Server参数,确认是不是只允许了特定IP访问。

5.5 自定义监控项脚本的执行环境问题

在实际监控场景里经常要添加自定义UserParameter来监控业务指标。这部分编译本身没问题,但脚本在执行时会遇到环境变量问题。Zabbix agent在执行脚本时是不加载用户完整环境变量的,日常/usr/bin、/usr/local/bin这些路径在脚本里要写全。建议所有自定义脚本统一放到/opt/zabbix/scripts目录下,UserParameter里用绝对路径引用:

UserParameter=custom.check,/opt/zabbix/scripts/check.sh

脚本还需要有执行权限,chmod +x不能漏。此外更重要的一点,agent是以zabbix用户身份执行脚本的,如果脚本有访问某些系统文件或执行某些命令的权限要求,提前给zabbix用户配置sudo免密规则或调整文件读取权限,否则脚本怎么写都是跑不通的。

6. 离线环境批量部署的小技巧

既然环境是离线内网,一台台手动配置显然不现实。企业里有几十台甚至上百台上述机器要部署agent的时候,我一般是做成脚本一键执行,配合ansible的离线模式或者pssh这种小工具批量分发。

脚本的核心逻辑是:

  1. 解压agent安装包和依赖库到临时目录。
  2. 执行configure、make、make install。
  3. 用sed命令替换配置文件里的Server和Hostname占位符。
  4. 创建systemd服务并启动。

批量脚本里一个容易忽略的问题是每台机器的Hostname不同。如果脚本里Hostname写死,所有机器在Zabbix Server上只会显示一个主机名,后加入的机器会把前面的挤掉。建议Hostname直接调用系统自身的hostname变量:

sed -i "s/Hostname=.*/Hostname=$(hostname)/" /opt/zabbix/etc/zabbix_agentd.conf

如果是大规模集群,还建议把agent的被动模式关掉,只保留主动模式(ServerActive),这样Server端压力小,防火墙规则也更好收敛。

7. 关于agent与agent2的选型思考

传统zabbix agent(C语言实现)和zabbix agent2(Go语言实现)在源码编译上各有侧重。传统agent依赖库少,编译参数简单,部署体积小,占用系统资源更少;agent2支持插件体系,后续可以做更多扩展,但编译时依赖Go工具链,离线环境下准备Go编译器本身又要费一番功夫。

麒麟系统上的实际体验是,优先建议用传统agent。原因有两个:

  • 传统agent在国产化系统上的兼容性问题更少,编译链路上少一个Go的版本约束。
  • 离线环境下的依赖准备更简单,编译器版本要求也没有Go那么苛刻。

等后续需要监控容器、DB等更丰富的指标时,再考虑单独机器上补充agent2来做侧重监控,或者干脆在运维管道的规划阶段就统一用agent2,只是要提前把Go的工具链一起打包进离线资源里。

8. 最后再讲点实用体会

麒麟离线源码编译这件事,上手之前觉得复杂,理顺了依赖和权限之后其实套路非常固定。我踩过最大的坑其实还不是编译本身,而是忽略了系统自带安全模块对进程运行造成的约束,导致服务装了无数遍还是起不来。所以给准备动手的实验建议:编译之前先把系统底子摸透,确认gcc版本、依赖库情况、安全策略状态,这三样都没问题再开始编译,效率会高很多。

另外,源码编译不要急着在所有机器上同时铺开。先拿一台最普通的测试机完整跑一遍流程,记录下所有报错和解决方案,再把这套流程固化成脚本或文档,后续批量执行就能规避绝大多数问题。做运维的人都知道,一次构建、处处运行的稳定部署,远比每一次都靠临场应变要靠谱得多。

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

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

立即咨询