ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

用Docker Compose部署Zabbix 7.0监控系统:从镜像选型到告警配置全指南

用Docker Compose部署Zabbix 7.0监控系统:从镜像选型到告警配置全指南 1. 为什么用 Docker 跑 Zabbix而不是直接装在物理机聊到 Zabbix 这套监控系统很多刚接触的人第一反应是不就是装个服务端、配个数据库、再装个 Agent 吗真上手之后才发现坑全藏在细节里——版本兼容、PHP 扩展缺失、数据库字符集不对、前端连不上服务端……一套搞下来大半天就没了。我在生产环境里踩过一轮之后现在新环境基本都是走 Docker 部署尤其是 Zabbix 7.0 以后官方镜像体系已经非常成熟用容器编排可以省掉大量环境层面的琐碎问题。用 Docker 部署 Zabbix说白了就是把原来需要手动安装、配置、调参的多个组件Server、Web 前端、数据库、Agent全部塞进标准化的容器里通过镜像版本和编排文件统一管理。这套方案最直观的好处有三个首先是环境隔离Zabbix Server 依赖的 PHP 扩展、数据库连接库、时区设置等全都固化在镜像里不会污染宿主机其次是升级回滚方便镜像版本一变就能整体切换出问题也能秒回退最后是迁移成本低export 一份 compose 文件和挂载目录换台机器直接拉起这在物理机部署时代是想都不敢想的。还有一个常被忽视的点Zabbix 是个组件多、关联复杂的系统Server、前端、DB、Agent、Proxy 各有各的生命周期手动部署时经常出现版本错配。Docker 镜像的 tag 本身就是一套版本对齐的协议比如用zabbix/zabbix-server-pgsql:7.0-ubuntu和zabbix/zabbix-web-nginx-pgsql:7.0-ubuntu镜像名里的pgsql后缀说明这个 Server 镜像已经内置了连接 PostgreSQL 的驱动配置只要用同一版本 tag基本不会出现组件间握手失败的问题。当然Docker 部署也不是银弹。如果你的监控规模到了上万台设备、每秒处理几十万条指标那容器化的性能损耗和运维复杂度反而会变成瓶颈那种场景建议直接上物理机 Zabbix Proxy 分层的架构。但对绝大多数中小团队几百台服务器、交换机、VMware 虚拟机这种规模Docker 部署的生产力优势是碾压级的。所以我这篇就基于 Zabbix 7.0 LTS 版本带你把整套环境从零拉起来包括容器编排、数据持久化、Agent 接入、告警通知这几个核心环节最后再把我在实际部署中碰到的坑一并列出来。适合两类人看一是刚接触 Zabbix、想快速搭一套环境练手的运维新人二是已经在用 Zabbix 但还在物理机部署、想平滑迁移到容器方案的团队。2. 部署前的思路拆解与组件选型2.1 整套系统的组件构成Zabbix 的逻辑架构其实不复杂但组件之间的关系要理清楚。一个最小可用的生产级部署至少包含四块Zabbix Server核心调度进程负责数据收集、触发器计算、告警生成。它自己不存数据需要连数据库。数据库存放配置、历史数据、趋势数据。Zabbix 支持 PostgreSQL 和 MySQL7.0 版本同时对两者提供官方镜像支持。Zabbix Web 前端Nginx PHP-FPM 的 Web 界面通过 PHP 的 PDO 扩展连数据库通过 API 跟 Server 通信。用户日常操作都在这一层。Zabbix Agent部署在被监控主机上的采集进程主动或被动上报指标。如果你的监控规模较大还会加一层 Zabbix ProxyProxy 承担边缘采集和缓冲的职责把压力从中心 Server 卸掉。但这篇先不展开 Proxy先把最核心的主链路搭通。2.2 数据库选型PostgreSQL 还是 MySQL官方镜像里Server 和 Web 前端都有两个变体-pgsql和-mysql。我推荐用 PostgreSQL理由不复杂Zabbix 内部有大量依赖 SQL 特性的操作比如分区表、并行查询、JSONBPostgreSQL 在高版本上对复杂查询的优化能力更强历史数据清理housekeeper的配合度也更好。另外Zabbix 官方文档中性能调优章节的示例大多基于 PostgreSQL遇到问题更容易找到对口的参考资料。MySQL 也不是不行如果你团队对 MySQL 更熟、已有高可用的 MySQL 集群想复用那就直接用-mysql镜像对外行为完全一致。这里不存在哪个不能用的问题只有哪个更顺手的问题。2.3 网络规划容器间通信组件要互相通信就需要一个共享网络。Docker Compose 会默认创建一个 bridge 网络容器之间通过服务名互相解析。这个设计很关键Zabbix Server 连接数据库时数据库地址直接填 compose 里的服务名比如postgresWeb 前端连接 Server 时地址填zabbix-server。用服务名而不是写死 IP容器重建时 IP 变了也不受影响。另外要给 Web 端口留好宿主机映射。一般习惯用 8080 映射到容器里的 80或者直接用 10051Server 的 trapper 端口映射出去供 Agent 上报。具体端口规划我下面会细说。2.4 存储规划持久化什么容器是无状态的重启后文件系统重置所以需要持久化的数据必须挂载到宿主机目录或命名卷。Zabbix 部署里需要持久化的东西有数据库数据文件这是最重要的丢失等于监控历史全部清零。Zabbix Server 的配置文件可选如果你手动改过zabbix_server.conf的某些参数建议挂载出来。Web 前端的 PHP 配置可选改了php-fpm参数或时区配置时用。我在生产环境里的习惯是所有持久化数据统一放在/opt/zabbix/下按组件分子目录数据库数据放./data/pgsql配置覆盖放./config。这样备份、迁移、定位问题都非常直观。3. 实操用 Docker Compose 拉起全套 Zabbix3.1 环境准备先确认宿主机条件。Zabbix Server 本身不算吃资源但数据库和前端进程跑在同一台机器上建议至少 2 核 4GB 内存起步磁盘 20GB 以上历史数据的增长速度取决于监控项数量和 retention 周期。如果你的监控对象不到 50 台这个配置足够跑一年。宿主机需要安装 Docker Engine 和 Docker Compose 插件。我用的是 Ubuntu 22.04Docker 版本 24Compose v2。安装方法这里不展开了官方文档写得已经非常清楚装完记得执行docker compose version确认版本。注意Docker 镜像仓库在国内访问速度不稳定是个老问题如果拉镜像超时可以配置 registry mirror 加速。我在/etc/docker/daemon.json里配置了 Docker Hub 的镜像加速地址改完重启 docker 服务生效。3.2 目录结构与 compose 文件我在/opt/zabbix下创建整个项目mkdir -p /opt/zabbix/{data/pgsql,config/server,config/web}目录结构解释data/pgsqlPostgreSQL 数据文件的挂载目录config/server放自定义的 zabbix_server.conf可选config/web放自定义的 PHP 配置可选然后写docker-compose.yml。这是整套环境的核心文件我要把每个参数为什么这么写解释清楚version: 3.8 services: postgres: image: postgres:16-alpine container_name: zabbix-postgres restart: unless-stopped environment: POSTGRES_USER: zabbix POSTGRES_PASSWORD: zabbix_pass_2024 POSTGRES_DB: zabbix volumes: - ./data/pgsql:/var/lib/postgresql/data networks: - zabbix-net zabbix-server: image: zabbix/zabbix-server-pgsql:7.0-ubuntu container_name: zabbix-server restart: unless-stopped environment: DB_SERVER_HOST: postgres POSTGRES_USER: zabbix POSTGRES_PASSWORD: zabbix_pass_2024 POSTGRES_DB: zabbix ZBX_STARTPOLLERS: 10 ZBX_STARTPOLLERSUNREACHABLE: 2 ZBX_STARTTRAPPERS: 4 ZBX_CACHESIZE: 64M ZBX_HISTORYCACHESIZE: 64M ZBX_TRENDCACHESIZE: 64M ports: - 10051:10051 volumes: - ./config/server:/etc/zabbix/zabbix_server.conf.d:ro depends_on: - postgres networks: - zabbix-net zabbix-web: image: zabbix/zabbix-web-nginx-pgsql:7.0-ubuntu container_name: zabbix-web restart: unless-stopped environment: ZBX_SERVER_HOST: zabbix-server DB_SERVER_HOST: postgres POSTGRES_USER: zabbix POSTGRES_PASSWORD: zabbix_pass_2024 POSTGRES_DB: zabbix PHP_TZ: Asia/Shanghai ports: - 8080:8080 depends_on: - zabbix-server networks: - zabbix-net networks: zabbix-net: driver: bridge逐个解释关键点postgres镜像没有用 Zabbix 官方打包的镜像而是直接用官方的postgres:16-alpine。为什么Zabbix 官方也有zabbix/zabbix-server-pgsql依赖的数据库镜像变体但实际上数据库本身不需要任何 Zabbix 定制初始化过程就是建库建用户建表。直接用标准 PG 镜像反而更干净也方便后续单独对数据库做备份和调优。Alpine 版本的镜像体积小作为数据服务足够用。POSTGRES_PASSWORD在 compose 文件里写明文仅限内网测试环境。生产环境建议通过环境变量替换或 Docker secrets 管理至少别把密码提交到 Git 仓库。ZBX_STARTPOLLERS等变量是 Zabbix Server 的并发进程数配置。POLLER 负责主动轮询被监控设备TRAPPER 负责接收 Agent 主动上报的数据。默认的 5 个 poller 对于几十台设备够用我习惯调高到 10 个给后续扩容留余地。Web 端口映射到 8080 是因为宿主机 80 端口可能被其他服务占用。Zabbix Web 容器内默认监听 8080镜像内 Nginx 配置决定外部访问http://宿主机IP:8080。depends_on只保证服务启动顺序不保证依赖服务已经就绪。PostgreSQL 启动到可以接受连接需要几秒所以第一次启动时 Server 容器可能会报 connection refused这是正常的容器重启策略会自动重试。3.3 首次启动与数据初始化compose 文件就位后执行cd /opt/zabbix docker compose up -d第一次启动需要拉镜像并初始化数据库。PostgreSQL 容器创建时会自动执行建库建用户操作Zabbix Server 第一次启动时会自动创建 schema 并写入初始数据。这个过程耗时取决于机器性能和网络通常 1~3 分钟。你可以用下面的命令观察日志确认初始化是否完成docker compose logs -f zabbix-server当日志出现类似server started的关键字说明 Server 已经成功连接数据库并启动。再确认 Web 是否就绪docker compose ps所有服务状态为Up且没有持续重启Restarting状态基本就没问题了。3.4 前端初始化浏览器访问http://宿主机IP:8080会进入 Zabbix 前端安装向导。首次安装需要填数据库连接信息注意这里的Database host不要填127.0.0.1或宿主机 IP因为 Web 容器访问的是 Docker 网络里的数据库服务要填 compose 里的服务名postgresDatabase host:postgresDatabase port:5432默认Database name:zabbixUser:zabbixPassword:zabbix_pass_2024填完后 Zabbix 会校验数据库连接并写入配置文件。安装完成后默认登录账号是Admin密码是zabbix。首次登录后强烈建议立刻修改默认密码。3.5 接入第一台被监控主机Web 界面能打开整个系统的主链路就算通了。接下来把你手头的一台 Linux 服务器接入监控验证端到端的数据流。在被监控的 Linux 主机上安装 Zabbix Agent这里以 Ubuntu/Debian 为例wget https://repo.zabbix.com/zabbix/7.0/ubuntu/pool/main/z/zabbix-release/zabbix-release_7.0-1ubuntu22.04_all.deb dpkg -i zabbix-release_7.0-1ubuntu22.04_all.deb apt update apt install -y zabbix-agent修改 Agent 配置/etc/zabbix/zabbix_agentd.conf最关键的是 Server 地址和主机名Server宿主机IP ServerActive宿主机IP:10051 Hostnameserver01Server是被动检查白名单Agent 只接受来自这个 IP 的请求。ServerActive是主动上报的服务器地址Agent 会主动连接这里的 10051 端口。Hostname必须与 Zabbix Web 前端里配置的主机名完全一致否则 Agent 数据上报后无法匹配到主机。重启 Agentsystemctl restart zabbix-agent然后回到 Web 前端在数据采集 → 主机里点击创建主机主机名填server01填写宿主机 IP端口默认 10050Agent 被动端口添加一个模板比如 Linux by Zabbix agent保存后稍等片刻主机状态应该会变为已监控可用性显示绿色 ZBX。到这里一条完整的采集链路就走通了。4. 监控核心原理与告警通知配置4.1 采集方式怎么选主动还是被动Zabbix 的 Agent 采集有两种模式这也是新手经常会混淆的地方被动模式Zabbix Server 主动连接到 Agent 的 10050 端口请求数据。服务端是发起方Agent 响应。主动模式Agent 周期性地主动连接到 Server 的 10051 端口上报数据。Agent 是发起方。两种模式在 Web 配置里的区别体现在模板上Linux by Zabbix agent active 这个模板里的监控项都是主动模式key 以agent.ping、system.cpu.load等开头类型是 Zabbix agent (active)而 Linux by Zabbix agent 则混合了两种。实际部署我的建议是一台主机只启用一种模式不要混用。如果被监控主机数量较大几百台以上或者网络中有防火墙限制入站连接优先用主动模式。主动模式下 Server 只需要开放 10051 端口等待上报Agent 不用开放入站端口网络层面更安全。小规模内网环境几十台用被动模式配置更简单模板条理也更清晰。这个选择同时会影响端口规划。如果你只用主动模式宿主机并不强制要映射 10051 端口Server 作为接收方仍然监听 10051但不需要映射到宿主机的公网接口内网 Docker 网络即可互通如果用被动模式必须保证 Server 能访问到 Agent 的 10050 端口同时 Agent 能访问到 Server或 proxy的 10051 端口。4.2 触发器怎么判断出事了光有数据还不够监控系统的核心价值在于异常时能发现并通知。Zabbix 里这个机制叫触发器。一个触发器本质上是一条表达式基于监控项的最新值或聚合值做逻辑判断。比如CPU 负载连续 5 分钟超过 4last(/server01/system.cpu.load[percpu,avg1])4或者磁盘可用空间低于 10GBlast(/server01/vfs.fs.size[/,free])10G触发器有多个严重级别从低到高分别是未分类、信息、警告、一般严重、严重、灾难。你在创建触发器的时候可以设置对应的级别后续告警通知可以根据级别决定渠道和行为比如只把严重以上的发短信警告级别的发邮件。新手常犯的一个错误是直接把阈值定死不看监控项的历史数据趋势。正确做法是先让监控项跑几天观察正常波动范围再根据真实数据设定报警阈值。否则很容易出现告警轰炸——一天几百条邮件到最后你恨不得把它关掉。4.3 告警媒介配置邮件通知Zabbix 告警链路是三段式媒介 → 用户 → 动作。任何一个环节没配好告警都发不出去。先配置告警媒介。管理员登录后在报警 → 媒介类型里选择 Email配置 SMTP 服务器信息。这里建议用 SMTP 而不是本地 sendmail因为容器环境里根本没有本地 MTA。配置要点SMTP 服务器填你的邮件服务商地址比如smtp.example.comSMTP 服务器端口一般 465SSL或 587STARTTLSSMTP HELO填发送方域名连接加密选 SSL/TLS用户名/密码发信邮箱的登录凭证然后创建一个接收告警的用户或者在 Admin 用户上直接配置在报警媒介标签页添加刚配好的 Email收件人填你的邮箱地址并设置当严重级别为警告及以上时通知。最后配置动作。在报警 → 动作里创建动作触发条件选触发器严重级别 ≥ 警告操作里配置发送消息给用户——这里选择接收告警的用户并按条件比如仅发送通知生成标题和内容模板。Zabbix 的告警消息模板支持宏变量比如标题{TRIGGER.STATUS}{TRIGGER.NAME} 内容 主机{HOST.NAME} IP{HOST.IP} 时间{EVENT.DATE} {EVENT.TIME} 当前值{ITEM.VALUE}用宏的好处是消息内容动态化不会出现每条告警都长一个样、关键时刻没法快速定位是哪台机器出问题的情况。4.4 企微/钉钉/飞书机器人告警邮件适合中低优先级的事件流但真正分秒必争的故障比如机房断电、主库宕机邮件往往不够即时。现在国内团队普遍用企微、钉钉、飞书的群机器人收告警。Zabbix 6.0 之后自带 Webhook 媒介类型可以通过 webhook 把消息推进群机器人。配置思路是创建 Webhook 媒介类型配置请求 URL群机器人的 webhook 地址把 Zabbix 的消息模板转换为机器人要求的 JSON 格式。以钉钉为例机器人的自定义关键词必须出现在消息正文里比如zabbix把 Zabbix 消息用宏拼成一个带关键词的 JSON body然后发送 POST 请求。Zabbix 会在触发器和恢复通知时调用这个 webhook效果就是群里的告警消息卡片。这套逻辑跟邮件其实是一套链路媒介配好 → 用户绑定 → 动作里引用。区别只是媒介类型选 Webhook要额外处理一下消息格式。5. 数据持久化、备份与升级回滚5.1 数据库备份策略监控系统的数据一旦丢失历史趋势、告警记录全部归零对排障来说是很大的损失。所以数据库备份是必须做的日常操作。最直接的方式是用pg_dump对 Zabbix 数据库做逻辑备份保留建表语句和数据恢复灵活。备份命令docker exec zabbix-postgres pg_dump -U zabbix -d zabbix -F c -f /tmp/zabbix_backup.dump然后将容器内的 dump 文件复制到宿主机docker cp zabbix-postgres:/tmp/zabbix_backup.dump /opt/zabbix/backup/恢复时docker exec -i zabbix-postgres pg_restore -U zabbix -d zabbix --clean /tmp/zabbix_backup.dump生产环境建议做定时备份用 crontab 每日凌晨执行保留最近 7 天的备份文件。如果你想更省事也可以给 PostgreSQL 容器装物理备份工具如 pgBackRest但那是另一个话题了。5.2 升级与回滚镜像 tag 的管理Docker 部署的优势在升级时体现得最明显。Zabbix 官方 LTS 版本会持续维护比如 7.0.x 的补丁版本更新升级操作其实就是改一下 compose 文件里的镜像 tagimage: zabbix/zabbix-server-pgsql:7.0.1-ubuntu改成新版本号然后docker compose up -d重新拉取并重建容器。但是有个关键点Zabbix Server 和 Web 前端的版本必须对齐否则前端可能因为后端数据结构不一致而报错。我的习惯是 Server、Web、Agent 的 tag 统一用同一个版本号避免版本错配。升级前务必先备份数据库。虽然 Zabbix 支持跨小版本升级但数据库 schema 可能会自动变更如果升级到一半失败回滚到旧镜像再去连已经变更的 schema反而会出问题。有备份在手心里不慌。5.3 告警配置的备份与 Git 管理很多人只备份数据库忽略了配置文件。实际上 Zabbix 的配置数据主机、模板、动作、媒介都存在数据库里逻辑备份已经把配置一起带上了。这一点跟 Prometheus 那种配置即代码的模式不同Zabbix 的配置都在数据库里所以数据库备份足够。但如果你想用 Git 做模板版本管理可以把 Web 前端导出的模板 YAML 文件放进 Git 仓库。Zabbix 支持模板的导出/导入跨环境迁移时这套流程非常方便。我的做法是把常用的模板Linux、Windows、SNMP 设备、Docker 等导出为 YAML 存入 Git新环境搭建完直接导入省去手动重建模板的重复劳动。6. 常见问题与排查技巧实录这部分是我实际部署和帮助别人排查时遇到最多的几个问题列出来当速查表用。6.1 Zabbix Server 日志报数据库连接失败现象docker compose logs zabbix-server里出现failed to connect to database。排查思路先确认 PostgreSQL 容器是否在运行docker compose ps确认 compose 里的DB_SERVER_HOST是否填的postgres服务名不是 IP确认数据库账号密码是否匹配。PostgreSQL 容器默认只有在第一次初始化时才创建用户如果你中途改过POSTGRES_PASSWORD但数据目录已有旧数据新密码不会生效。用docker exec进入 postgres 容器手动验证psql -U zabbix -d zabbix -c select 1能返回结果说明数据库本身正常。一个隐藏坑如果./data/pgsql目录已经存在且里面有旧数据而你在 compose 里换了数据库密码PostgreSQL 会忽略新密码继续用旧密码。此时要么改密码ALTER USER zabbix WITH PASSWORD 新密码要么清空数据目录重新初始化。6.2 Web 前端打不开或白屏现象访问http://IP:8080页面加载不出来。排查思路先看容器状态docker compose ps确认 zabbix-web 是Up状态而不是Restarting。看 web 容器日志docker compose logs zabbix-web。常见报错是 PHP 连接数据库超时或权限问题。确认数据库服务名。Web 容器的DB_SERVER_HOST也必须是postgres服务名而不是宿主机 IP。还有一个经常被忽略的点Zabbix Web 容器默认监听 8080 端口。如果你是按网上老教程写的ports: - 8080:80实际上把宿主机的 8080 映射到了容器内的 80而容器内 Nginx 根本没有监听 80所以怎么访问都不通。正确写法是- 8080:8080。6.3 Agent 显示灰色、不可达现象Web 前端主机列表里Agent 的可用性显示灰色或者红色 ZBX。排查思路检查 Agent 配置里的Server是否指向 Zabbix Server 宿主机 IP不是被监控主机自己。检查防火墙宿主机上测telnet 被监控主机IP 10050被监控主机上测telnet 宿主机IP 10051。检查 Agent 是否在运行systemctl status zabbix-agent。检查 Web 前端主机配置里的 IP 地址和端口默认 10050是否正确。如果启用的是主动模式检查主机名前端的主机名必须和/etc/zabbix/zabbix_agentd.conf里的Hostname完全一致大小写也区分。这里有个经验用zabbix_get命令可以快速定位问题。在 Server 容器或宿主机安装 zabbix-get 后执行zabbix_get -s 被监控主机IP -p 10050 -k agent.ping返回1说明 Server 到 Agent 的被动通道正常问题在别处返回超时则说明网络不通或 Agent 配置有误。6.4 SNMP 设备监控不到数据场景用 Zabbix 监控交换机、路由器、UPS 等网络设备时添加了主机、配了 SNMP 模板但数据一直是空的。排查思路先用 snmpwalk 手动验证snmpwalk -v2c -c public 设备IP .1.3.6.1.2.1.1.1.0能返回系统描述说明 SNMP 本身可用。连不上就检查设备的 SNMP 开关、community 字符串、ACL 限制。检查 Zabbix 主机配置里的 SNMP 接口IP/端口/版本/community 是否和实际设备一致。注意 Zabbix 里 SNMP 接口的 IP 是单独配置的不是默认的主机 IP。SNMP 模板里的键值和设备支持的 MIB 要对应。不同厂商华为、思科、H3C的部分 OID 有差异可能需要复制模板并修改 OID 适配。6.5 磁盘空间被历史数据撑爆场景跑了几个月后发现宿主机磁盘越来越小最后一看是 PostgreSQL 的数据目录特别大。这是正常的Zabbix 默认的 history 数据保留时间是 31 天趋势数据保留 365 天。大量监控项在高频采集下数据增长速度远超你想象。解决办法是在 Web 前端管理 → 常规 → 历史数据里调整保留策略或者给数据库单独挂一个更大的数据盘。另外 Zabbix 自带 housekeeper 进程会定期清理过期数据但如果数据量太大housekeeper 清理速度跟不上插入速度也会造成堆积。可以通过调大ZBX_HOUSEKEEPERFREQUENCY和ZBX_MAXHOUSEKEEPERDELETE参数来加快清理节奏。7. 一些我的实操心得整套环境搭完后我个人的体会是Docker 部署 Zabbix 这件事真正的价值不在于装得快而在于让监控系统变成一种可复制的、标准化的交付物。同样的 compose 文件和目录结构拿到新的服务器上五分钟就能拉起一套和现有环境完全一致的服务这种可重复性在物理机部署方式下很难实现。最后再分享一个小技巧如果你打算用这套方案覆盖比较大的监控规模比如 200 台以上建议从一开始就把 Zabbix Proxy 纳入架构而不是等 Server 扛不住再临时加。Proxy 的部署方式和 Server 几乎一样也是一条 compose service配置好ZBX_HOSTNAME指回 Server 即可。提前把 Proxy 铺到你的各个机房或网络分区采集压力就地消化中心 Server 只做汇聚和告警后面扩容会从容很多。监控系统的搭建只是第一步真正考验人的是后续的阈值调优、告警降噪、模板维护。一个健康的监控平台应该是告警稀少但每一条都值得处理而不是每天几十条但全都没人看。带着这个目标去调你的触发器你会回来感谢我的。
返回列表