把一台已经装好 Zabbix Agent 的虚拟机克隆成多台,再让每台克隆机都用 Zabbix 监控 Nginx,这个流程看起来就是改个 IP、配个模板,实际上踩坑的地方不少。我最近处理的一批 Nginx 节点里,有三台克隆机反复出现连接不可达、监控数据串台,最后定位下来是主机名没改、agent 配置里还挂着源机的 Server 地址、Nginx 状态页根本没开启这三件事叠在一起。下面围绕克隆机、Nginx 监控、Zabbix 连接这条链路,把该改的配置、该验证的命令、该看的日志按操作顺序拆开讲清楚。如果你正在做 Nginx 集群监控,或者刚克隆完机器准备接入 Zabbix,可以直接把它当操作清单用。
1. 克隆机接入 Zabbix 之前,必须处理主机名、agent 标识和网络地址
1.1 克隆带来的“隐性三重复”
虚拟机克隆本质上是把磁盘完整复制一份,所以新机器的 /etc/hostname、/etc/hosts、Zabbix agent 配置、SSH 主机密钥、machine-id 全部和源机一样。如果只改了 IP 就急着接 Zabbix,后面一定会出问题。
对 Zabbix 来说,最要命的是三个重复:
- 主机名重复。Zabbix Web 界面里每个主机靠 Host name 区分,尤其开启 active checks 之后,agent 会以配置里的 Hostname 向服务端注册。两台机器都叫 nginx-node01,数据就会落到同一个主机上,同一张折线图里混着两台机器的数值,告警阈值完全失去意义。
- agent Hostname 重复。克隆机上
/etc/zabbix/zabbix_agent2.conf里的Hostname=还是源机的值,agent 起来之后仍然以旧名字上报,Zabbix Server 找不到这个名字对应的新主机,数据要么丢失,要么写到旧主机的历史数据里。 - 网络地址冲突。源机如果是静态 IP,克隆机需要单独改 IP、改网关、重新生成 MAC 相关配置;如果用的 DHCP 也不能掉以轻心,要确认拿到的确实是预设地址,否则后面 zabbix_get 永远会连错机器。
1.2 修改顺序和具体命令
我的建议是先改系统主机名,再改 agent 配置,最后重启服务,顺序不要乱。
hostnamectl set-hostname app-nginx-02然后检查 /etc/hosts,确保本机名解析正常,尤其是 agent 要连接本机的时候:
grep -n "app-nginx-02" /etc/hosts接着修改 Zabbix agent 配置。这里以 agent2 为例,路径一般是/etc/zabbix/zabbix_agent2.conf:
Hostname=app-nginx-02 Server=10.0.0.10 ServerActive=10.0.0.10三个参数的作用分别是:
Hostname:agent 注册时的名字,必须和你后面在 Zabbix Web 界面创建的主机名保持一致,active checks 靠这个名字认主机。Server:被动检查的白名单,只有列在这里的 IP 能从 agent 的 10050 端口拉数据。ServerActive:主动检查的服务端地址,agent 会主动连接这个地址发起 active checks。
克隆机最容易漏的就是这三个参数还是源机的值。之前遇到过一台机器,Server=还指向旧 Zabbix Server 的 IP,新服务端怎么拉都是 unreachable,改掉之后立刻恢复。
顺手把 SSH 主机密钥和 machine-id 也清一下:
rm -f /etc/ssh/ssh_host_* systemctl restart sshdZabbix 本身不在乎这两个东西,但如果后面要批量管理这些克隆机,不清理就会出现 SSH 登录时报 “REMOTE HOST IDENTIFICATION HAS CHANGED”,排查半天才发现问题出在密钥残留。machine-id 重复则可能在 systemd 相关服务初始化时报一些奇怪错误,属于卫生问题。
1.3 改完怎么验证没有残留
这一步别跳过,直接上命令:
hostname cat /etc/hostname grep -E '^(Hostname|Server|ServerActive)' /etc/zabbix/zabbix_agent2.conf systemctl restart zabbix-agent2 zabbix_agent2 -t agent.pingagent.ping 返回 1,说明 agent 本身能正常响应本地请求。但这只是第一步,后面还要看服务端能不能取到 nginx 相关数据。
2. Nginx 监控数据从哪里来:先把 stub_status 状态页打开
2.1 两种常见监控路径
Zabbix 官方对 Nginx 提供了一套模板,核心思路是让 agent2 的 nginx 插件通过 HTTP 去访问 Nginx 的状态页,常见模板名是 “Nginx by Zabbix agent 2”。另一条路是自己写 UserParameter,让经典 agent 去 curl 状态页再解析。
不管走哪条路,前提都一样:Nginx 必须开启stub_status状态页。状态页没开,模板里所有指标都会报 not supported 或者取到 0。
2.2 在 nginx.conf 里加一个受控的 location
在需要监控的 server 块里加一个精确匹配的 location:
server { listen 80; server_name _; location = /nginx_status { stub_status on; access_log off; allow 127.0.0.1; allow 10.0.0.10; # Zabbix Server 或 Zabbix Proxy 的地址 deny all; } }这里有几个点要解释一下:
location = /nginx_status是精确匹配,不会影响/nginx_status/这种路径,也不会把业务请求误路由到这里。stub_status on;开启状态页输出。allow 127.0.0.1必须保留,因为 agent 插件默认从本机取数。allow 10.0.0.10是 Zabbix Server 或 Proxy 的地址;如果你用 agent2 插件,它只访问 127.0.0.1,这个 allow 其实可以不要,但留着对排查有好处,方便直接从管理机 curl 验证。deny all;确保外网不能随便访问状态页,避免连接数、请求量这些信息泄露。
改完先检查语法再重载:
nginx -t nginx -s reload如果你用的是发行版自带 Nginx,也可以通过systemctl reload nginx,效果一样。
2.3 验证状态输出和指标含义
本机先 curl 一下:
curl http://127.0.0.1/nginx_status正常的输出长这样:
Active connections: 2 server accepts handled requests 10 10 10 Reading: 0 Writing: 1 Waiting: 1每一行含义如下:
| 输出内容 | 含义 | 监控时怎么用 |
|---|---|---|
| Active connections | 当前活跃连接数 | 快速判断当前压力 |
| accepts | 累计已接受连接数 | 和 handled 对比看是否有短连接异常 |
| handled | 累计已处理连接数 | 如果明显小于 accepts,说明连接被过早丢弃 |
| requests | 累计请求数 | 从总数做增量可以看请求速率 |
| Reading | 正在读取请求头的连接数 | 偏高说明请求量在涨 |
| Writing | 正在写响应的连接数 | 偏高说明响应处理慢或网络阻塞 |
| Waiting | 空闲长连接等待请求数 | keepalive 场景下观察连接复用 |
中间那一行的三个数字,第一个是 accepts,第二个是 handled,第三个是 requests。正常情况 accepts 和 handled 几乎相等,如果长期有差值,就要查 worker_connections、listen backlog 这些参数。
2.4 状态页只能本机访问时,agent 怎么取数
如果你的 Nginx 在宿主机上直接跑,agent 也在这台机器上,那就让插件走 127.0.0.1,完全不需要把状态页暴露给外部。
如果 Nginx 跑在 Docker 容器里,agent 跑在宿主机上,要把容器端口映射到宿主机,然后让插件指向127.0.0.1:映射端口。此时 allow 那段要加容器的网关地址或者干脆只允许本机,避免容器外其他机器直连。
3. Zabbix Agent 配置和模板绑定:让监控项真正取到值
3.1 官方模板还是自定义键值
如果整个环境都是 Zabbix 6.0 以上,且 agent 用的都是 agent2,直接用官方模板 “Nginx by Zabbix agent 2” 最省事。官方模板通过 agent2 的 nginx 插件采集,插件会访问/nginx_status页面,然后按标准格式解析。
如果环境中还有老版本 agent,或者 Nginx 状态页在 HTTPS 后面、需要自定义路径,我会直接写 UserParameter。好处是逻辑完全自己掌控,curl 一下、awk 一下就能返回结果,排查也直观。
3.2 agent2 的 nginx 插件配置
agent2 的插件配置文件一般在/etc/zabbix/zabbix_agent2.d/plugins.d/nginx.conf,如果目录不存在就自己建。
Plugins.Nginx.Status.Host=127.0.0.1 Plugins.Nginx.Status.Port=80 Plugins.Nginx.Status.Path=/nginx_status Plugins.Nginx.Status.Scheme=http改完重启 agent2:
systemctl restart zabbix-agent2然后用 agent2 自带测试方式验证:
zabbix_agent2 -t nginx.status.active zabbix_agent2 -t nginx.status.accepted zabbix_agent2 -t nginx.status.handled zabbix_agent2 -t nginx.status.requests zabbix_agent2 -t nginx.status.reading zabbix_agent2 -t nginx.status.writing zabbix_agent2 -t nginx.status.waiting能返回数值,说明插件、状态页、网络都通了。这里如果返回 not supported,多半是路径不对,或者插件没加载成功,先 curl 看看状态页是否真的返回了内容。
3.3 用 UserParameter 实现自定义键值
没有 agent2 或者不想依赖插件的环境,可以新建一个配置文件,例如/etc/zabbix/zabbix_agentd.d/nginx_status.conf:
UserParameter=nginx.active,curl -s http://127.0.0.1/nginx_status | awk '/Active/{print $3}' UserParameter=nginx.accepts,curl -s http://127.0.0.1/nginx_status | awk 'NR==3{print $1}' UserParameter=nginx.handled,curl -s http://127.0.0.1/nginx_status | awk 'NR==3{print $2}' UserParameter=nginx.requests,curl -s http://127.0.0.1/nginx_status | awk 'NR==3{print $3}' UserParameter=nginx.reading,curl -s http://127.0.0.1/nginx_status | awk '/Reading/{print $2}' UserParameter=nginx.writing,curl -s http://127.0.0.1/nginx_status | awk '/Writing/{print $4}' UserParameter=nginx.waiting,curl -s http://127.0.0.1/nginx_status | awk '/Waiting/{print $6}'这样写的好处是键值名完全可控,后面建模板、建触发器时直接对键名。测试方式:
zabbix_agentd -t nginx.active zabbix_agentd -t nginx.writing如果本机能取到值,但服务端取不到,那就回到第 4 章的网络排查,大概率是白名单或防火墙。
3.4 Web 界面创建主机并绑定模板
Zabbix 界面的操作路径一般是:
- 数据采集 → 主机 → 创建主机。
- 主机名称填
app-nginx-02,一定要和 agent 配置里的 Hostname 一致。 - 如果是被动检查,接口类型选 Agent,填克隆机的 IP 或 DNS,端口默认 10050。
- 链接模板区域搜索 “Nginx”,选对应的 “Nginx by Zabbix agent 2” 模板。
- 保存,等待 1 到 2 个采集周期。
- 到 监测 → 最新数据 里筛选主机,看 nginx.* 指标是否有值。
为什么主机名必须一致?因为 active checks 的注册流程里,agent 会把Hostname=的值上报给 Zabbix Server,Server 用这个名字去找对应的主机配置。名字对不上,即使网络全通,数据也不知道该往哪里写。
3.5 克隆机上最容易漏的两个绑定问题
第一个是旧主机还挂在 Zabbix 里。如果源机之前已经监控过,新克隆机接入前最好把旧主机停用或删除,不然同 IP、同 Hostname 的情况下,新主机数据可能和旧主机互相覆盖。第二个是 Hostname 没改,数据全部落到旧主机上。这个坑最隐蔽,因为 zabbix_get 也是通的,Latest data 也有数值,只是你盯着新主机界面看,一直显示没数据。
4. 连接失败时按这个顺序排查:端口、白名单、防火墙、日志
4.1 先确认 agent 进程和监听端口
连接不通,别直接改配置,先看 agent 到底起没起来:
systemctl status zabbix-agent2 ss -lntp | grep 10050 ps -ef | grep zabbix10050 是 agent 被动检查的监听端口。如果这个端口不存在,说明 agent 没起来,后面所有排查都白做。常见原因是克隆机改完主机名之后没有重启,或者配置文件语法错误。
4.2 再确认 agent 配置里的 Server 白名单
Zabbix 的被动检查逻辑是:Server 主动连 agent 的 10050 端口,agent 收到请求后会校验来源 IP 是否在Server=列表里。不在列表里就直接丢弃,agent 日志里会出现类似 “not allowed host” 的记录。
所以克隆机必须检查这点:
Server=127.0.0.1,10.0.0.10 ServerActive=10.0.0.10Server=是白名单,ServerActive=是主动连接地址。很多人只改 Hostname 不改这两个参数,结果新 Zabbix Server 永远连不上。
4.3 防火墙和 SELinux
白名单没问题,下一步查防火墙。
firewall-cmd --state firewall-cmd --list-ports firewall-cmd --permanent --add-port=10050/tcp firewall-cmd --reload克隆机最容易出现一个情况:源机之前为了别的服务开过防火墙规则,克隆之后新网络段根本不在允许列表里。如果是 Ubuntu,对应的命令是 ufw;如果是 Debian 系没装 ufw,还要看 iptables 是否被清了。
SELinux 也要考虑。可以临时关一下做对比测试:
setenforce 0如果关掉之后 zabbix_get 立刻通了,说明是 SELinux 策略问题,再把策略补上,不要长期保持关闭。Zabbix 官方文档针对不同发行版都有对应的 SELinux 策略说明,按版本装对应策略包即可。
4.4 用 zabbix_get 判断问题在哪一侧
zabbix_get 是从 Zabbix Server 侧主动拉取 agent 数据的工具,没有就先装:
yum install zabbix-get然后分三档验证:
| 测试对象 | 命令 | 判断结果 |
|---|---|---|
| agent 本机取数 | zabbix_agent2 -t nginx.active | 能返回值,说明插件和状态页正常 |
| 服务端取数 | zabbix_get -s 10.0.0.11 -k nginx.active | 能返回值,说明网络、白名单、端口全通 |
| Web 界面 item | 最新数据 / item 的 last error | 能出数,说明模板和主机绑定正确 |
如果第一档通过、第二档失败,问题就集中在 Server 白名单、防火墙、端口这三件事上;如果第一档也失败,问题在 agent 配置或者 Nginx 状态页本身。
4.5 日志怎么看
每层都有日志,按顺序翻:
/var/log/zabbix/zabbix_agent2.log或/var/log/zabbix/zabbix_agentd.log:看 agent 启动、连接拒绝、插件加载失败。/var/log/zabbix/zabbix_server.log:看服务端是否尝试连接、是否收到 active checks 注册。- Nginx 的 error log:看
/nginx_status是否有 404、403、405 这类请求记录。
我之前遇到过一种情形:agent 日志没有任何异常,zabbix_get 也能取到 nginx.active,但 Web 界面 item 一直报 not supported。最后发现是模板里的键名和 plugin 返回的键名对不上,版本匹配问题。这种情况只能看 item 的 last error,它会明确告诉你 what key is not supported。
4.6 克隆机典型现象对照表
| 现象 | 最可能原因 | 先查哪里 |
|---|---|---|
| Web 界面显示 unreachable | 防火墙挡 10050、Server 白名单没加新 IP | zabbix_get、firewall-cmd |
| 主机能看到但所有 item 没数据 | 模板没链接、键值名不匹配 | 最新数据、agent -t |
| nginx 状态项报 not supported | 状态页没开、路径不对、插件未启用 | curl 状态页、agent 日志 |
| 数据写到旧主机 | 克隆机 Hostname 没改,active checks 注册到旧名 | grep Hostname |
| zabbix_get 通但 web 没显示 | 主机名不匹配或主机被分配到代理下 | 主机配置、代理配置 |
5. 多台克隆机批量接入 Zabbix 的配置管理思路
5.1 不要一台一台手工改
一次克隆三五台,手工改问题不大。一旦节点上了两位数,每台机器都去敲一遍 hostnamectl、sed 配置、重启服务,迟早会漏掉某台的 Server 白名单。
可以准备一个简单的初始化脚本,克隆完成后传参执行:
#!/bin/bash HOSTNAME=$1 NEW_SERVER_IP=$2 hostnamectl set-hostname "$HOSTNAME" sed -i "s/^Hostname=.*/Hostname=$HOSTNAME/" /etc/zabbix/zabbix_agent2.conf sed -i "s/^Server=.*/Server=$NEW_SERVER_IP/" /etc/zabbix/zabbix_agent2.conf sed -i "s/^ServerActive=.*/ServerActive=$NEW_SERVER_IP/" /etc/zabbix/zabbix_agent2.conf systemctl restart zabbix-agent2用法:
bash init_clone_agent.sh app-nginx-02 10.0.0.10这里我一般习惯先把一台克隆机完整跑通,再把这个脚本批量套到其余机器上,避免带着同一个错误复制到所有节点。
5.2 维护主机名、IP、模板映射表
批量接入时,表格比记忆可靠。建议至少维护这些列:
| 虚拟机名 | IP | 主机名 | L链接模板 | 备注 |
|---|---|---|---|---|
| nginx-clone-01 | 10.0.0.11 | app-nginx-01 | Nginx by Zabbix agent 2 | 权限组 A |
| nginx-clone-02 | 10.0.0.12 | app-nginx-02 | Nginx by Zabbix agent 2 | 权限组 A |
| nginx-clone-03 | 10.0.0.13 | app-nginx-03 | Nginx by Zabbix agent 2 | 权限组 B |
名字最好有规律,比如app-nginx-01,这样后面写脚本、批量建主机、做告警通知都很方便。
5.3 批量验证连接
全部接入后,可以写一个循环到服务端批量验证 agent.ping:
for ip in 10.0.0.11 10.0.0.12 10.0.0.13; do echo "== $ip ==" zabbix_get -s "$ip" -k agent.ping done再把 nginx.active 也拉一遍:
for ip in 10.0.0.11 10.0.0.12 10.0.0.13; do echo "== $ip ==" zabbix_get -s "$ip" -k nginx.active done有值就说明状态页、agent 取数、网络、白名单都是通的。如果某个 IP 返回空或者报错,再单独回到第 4 章排查。
5.4 节点数量多了,考虑用 Zabbix Proxy
当克隆出来的节点分布在多个网段,或者单台 Zabbix Server 要管理几十上百台 agent 时,建议加一层 Zabbix Proxy。Proxy 部署在靠近被监控机器的位置,agent 把数据交给 Proxy,Proxy 再统一上报给 Server。
使用 Proxy 之后的改动点:
- Proxy 的
Server和ServerActive指向 Zabbix Server。 - 被监控节点的 agent 配置里,
Server=和ServerActive=改成指向 Proxy 的 IP。 - Web 界面创建主机时,选择该主机由哪个 Proxy 管理。
- 这样 Zabbix Server 不用直接连接每台克隆机的 10050 端口,网络策略好开放很多。
首次从单机过渡到 Proxy 时会觉得多了一层配置,但节点越多,收益越明显,尤其是跨网段、防火墙策略严格的环境。
5.5 监控项别贪多
克隆机批量接入时,最容易犯的错是给每台机挂一大堆模板、加几十个监控项。Nginx 监控核心就是连接数、请求数、Reading/Writing/Waiting 这几个指标,足够判断容量和异常。每台机从 7 到 10 个 Nginx 指标起步,跑一阵子再看要不要补,比一开始就堆满更稳。
更新周期也不用拉得太短。默认 1 分钟一次对大多数 Nginx 集群够用;如果节点连接数高、想细化告警,再单独把nginx.active的更新间隔调到 10 秒或 30 秒。更新间隔越短,对 Server 的数据库写入压力越大。
处理克隆机接入 Zabbix 监控 Nginx,本质上就是把三件事做干净:机器身份和源机分开,Nginx 开一个受控的状态入口,agent 的取数和通讯配置对齐。踩过几次坑之后会发现,绝大多数连接问题不是 Zabbix 功能问题,而是主机名残留、Server 白名单没更新、防火墙挡了端口。先把一台克隆机从改主机名到 Latest data 有数值完整走一遍,再批量复制这个流程,后面会省很多事。