刚开始用 Zabbix 的人,通常会在两个地方卡住。第一个是被"企业级"这三个字吓住,觉得这套东西架构一定很复杂,没个专门的监控团队根本玩不转;第二个恰恰相反,跟着网上各种教程在自己的 CentOS、openEuler 机器上源码编译安装,最后把系统环境搞得一团糟。我前几年是走第二条路的,那感觉就像在没有抽屉的柜子里硬塞杂物——Zabbix Server 要一堆 PHP 扩展,机器上刚好有个业务用的老版本 PHP,版本冲突的时候真的想砸键盘。
后来全面切到 Docker 部署,Zabbix 这套"Server + 前端 + 数据库 + Agent"的组合一下子清爽了:镜像拉下来,一个 docker-compose 编排文件写完,两条命令就能得到一个完整可用的监控与告警平台。这篇就围绕这个方案展开,讲讲我实际搭建时怎么选版本、怎么写编排文件、怎么把 Linux 主机、Windows 机器、交换机都纳入监控,以及这几年磕磕绊绊踩过的一堆坑。
适合谁看?不管你是刚接手公司监控体系的运维新人,还是想在自己服务器上搭一套监控系统、及时发现自己业务异常的独立开发者,按文中的步骤操作都能顺利跑起来。我尽量不写空中楼阁的东西,每一步都有实际指令和踩坑记录,照着做基本不会翻车。
1. 监控选型这回事:为什么偏偏是 Zabbix + Docker
1.1 传统部署 Zabbix 的痛点在哪
先说结论:Zabbix 本身没问题,问题出在它传统的安装方式上。Zabbix Server 依赖非常多的组件,包括数据库(PostgreSQL 或 MySQL)、前端运行环境(Nginx/Apache + PHP 及一堆扩展如 gd、bcmath、ctype、libxml)、SNMP 基础库,还要 gcc 编译环境。老版本的发行版尤其痛苦,比如 CentOS 7 自带的 gcc 版本太老,编译较新版本的 Zabbix 时会直接报错,你得先手动升级工具链;PHP 版本不够,又得挂第三方源,一挂第三方源,系统里其他业务依赖的 PHP 包就可能被一并升级,搞得其他应用跟着挂。
我在 openEuler 上还遇到过另一个坑:系统默认的 dnf 源里 Zabbix 库存量很老,为了装新版只能自己加源,加完源之后依赖解析满屏的冲突提示,看半天不知道哪个包把哪个包顶掉了。即便好不容易装完,后面升级又是新一轮折磨——配置文件散落在 /etc/zabbix、/usr/local/etc、/etc/nginx 好几个位置,升级前要手动备份,升级后还要重新对比模板。
Docker 方案把这些依赖全部封装进镜像里,宿主机只需要一个 Docker Engine,什么 PHP、Nginx、数据库客户端统统不用管。镜像的维护方是 Zabbix 官方,版本配套关系是经过测试的,你不需要关心 zabbix-server 7.0 到底匹配哪个 PHP 版本。这也是为什么后来我给朋友和客户做监控方案时,一律推荐容器化。
1.2 容器化之后的架构长什么样
理解 Zabbix 的容器化架构,首先要明白它由哪几个部分组成:
- Zabbix Server:负责数据采集调度、触发器计算、告警生成,监听 10051 端口,接收 Agent 主动上报的数据,也接受 Agent 的被动采集请求。
- 数据库(PostgreSQL/MySQL):存放配置、历史数据、事件和告警记录,是整个系统的"账本"。
- Zabbix Web:就是那个登录后看到的监控界面,底层是 Nginx + PHP,负责渲染页面、执行管理操作,它直接连数据库,并且通过内部网络访问 Server。
- Zabbix Agent/Agent2:安装在被监控对象上,采集 CPU、内存、磁盘、进程等指标。被动模式下 Server 连 Agent 的 10050 端口拿数据,主动模式下 Agent 把数据推给 Server 的 10051。
- Proxy(可选):分布式场景下的中转节点,适合跨机房、跨网络段、设备数量特别大的场景,后面我会单独说。
用 Docker Compose 部署时,这些组件就是 Compose 文件里的几个 service。它们在同一个自定义网络里互相用服务名通信(比如 web 容器里配置DB_SERVER_HOST=postgres),对外只需要暴露少数端口给外部:Web 用 8080,Server 用 10051,Agent 用 10050。数据库端口我一般映射到宿主机上,安全考虑,只在编排网络内部访问。
这套架构里"配置在数据库、页面只管展示"的设计,让运维变得很舒服:页面绑定的数据库和 Server 只要连通,前端想拆到另一台机器做高可用都可以。
2. 部署前置条件:版本选择、镜像源与目录规划
2.1 版本怎么选:6.0 LTS 还是 7.0 LTS
Zabbix 官方同时维护多个版本线,普通版本只是尝鲜,生产环境一定选 LTS(长期支持)版本。当前两个主流 LTS 是 6.0 和 7.0。
| 对比项 | Zabbix 6.0 LTS | Zabbix 7.0 LTS |
|---|---|---|
| 发布时间 | 2022 年初 | 2024 年下半年 |
| 标准支持期 | 约 5 年 | 约 5 年 |
| 新部署推荐度 | 存量环境继续用 | 新环境优先选 |
| 主要改进 | 稳定的老将 | 全新 UI、更细的权限控制、报警风暴控制、宏增强 |
我的建议很直接:如果是新搭建,直接用 7.0 LTS 系列镜像(写本文时对应 tag 是7.0-ubuntu-latest),没必要从 6.0 起步再走一遍升级流程。如果公司已有 6.0 的存量环境,倒也不用急着升,6.0 还在支持期内,半年内做好升级规划即可。Zabbix 版本跨度大的升级不能直接跳,6.0 到 7.0 必须中间经过 6.4 这类过渡版本,步骤比新装复杂得多。
2.2 镜像源配置:先把 docker 下载慢这个拦路虎解决掉
国内部署容器化应用,第一个卡点基本是镜像拉取慢,Zabbix 这几个镜像加起来有好几个 GB,直接拉官方 Docker Hub 能等到天荒地老。提前把 registry mirror 配好,后面能省下大把时间。
在/etc/docker/daemon.json里加上镜像加速地址:
{ "registry-mirrors": [ "https://docker.m.daocloud.io", "https://docker镜像加速地址填入你自己的" ] }然后重启 Docker:
sudo systemctl daemon-reload sudo systemctl restart docker这里多说一句:如果是阿里云容器镜像服务,登录后控制台会给你一个专属于你账号的加速地址,格式类似https://xxxx.mirror.aliyuncs.com,把它填进去效果最稳定。配置好之后先用docker info看一下 Registry Mirrors 字段是否生效,再拉镜像验证速度。
对没有 Docker 的机器,安装 Docker Engine 本身也有讲究。CentOS 7 上推荐用官方 docker-ce 源安装,openEuler 这类系统建议直接参照 Docker 官方文档里对应发行版的安装步骤,不要用系统自带的旧版本 docker 包——老版本的 docker 对 Compose 文件语法支持不完整,排查起来很恼火。另外装完记得把当前用户加进 docker 组,免得每条命令都要 sudo:
sudo usermod -aG docker $USER # 重新登录终端后生效2.3 目录结构与端口规划
我习惯把所有文件放在/opt/zabbix下面,结构统一、备份方便:
/opt/zabbix/ ├── docker-compose.yml ├── data/ │ └── pg/ # PostgreSQL 数据卷目录 ├── alertscripts/ # 自定义告警脚本挂载目录 └── snmptraps/ # SNMP trap 文件目录端口规划按下面的表格来,避免跟现有服务冲突:
| 端口 | 用途 | 暴露位置 |
|---|---|---|
| 8080/TCP | Zabbix Web 页面 | 宿主机对外 |
| 10051/TCP | Server 接收 Agent 上报 | 宿主机对外/内网 |
| 10050/TCP | 宿主机 Agent 被采集 | 宿主机对外/内网 |
| 5432/TCP | PostgreSQL | 不暴露,仅 Compose 网络内 |
选 8080 而不是 80,是因为很多机器上 80 已经被 Nginx 或者其他 Web 服务占了。后面如果要做 HTTPS、要挂域名,可以在宿主机 Nginx 里做反向代理,把域名转发到容器的 8080 端口。
3. docker-compose 编排文件逐行拆解
3.1 一份可直接落地的编排文件
下面这份是我目前生产环境在用的精简版,数据库用 PostgreSQL 16,Zabbix 用 7.0 LTS:
version: '3.8' services: postgres: image: postgres:16-alpine container_name: zabbix-db restart: always environment: POSTGRES_USER: zabbix POSTGRES_PASSWORD: zabbix POSTGRES_DB: zabbix TZ: Asia/Shanghai volumes: - ./data/pg:/var/lib/postgresql/data networks: - zbx_net zabbix-server: image: zabbix/zabbix-server-pgsql:7.0-ubuntu-latest container_name: zabbix-server restart: always environment: DB_SERVER_HOST: postgres POSTGRES_USER: zabbix POSTGRES_PASSWORD: zabbix POSTGRES_DB: zabbix TZ: Asia/Shanghai ports: - "10051:10051" volumes: - ./alertscripts:/usr/lib/zabbix/alertscripts - ./snmptraps:/var/lib/zabbix/snmptraps depends_on: - postgres networks: - zbx_net zabbix-web: image: zabbix/zabbix-web-nginx-pgsql:7.0-ubuntu-latest container_name: zabbix-web restart: always environment: ZBX_SERVER_HOST: zabbix-server DB_SERVER_HOST: postgres POSTGRES_USER: zabbix POSTGRES_PASSWORD: zabbix POSTGRES_DB: zabbix PHP_TZ: Asia/Shanghai ports: - "8080:8080" - "8443:8443" depends_on: - zabbix-server - postgres networks: - zbx_net zabbix-agent: image: zabbix/zabbix-agent2:7.0-ubuntu-latest container_name: zabbix-agent restart: always environment: ZBX_HOSTNAME: "docker-host" ZBX_SERVER_HOST: "zabbix-server" ZBX_PASSIVE_ALLOW: "true" ZBX_ACTIVE_ALLOW: "true" ports: - "10050:10050" networks: - zbx_net networks: zbx_net: driver: bridge把上面内容保存为/opt/zabbix/docker-compose.yml,在目录下执行docker compose up -d就能启动。下面我逐段说清楚每个服务为什么这么配。
3.2 zabbix-server 服务:数据采集核心的配置逻辑
核心环境变量是那套DB_SERVER_HOST、POSTGRES_USER、POSTGRES_PASSWORD、POSTGRES_DB。这里最容易犯的错误是把DB_SERVER_HOST写成localhost——容器里的 localhost 是容器自己,不是宿主机,更不是旁边的 postgres 容器。在 Compose 自定义网络里,直接用服务名postgres做主机名,由 Docker 的内置 DNS 解析到数据库容器,这是整个编排能跑通的前提。
TZ: Asia/Shanghai这一项被很多人忽略,但它极其重要。Zabbix Server 默认时区是 UTC,如果不显式设置成Asia/Shanghai,你会发现历史数据的时间戳比北京时间慢 8 个小时,触发器判断也会跟着乱,告警时段管理基本废掉。
./alertscripts:/usr/lib/zabbix/alertscripts这个挂载是为自定义告警脚本准备的。Zabbix 里有个"脚本"类型的告警媒介,比如发短信、调用内部系统 API,都是执行服务器上的脚本文件。不挂这个目录,后面想加脚本只能docker exec进去改,容器一重建就什么都没了。
snmptraps 目录挂载则是在你打算接收网络设备主动发来的 SNMP Trap 时才需要,如果只用 Zabbix 主动轮询交换机,这个目录可以先不挂。
3.3 zabbix-web 与数据库:前端和存储背后的配合逻辑
Web 容器里ZBX_SERVER_HOST告诉前端页面去哪个地址连接 Server,这里填服务名zabbix-server。PHP_TZ控制前端界面时区,不设置的话,页面上显示的问题发生时间、告警时间同样是 UTC,非常别扭。
PostgreSQL 的数据目录挂载到宿主机的./data/pg,这是这套部署里最不能丢的东西——所有主机配置、模板、历史数据都在这。容器删了无所谓,卷目录没了等于重新搭一套。所以后面做备份的时候,我最优先备份的就是这个目录。
关于数据库用 PostgreSQL 还是 MySQL,Zabbix 官方对两者都支持,但官方镜像里 PostgreSQL 一直是默认参考实现,社区里踩坑的也少。MySQL 8.0 的mysql_native_password认证插件在新版本里默认关闭,不少人在 Zabbix 连 MySQL 时碰到 authentication plugin 报错,PostgreSQL 没这些幺蛾子。新部署我建议直接 PostgreSQL,别在数据库选型上增加变量。
3.4 agent 容器:监控宿主机自身的最简入口
如果你这台机器上跑着 Zabbix Server 本身,你大概率也想监控这台宿主机的 CPU、内存、磁盘,那这个 agent 容器就很有用。它暴露10050端口给 Server 做被动采集,同时自己也会主动推数据。
Agent2 是官方新一代 Agent,性能更好、支持用 Go 插件扩展采集能力,比如直接通过挂载/var/run/docker.sock用"由 Zabbix agent 2 监控 Docker"模板采集容器指标。新环境没必要再用老 agent1 了。
要注意的是,ZBX_HOSTNAME必须跟 Web 前端里添加主机时的"主机名称"完全一致(默认宏{HOST.HOST}也用它来做主动采集匹配)。我见过不少人把这两处名字写得不一致,结果被动监控的键值有数据,主动监控的键值全是"不支持"。
4. 启动初始化与首次纳管:把 Linux、Windows 主机接入监控
4.1 启动服务与基础验证
编排文件写好后,后面的操作其实很少:
cd /opt/zabbix docker compose up -d docker compose ps第一次启动因为要拉好几个镜像,耗时取决于网络。等所有服务状态变为running(或healthy)之后,别急着登录页面,先看一眼日志确认数据库初始化有没有成功:
docker logs -f zabbix-server --tail 50正常情况下你能看到server started之类的字样。看到PostgreSQL server does not respond就说明数据库还没就绪,等一两分钟再试。这是 Compose 编排里很常见的时序问题:depends_on只能保证 postgres 容器启动了,不能保证 PostgreSQL 进程已经能接受连接。Zabbix Server 有自动重试机制,正常情况下等一会就能自己连上,不用手动干预。
4.2 Web 页面初始化流程
浏览器访问http://服务器IP:8080,进入 Zabbix 的安装向导。左侧下拉菜单可以选择界面语言,直接选"中文(zh_CN)"能省不少事。向导里需要填的关键项:
- 数据库地址:填
postgres,不是localhost,也不是宿主机 IP。因为页面容器在 Compose 网络里,只有服务名能正确解析到数据库。 - 数据库端口:默认 5432 即可。
- 数据库名称/用户/密码:对应 Compose 里的
zabbix / zabbix / zabbix。
检查项页面如果某个 PHP 扩展显示红色不通过,说明镜像和版本不匹配,很少见,真遇到了优先检查是不是用了不配套的 web 镜像 tag。
配置完成后进入登录页,默认账号Admin、密码zabbix,登录后第一件事就是去"用户设置"里改密码。这一步经常有人偷懒,监控平台一旦暴露在公网,默认口令不超过一天就会被扫掉。
4.3 "其他主机怎么添加 Zabbix 监控":Linux 主机接入全流程
这个问题我在好几个技术群里被反复问过,核心流程其实就四步:装 Agent → 配 Server 地址 → 前端加主机 → 链接模板。
以一台 CentOS/Ubuntu 业务机为例,最简单的方式是直接装原生 Agent 包。RHEL 系执行:
rpm -Uvh https://repo.zabbix.com/zabbix/7.0/rhel/9/x86_64/zabbix-release-7.0-1.el9.noarch.rpm dnf install -y zabbix-agent2Ubuntu/Debian 系用wget下载对应版本的 deb 包再dpkg -i安装,安装后改/etc/zabbix/zabbix_agent2.conf里的Server=和ServerActive=两项,填上 Zabbix Server 的 IP,然后:
systemctl enable --now zabbix-agent2前端操作路径:配置 → 主机 → 创建主机。主机名称填一个自己看着舒服的名字(比如 web-prod-01),可见名称可以写中文备注;"由 Agent 监控的接口"填 Agent 所在机器的 IP,端口 10050;填完先别着急点添加,在"模板"字段搜索Linux by Zabbix agent,选中链接后保存。
等一两分钟,回到"监测 → 最新数据",按主机筛选,能看到CPU utilization、Memory utilization等数据陆续进来,就说明链路通了。
4.4 Windows 主机与 GPU 监控的特殊处理
Windows 机器从 Zabbix 官网下载对应版本的zabbix_agent2-7.0.x-windows-amd64-static-full.exe,双击安装,在安装向导里填写 Zabbix Server IP,装完服务会自动启动。之后前端添加主机,链接 Windows 模板即可。
Windows 监控里大家问得比较多的是 GPU。默认的Windows by Zabbix agent模板是不采 GPU 指标的,需要额外处理。最直接的办法是让 Agent 执行nvidia-smi:在被监控机器上配置一个自定义 UserParameter,把nvidia-smi --query-gpu=utilization.gpu,memory.used --format=csv,noheader,nounits的输出读出来,再在前端配置对应的 trapper 或自定键值。也可以直接找社区现成的 NVIDIA GPU 监控模板导入。注意前提是被监控机器装了 NVIDIA 驱动且nvidia-smi在 Agent 能看到的环境变量路径里。
此外还有个便利做法:如果想把 Docker 容器本身也纳入监控,在被监控机器上给 Agent2 挂载 docker socket(/var/run/docker.sock),前端链接"由 Zabbix agent 2 监控 Docker"模板,容器的 CPU、内存、状态、健康检查全都能看到。容器化环境里这套组合我几乎每个项目都会用。
5. 告警通道与触发动作:让告警真正打到钉钉和邮箱
5.1 邮件告警是最简单可靠的第一条通道
监控平台没有告警推送,等于装了监控却没装眼睛。Zabbix 的告警链路是三段式:告警媒介(Media)→ 触发器(Trigger)→ 动作(Action)。媒介定义"通过什么方式发",触发器定义"什么情况算有事",动作定义"触发后对谁、发什么"。
邮件是最容易先跑通的。登录 Web,右上角头像 →用户设置 → 告警媒介 → 添加,类型选Email,填收件邮箱,SMTP 服务器、端口、TLS 选项、认证账号密码都填上。如果你是拿网易、QQ 这类邮箱发信,记得用授权码而不是登录密码。
配置完后给当前用户添加好媒介,再到"告警 → 动作"里看自带的Report problems to Zabbix administrators动作。这个默认动作的作用是:任何触发器进入异常状态,就给"Zabbix administrators"用户组里配置了媒介的用户发通知。只要用户组里有你、你有媒介,告警邮件就能发出来。
5.2 钉钉、企业微信 Webhook 告警的关键配置
Zabbix 7.0 的 Web 前端内置了钉钉、企业微信、Slack 等 Webhook 媒介类型,不用再手工写脚本了。以钉钉为例:
- 在钉钉群添加一个自定义机器人,拿到 Webhook 地址和安全设置(加签的密钥)。
- 前端告警 → 告警媒介 → 添加 → 选择类型
DingTalk,填入机器人的 Webhook 地址、加签密钥。 - 给用户设置里添加这个告警媒介。
- 在"动作"里复制一个现有动作,或者直接改默认动作的收件用户。
Webhook 媒介的好处是,Zabbix 已经帮你把告警标题、消息体、@指定人这些逻辑封装好了。第一次发测试消息的时候,钉钉机器人安全设置如果选了"自定义关键词",消息里必须包含你设置的关键词,否则钉钉会直接拒绝推送,这个细节很容易被忽略。
5.3 触发器表达式怎么写,以及如何避免告警风暴
触发器是判断"有没有问题"的规则,比如说 CPU 空闲率低于 20% 持续 5 分钟算告警:
last(/Linux by Zabbix agent/system.cpu.util[,idle])<20注意前面必须写last(/主机名/键名)这种完整路径格式,主机名要和"主机名称"完全一致。写表达式时可以先点"插入宏变量"按钮,可视化选择监控项,不容易写错。
比写触发器更重要的是限流。默认触发器一旦异常,动作会立刻发告警,恢复时发恢复通知。如果一台机器上挂了 50 个触发器,一次网络抖动可能同时触发 30 个,钉钉群瞬间被刷屏,这就是告警风暴。我的处理方式:
- 在触发器配置里设置恢复表达式(即触发异常后,要恢复正常并持续一段时间才算恢复),减少抖动;
- 在动作里配置告警升级等级:比如严重(High)以上才发钉钉,一般级别的只在"监测 → 问题"里显示;
- 给计划内的变更操作提前配置维护周期:比如每周日凌晨数据库备份,把这段时间设成维护,触发器不过期也不发告警。
告警平台做得好不好,很多时候不取决于你能采多少指标,而取决于你发了多少条"没人看的告警"。少而准,永远比多而全强。
6. 容器化日常三大坑:Not Running、数据库密码错乱与时间时区问题
6.1 "zabbix server is not running"到底怎么排查
这个提示基本是 Zabbix 用户遇到最多的报错,页面上显示zabbix server is not running: the information displayed may not be current.原因其实就一个:Web 前端在指定的ZBX_SERVER_HOST上连不上 Server 的 10051 端口。
排查链路按顺序来:
第一步,先确认容器本身活着:
docker ps | grep zabbix如果 server 容器不在列表里,查日志找崩溃原因:
docker logs --tail 100 zabbix-server第二步,如果容器在,但日志里有cannot start alert manager service、database is down之类的信息,按照容器名逐个看 postgres 是否正常,可能是数据库数据卷权限变了,也可能是内存不足导致 PostgreSQL 被 OOM 杀掉。
第三步,确认 Web 容器和 Server 容器网络通不通。两个容器都在同一 Compose 网络时,在 web 容器里执行:
docker exec zabbix-web bash -c "nc -vz zabbix-server 10051"连不通就检查ZBX_SERVER_HOST是否写成了 IP 而不是服务名。
还有一个非常隐蔽的原因:时区没配好导致内部任务报错。之前我在某个环境里看到 Server 日志反复出现timezone相关错误,前端就是这个提示。加上TZ=Asia/Shanghai后重启就好。所以看到这个提示,别急着在网上搜一堆玄学原因,按"容器状态 → Server 日志 → 网络连通 → 时区"这个顺序排查,10 分钟能解决。
6.2 "zabbix access denied for user 'replace_user'@'localhost'"这类数据库报错
这个报错我在帮人远程看问题时遇到过一次。搜出来的报错原文大致是zabbix access denied for user 'replace_user'@'localhost' (using password: YES)。replace_user这个用户名一看就知道不是真实用户,它是官方镜像里环境变量未正确传入时的一个占位符。
根因通常是:你改了 compose 文件里的密码或用户名,但数据库数据卷里已经用旧的凭证初始化过了。比如第一次启动时用POSTGRES_PASSWORD=abc,后来改成xyz,但./data/pg目录里 PostgreSQL 的数据还是老样子,Server 用新密码去连,数据库当然拒绝。
解决办法分两种情况。如果数据不重要,直接清掉数据卷重建:
docker compose down # 确保 data/pg 目录里没有重要数据再执行 rm -rf data/pg docker compose up -d如果数据重要,就不能删卷了,得用docker exec进入 postgres 容器里,用psql修改 zabbix 用户的密码,让它和你 compose 文件里的一致。不管哪种方案,核心教训是:数据库卷初始化后,凭证就不能随便改了,要么改回旧值,要么改数据库里的用户密码,保持前后一致。
6.3 页面时间差 8 小时、图表中文乱码
时间差 8 小时这个问题我在新搭建的 Zabbix 上几乎必见一次。表象是"最新数据"里的时间比当前时间晚 8 小时。原因前面提过:Server、Web、数据库三处时区不一致。RHEL 系的宿主机默认 UTC,如果你的 compose 文件里没配TZ和PHP_TZ,容器就跟着宿主机走。解决办法是把三个容器的环境变量都补上TZ: Asia/Shanghai,Web 另加PHP_TZ: Asia/Shanghai,docker compose up -d重建生效。
中文乱码发生在图形监控页。Zabbix 自带的镜像里没有中文字体,当监控项名称、主机名称里有中文时,图形里的中文就显示成一堆方块。解决办法是往 Web 容器里装中文字体:
docker exec -it zabbix-web bash -c "apt-get update && apt-get install -y fonts-noto-cjk"装完在"监测 → 图形"页面刷新就能看到正常中文。注意容器重建后这个修改会丢失,所以要么写进 Dockerfile 重新构建,要么在 compose 里把字体文件目录挂载进去。我给生产环境用的方案是:在宿主机放好一个msyh.ttf或者 Noto CJK 字体文件,挂载到容器的字体目录。
6.4 交换机等网络设备监控:SNMP 的正确打开方式
网络设备不支持装 Agent,全靠 SNMP 协议来监控。以一台千兆交换机为例,流程分三步。
第一步,在交换机上开启 SNMP v2c(以华为为例):
snmp-agent snmp-agent sys-info version v2c snmp-agent community read cipher public_zabbix第二步,在前端数据采集 → 主机 → 创建主机,主机接口类型选SNMP,填交换机的管理 IP,端口 161,SNMP 版本和团体名(community)填对应值。
第三步,链接模板。Zabbix 自带的模板库里有Generic by SNMP、Network device by SNMP这样的模板,可以采集接口状态、流量、CPU 内存(如果设备支持)。带宽数据的本质是从ifHCInOctets、ifHCOutOctets(64 位计数器)算出来的,模板里已经封装好了,你只要关注哪些接口需要监控,把不用的接口从模板里剔除就行。
这里有个实操细节:很多网络设备同时返回很多接口(包括空口),默认模板会把所有接口都纳入监控,首页列表会特别长。建议在模板里用正则过滤器把eth-trunk、vlanif等关键接口过滤出来。另外 SNMP 轮询间隔别设太短,默认 1 分钟足够,太频繁会让老设备 CPU 飙升。
7. 从能用走向好用:监控大屏、自动发现与备份升级
7.1 监控大屏:先用好 Zabbix 自带的,再考虑 Grafana
"监控大屏"是热词,也是很多团队在监控建设初期就想要的东西。其实 Zabbix 自带的仪表板功能已经能做相当漂亮的展示:监测 → 主机 → 仪表板,可以拖拽图表组件,支持饼图、线图、单值、拓扑图,还能在多个仪表板之间做轮播(幻灯片模式)。把大屏投到办公室的电视上,完全够用。
如果对视觉效果要求更高,再考虑 Grafana + Zabbix 数据源插件。Grafana 的图表渲染确实漂亮,但引入它意味着多维护一套系统、多学一套面板语法。我的建议是先把自带的 Dashboard 用熟,真正有业务价值、需要统一展示多套监控数据时再上 Grafana。一上来就搞双平台,容易两头都没用好。
7.2 设备一多,自动发现和自动注册是刚需
当你从监控 10 台机器扩展到上百台时,手动一台台添加主机就不可行了。Zabbix 提供了两条自动化路径:
Agent 自动注册:在被监控机器的 Agent 配置里加一行HostMetadata=linux-server,然后在前端告警 → 动作 → 自动注册动作里配置规则:当收到带这个元数据的新 Agent 时,自动添加到指定主机组、链接指定模板、设置指定用户作为联系人。新机器装好 Agent 后,一两分钟内就自动进入监控系统了。
网络发现:适合自动发现网段里的交换机等 SNMP 设备。数据采集 → 发现 → 创建发现规则,填 IP 段、SNMP 团体名、扫描间隔,再把"发现动作"配置成自动链接 SNMP 模板。适合资产交接不清晰的老环境,扫一遍基本能知道自己到底有多少设备活着。
7.3 备份与升级:这两个操作永远先做备份
容器化部署让备份变得极其简单,核心就两件事:配置文件 + 数据库数据卷。
数据库的在线备份用 pg_dump:
docker exec zabbix-db pg_dump -U zabbix zabbix > zabbix_backup_$(date +%F).sql恢复时把备份文件放进容器再psql导入即可。除了数据库,/opt/zabbix整个目录(docker-compose.yml、alertscripts、data 目录)也建议纳入定期备份。
升级 Zabbix 前,我个人的习惯流程是:先备份数据库和 /opt/zabbix 目录 → 修改 compose 文件里的镜像 tag(比如 7.0 的小版本更新)→docker compose pull→docker compose up -d→ 看日志确认数据库迁移完成 → 登录页面确认数据还在。
Zabbix 7.0 的小版本升级(比如 7.0.0 到 7.0.5)相对平滑,但大版本升级绝不要在生产环境直接跳,一定先在测试环境验证一遍,确认模板和自定义脚本都兼容后再动线上的。
7.4 最后分享一点个人体会
围绕 Docker 部署 Zabbix 这套方案,前前后后我在不下十个环境里实践过,最大的体会是:容器化真正解决的问题不是"部署快",而是"可预期"。哪个组件需要什么依赖、什么版本、什么环境变量,全部写在 docker-compose.yml 里,新环境拉下来就能跑,不需要赌运气。
给刚入门的读者一个实用建议:第一次搭,不要一上来就追求把所有设备、所有指标都纳进来。先把 Server 自己监控好,再加两三台核心机器,把告警通道跑通,再逐步扩展。告警阈值、维护时段这些,都是在实际运行一两周之后才慢慢调优的。你不需要一次做到完美,但你需要先让这套系统转起来,再让它越转越顺手。