尧图精选

使用Docker Compose快速部署Zabbix企业级监控告警平台

🕒 发布时间:2026/9/16 3:19:58 📁 来源:尧图网络
我最早接触 Zabbix 还是 4.x 时代那时候想在 CentOS 7 上完整跑起来光是编译 PHP 扩展、折腾字符集、处理 MySQL 权限就能耗掉一个下午常常环境装好了激情也磨没了。后来 Docker 普及Zabbix 官方出了容器镜像部署门槛直线下降。这篇就来聊聊怎么用 Docker Compose 把一套 Zabbix 企业级监控告警平台快速搭起来从架构规划、版本选型到容器编排、添加主机、配置告警、日常排错一条线走完。不管你是刚接触监控的新人还是已经在传统方式里挣扎过的老手这套思路都能让你省掉大量无效的时间成本直接把监控能力落地。1. 为什么要在 Docker 里跑 Zabbix——先搞清楚这件事再做1.1 传统部署的痛点到底在哪很多人以为 Zabbix 难用其实它的功能设计和文档在开源监控里已经算非常成熟的了真正劝退人的是环境搭建环节。Zabbix Server 是 C 写的服务端前端是 PHP 应用数据存在 MySQL 或 PostgreSQL 里一个完整的运行环境至少牵扯到 Web 服务器、PHP 扩展、数据库、服务进程四层依赖。传统部署方式下你需要手工装 Nginx 或 Apache、编译安装 PHP 模块、初始化数据库、再用源码包编译 Zabbix Server。每一步都有版本兼容问题PHP 版本太新不行、数据库排序规则不对导致建表失败、依赖库缺失等等随便一个报错都能让人卡上半天。我印象很深的一次任务同事在一台 CentOS 7 上按照官方文档装 Zabbix 6.4卡在 PHP 的 gd 扩展上系统自带的 PHP 版本太旧装新版又牵动一堆依赖最后他直接放弃了。我说换个思路用 Docker 跑他还不信结果我把没启动成功的机器上的 docker-compose 文件丢到新机器上十分钟后监控页面就出来了。这就是容器化的威力它把最恶心的环境适配问题变成了一次性的镜像构建问题。1.2 Docker 化部署带来的几个核心收益用 Docker 跑 Zabbix 的优势我总结下来主要是这四点第一环境一致性极强。镜像里已经包含了代码和运行时依赖只要宿主机有 Docker 引擎就能把同样的一套服务跑起来。同一份 compose 文件在不同机器上执行结果基本一致。第二升级和回滚变得轻松。官方镜像的 tag 就是版本标识想升到新版本直接把镜像 tag 改掉再 docker compose up -d 即可。出了故障把 tag 切回旧版也能快速恢复虽然数据库结构回滚有限制但至少应用本身可以秒级处理。第三数据和服务解耦。数据库数据放在 volume 或挂载目录里容器删除重建不影响数据。服务进程生命周期由 Docker 管理挂掉后 restart 策略会自动拉起减少人工介入。第四组件隔离和服务编排方便。MySQL、Server、Web 前端、Agent 各跑各的容器用 docker-compose 一次启动依赖关系、端口映射都写在配置里比一堆脚本去管理进程清晰太多。当然容器化也不是银弹。容器内的日志全部输出到 stdout排错要多 docker logs 而不是直接翻文件直接 exec 进容器调试受限一些编辑器不是没有就是不顺手。把这些都考虑进去之后总体收益仍然远大于成本。1.3 什么场景建议首选 Docker 部署根据我自己的经验Docker 化适合这几类情况测试环境快速验证功能、中小团队从零构建监控能力、已经有容器化习惯的运维团队、想通过 CI/CD 流程自动化构建监控平台本身的场景。反过来如果你所在的运维环境是离线内网、内核版本过于老旧、或者对容器安全策略限制严格传统二进制部署也可能更适合那就不必强行容器化。关键是评估自家现状别为了“用 Docker” 而引入新问题。2. 部署前想清楚的三件事版本、架构与网络规划2.1 版本选择与官方镜像说明Zabbix 目前的长期支持版本主要集中在 6.0 LTS 和 7.0 LTS 两条线上。6.0 经过多年的补丁迭代稳定性和兼容性已经验证得很充分很多企业还在使用7.0 带来了全新 UI 组件对时区、主题、可视化交互有较大提升但部署侧其实差异不大。我个人的建议是新项目可以直接上 7.0 LTS如果想求稳或者你需要对旧模板的兼容性做充分测试那 6.0 也很合适。官方镜像主要的几个角色如下zabbix/zabbix-server-mysql监控服务端负责数据收集、触发器计算、告警判断。zabbix/zabbix-web-nginx-mysqlWeb 前端内置 Nginx 和 PHP-FPM提供界面访问。zabbix/zabbix-web-apache-mysqlWeb 前端的 Apache 版本如果你更习惯 Apache 生态可以选它。zabbix/zabbix-agent被监控端代理主动或被动上报主机状态。zabbix/zabbix-java-gateway主要用于 JMX 监控如果你要监控 Java 中间件就值得加一个。镜像 tag 通常带 -ubuntu-latest 或 -alpine-latest 这类后缀。我比较推荐 ubuntu 变体因为 alpine 变体镜像虽然更小但容器内的调试工具很少遇到问题想用 bash、nc、curl 之类的常用命令都找不到排错会非常痛苦。生产环境还应该锁定具体的版本 tag比如 6.4-ubuntu-latest而不是直接 latest不然哪天官方更新 tag 导致拉取到不兼容版本就尴尬了。2.2 容器架构与内部网络交互方式搭这套平台最核心的是理解各容器之间怎么协作。我用一个最小拓扑来说明zabbix-mysql 容器是数据底座所有的配置、主机信息、告警历史、监控项数值都存在这里。zabbix-server 容器启动时通过环境变量连接数据库把历史数据和配置缓存加载到内存。zabbix-web 容器负责画页面它需要直接访问数据库去读配置和数据同时还要连 zabbix-server 的 10051 端口去感知 Server 状态。zabbix-agent 容器可以当成一台被监控主机用来观察监控平台自身。这里有个关键点容器之间互访我不建议通过映射端口到宿主机再用 IP 访问最好直接使用 Docker 内部网络。compose 文件里定义一个自定义 bridge 网络后同一网络内的服务名自动解析为容器 IPServer 端配置 DB_SERVER_HOSTzabbix-mysql 就能找到数据库容器。这样既安全又省事还不占宿主机端口。对外端口只需要暴露 Web 和 Server 两部分。Web 端口默认映射到宿主机某个端口比如 8080Server 的 10051 端口要暴露给被监控主机的 Agent 做主动模式上报。数据库 3306 端口和 Agent 的 10050 端口我一般不暴露到宿主机避免不必要的安全暴露面。2.3 数据持久化、时区与存储规划Zabbix 运行一段时间后数据量会非常可观历史数据单表可能以 GB 计趋势数据更是飞速增长。所以数据库存储的规划特别重要。用 Docker 命名卷是快捷方式Docker 自动帮你管理目录但更推荐的方式是挂载宿主机目录比如 /data/zabbix/mysql:/var/lib/mysql这样通过常规备份工具也能直接备份。容器默认时区是 UTC如果不处理你会发现监控图表的时间比本地时间慢 8 个小时告警时间也是错的。解决方案很简单在 compose 里所有服务都设置 TZAsia/ShanghaiWeb 前端额外设置 PHP_TZAsia/Shanghai。第一次部署就把这件事做掉后面能省掉一堆莫名其妙的困惑。数据库字符集同样要提前定好。Zabbix 建议 MySQL 使用 utf8mb4 字符集排序规则用 utf8mb4_bin。不加这个配置轻则中文字段显示异常重则启动时数据库版本不兼容。compose 里通过 MySQL 容器的 command 参数可以显式指定。3. 一步一步把 Zabbix Server 跑起来实操核心3.1 编写 docker-compose.yml先准备一个目录比如 /opt/zabbix然后添加 docker-compose.yml。下面这套配置是我日常使用的基础模板已经包含了健康检查和时区设置你直接复制下来按需调整即可services: zabbix-mysql: image: mysql:8.0 container_name: zabbix-mysql command: - --character-set-serverutf8mb4 - --collation-serverutf8mb4_bin - --max-connections512 environment: MYSQL_DATABASE: zabbix MYSQL_USER: zabbix MYSQL_PASSWORD: Zabbix2024 MYSQL_ROOT_PASSWORD: Root2024 TZ: Asia/Shanghai volumes: - /data/zabbix/mysql:/var/lib/mysql restart: unless-stopped networks: - zabbix-net healthcheck: test: [CMD, mysqladmin, ping, -h, localhost, -pRoot2024] interval: 10s timeout: 5s retries: 5 zabbix-server: image: zabbix/zabbix-server-mysql:7.0-ubuntu-latest container_name: zabbix-server environment: DB_SERVER_HOST: zabbix-mysql MYSQL_DATABASE: zabbix MYSQL_USER: zabbix MYSQL_PASSWORD: Zabbix2024 TZ: Asia/Shanghai ports: - 10051:10051 depends_on: zabbix-mysql: condition: service_healthy restart: unless-stopped volumes: - /etc/localtime:/etc/localtime:ro networks: - zabbix-net zabbix-web: image: zabbix/zabbix-web-nginx-mysql:7.0-ubuntu-latest container_name: zabbix-web environment: ZBX_SERVER_HOST: zabbix-server DB_SERVER_HOST: zabbix-mysql MYSQL_DATABASE: zabbix MYSQL_USER: zabbix MYSQL_PASSWORD: Zabbix2024 PHP_TZ: Asia/Shanghai ZBX_MEMORY_LIMIT: 256M ports: - 8080:8080 depends_on: - zabbix-server restart: unless-stopped networks: - zabbix-net zabbix-agent: image: zabbix/zabbix-agent:7.0-ubuntu-latest container_name: zabbix-agent environment: ZBX_SERVER_HOST: zabbix-server ZBX_HOSTNAME: zabbix-server ports: - 10050:10050 depends_on: - zabbix-server restart: unless-stopped networks: - zabbix-net networks: zabbix-net: driver: bridge我解释一下这里几个容易踩坑的细节。MySQL 的 command 参数不能省。如果不指定字符集MySQL 默认是 latin1Zabbix 建表时会有字符集兼容问题前期不明显等到采集中文数据时乱码就麻烦了。max-connections 设置到 512 是给并发连接留余量如果采集的主机数量很大可以再调大。数据库健康检查这段很重要。第一次部署时如果没有 healthcheckServer 容器可能在数据库还没启动完成就开始连接数据库日志里出现大量Access denied或Cant connect看起来像密码错误其实是数据库还没就绪。加了 healthcheck 并让 Server 通过 depends_on 等待健康状态能从根源上避免这个问题。端口冲突也需要特别注意。Web 前端默认使用 8080 端口如果你宿主机已经占用了 8080记得改成 8081 或自定义端口。10051 是 Zabbix Server 接收 Agent 上报的端口建议保持默认。10050 是 Agent 监听端口如果只把 Agent 容器当作被监控对象也可以不映射到宿主机直接通过容器网络访问即可。3.2 启动容器、验证服务状态配置文件就绪后执行启动命令cd /opt/zabbix docker compose up -d第一次拉取镜像可能要等几分钟。拉取完成并启动后用 docker compose ps 查看状态docker compose ps正常状态应该是四个容器都显示 Up其中 zabbix-mysql 还会显示 healthy。接着看 Server 日志确认它是否成功连接数据库docker logs zabbix-server --tail 100如果看到类似resuming Zabbix server processes或者server #0 started的字样说明 Server 已经起来了。再检查 Web 容器docker logs zabbix-web --tail 50此时浏览器访问 http://宿主机IP:8080应该能看到 Zabbix 登录页面。初始账号是 Admin密码是 zabbix。3.3 登录后必须做的第一轮配置登录成功的第一件事不是急着添加主机而是先把基础环境设置好。先改密码。默认密码全世界都知道如果你面向公网环境不换密码和裸奔没什么区别。右上角点击用户头像进入 User profile修改密码并设置语言为 zh_CN时区设置为 (UTC08:00) Asia/Shanghai。再设置前端 URL。在 Administration - General - URL 里把访问地址改成实际使用的地址比如 http://192.168.1.10:8080。这个 URL 会用在告警通知的链接里如果不改邮件或钉钉消息里的跳转链接就会指向 localhost点半天也跳不对。还有一步容易被忽略的是时区生效验证。在 Latest data 页随便看一个监控项的时间戳确认显示的是本地时间。如果还是 UTC多半是 PHP_TZ 没设置成功重新检查 Web 容器的环境变量后重启容器。这时监控平台本身已经可用了但还没有监控任何东西。接下来添加一台真实主机把采集链路跑通。4. 添加第一台被监控主机把链路跑起来4.1 被监控端安装并配置 Zabbix Agent在 Linux 主机上安装 Agent 非常直接。Ubuntu 系统执行apt update apt install zabbix-agent -yCentOS 或 RHEL 系统先导入官方源再安装以 7.0 为例rpm -Uvh https://repo.zabbix.com/zabbix/7.0/rhel/9/x86_64/zabbix-release-7.0-1.el9.noarch.rpm dnf install zabbix-agent -y安装完成后编辑 /etc/zabbix/zabbix_agentd.conf重点修改三个参数Server192.168.1.10 ServerActive192.168.1.10:10051 Hostnameweb-server-01第一个 Server 是允许哪个地址来被动采集第二个 ServerActive 表示 Agent 要主动连接哪个 Server 地址上报数据第三个 Hostname 是这个 Agent 的唯一标识。很多新手会在这里栽跟头Hostname 写什么无所谓但必须和后面在 Web 前端添加主机时的 Host name 字段保持一致。Zabbix Server 接收数据时靠 Hostname 来区分是哪台机器上报的数据两边不一致上报数据识别不了主机状态就一直是红色灰色。配置完成重启服务并设置开机自启systemctl restart zabbix-agent systemctl enable zabbix-agentWindows 被监控主机需要去官网下载 Windows Agent exe 包解压后修改 zabbix_agentd.conf 同样三个参数然后用管理员身份安装服务启动。Windows 最大的坑是防火墙10050 端口要放行入站规则否则 Server 永远连不上它。4.2 在 Web 前端添加主机并绑定模板回到 Zabbix 页面菜单 Data collection - Hosts - Create host进入添加页面后按下面填Host name 填 web-server-01必须和 Agent 配置里的 Hostname 完全一致。Interfaces 区域点击 Add 选择 AgentIP address 填被监控主机的实际 IP端口填 10050。Templates 区域输入 Linux by Zabbix agent把它添加进去。Linux by Zabbix agent 模板会自带一堆 Linux 基础监控项包括 CPU、内存、磁盘、网络、系统负载等等不需要你手动一个个添加监控项直接套模板最省心。保存后主机列表里会出现新主机状态区域会先显示灰色过一两分钟自动变成绿色并有可用性和数据。点击 Machines - Latest data筛选这台主机能看到带数值的数据就说明采集链路正常。如果过了几分钟还没有数据优先检查三件事第一被监控主机的防火墙是否放行了 10050 端口第二Zabbix Server 能不能 telnet 到被监控主机的 10050 端口第三Agent 是否在运行。4.3 配置告警通知以钉钉机器人为例没有告警的监控就是花瓶。Zabbix 的告警链路是监控项数据满足触发器条件后生成事件动作匹配到用户和媒体类型后发送通知。我用钉钉机器人给你完整演示一版这套配置免去了搭 SMTP 的麻烦。先在钉钉群里添加一个自定义机器人拿到 Webhook 地址和加签密钥。然后进入 Zabbix 的 Administration - Media types可以看到自带的 DingTalk 媒体类型点击进去选择 Enabled填入 Webhook URL如果需要加签把加签密钥也填进去。新建一个接收告警的用户Administration - Users - Create user用户名 ops密码随意加入 Zabbix administrators 组。在用户详情的 Media 标签里添加一条记录类型选 DingTalk收件人填手机号或自定义关键字。最后配置动作Alerts - Actions - Trigger actions把默认的 Report problems to Zabbix administrators 动作改为启用状态并确保 Operation 里选择发送给 ops 用户。保存后手动触发一个测试触发器不到一分钟钉钉群就会收到告警消息。邮件告警也是常见需求配置思路一样在 Media types 里启用 Email填好 SMTP 服务器、发件账号、密码或授权码然后在用户 Media 里绑定收件邮箱即可。需要注意很多云邮箱默认关掉 SMTP需要去邮箱设置里开启客户端授权。4.4 加一台 Windows 或交换机的监控既然提到企业级监控免不了要覆盖 Windows 服务器和网络设备。Windows 安装 Agent 后在 Web 前端添加主机时模板选择 Windows by Zabbix agent 即可。交换机路由器这类网络设备Zabbix 主要通过 SNMP 采集前提是设备开启 SNMP 协议。添加主机时接口选择 SNMP填入设备 IP 和 community string默认通常是 public模板可以选 Generic by SNMP 或者厂商专用模板比如华为、思科的模板社区都有现成的导入后直接用。5. 常见问题与排查技巧实录5.1 前端提示 Zabbix server is not running这个是出现频率最高的报错。前端页面顶部会显示一段黄色警告说 Zabbix server is not running。出现这个很多人一时不知道从哪里下手。我的排查思路分三步走。第一步确认 Server 容器本身是否存活docker compose ps zabbix-server如果容器显示已退出看日志docker logs zabbix-server --tail 50日志里大概率会直接告诉你问题比如数据库连接失败、SQL 初始化脚本执行出错、权限不足等等。第二步如果容器是 Up 状态可能是 Server 还在启动过程中等一到两分钟再刷新页面。我之前碰到过几次不是真报错只是 Server 启动需要时间同步数据库前端在 Server 尚未就绪时就显示了警告。第三步如果所有容器都正常但警告不消失检查 Web 容器能不能访问 Server 的 10051 端口docker exec zabbix-web bash -c nc -zv zabbix-server 10051如果网络不通可能是自定义网络配置错误重新检查 compose 文件的 network 段落确保 web 和 server 在同一个网络中。有一种容易迷惑人的情况是日志里报Access denied for user replace_user。这个报错说明你用了网上找到的环境变量模板但 MYSQL_USER 填了 replace_user 这个占位符没替换。仔细看你 compose 文件里数据库用户和密码是否写成了 demo 值权限错误多出在这种地方。5.2 镜像下载慢、容器反复重启国内拉 Docker Hub 镜像经常碰到超时或速度只有几十 KB。最简单的优化是在 /etc/docker/daemon.json 里配置镜像加速器{ registry-mirrors: [ https://docker.m.daocloud.io, https://docker.mirrors.ustc.edu.cn ] }改完执行 systemctl restart docker 重启 Docker 再重新拉取。注意镜像加速只影响新镜像的拉取已存在的镜像不受影响。容器反复重启的常见原因有端口被占用、磁盘空间不足、内存不足被 OOM 杀掉。先用 docker ps -a 看容器退出码退出码 137 通常是内存不足被系统杀了退出码 1 多半是应用启动报错。再用 docker logs 对照看具体报错。如果宿主机磁盘空间不足Zabbix 数据库无法写入容器会因为健康检查失败被 Docker 重启。建议定时检查 /data 目录的使用率别让监控平台的磁盘先爆了。5.3 Agent 主机状态变红、数据采集不到添加主机后 Forever red 是另一个高频问题。排查链路可以这样走先在 Zabbix Server 宿主上看是否能和 Agent 通信telnet 192.168.1.20 10050如果连接不通就是网络或防火墙问题。查看被监控主机的 Agent 服务状态systemctl status zabbix-agent再看 Agent 日志 /var/log/zabbix/zabbix_agentd.log里面有明确的连接记录能看到是连接被拒绝还是超时。还有一种隐蔽问题一台 Agent 被多个 Server 同时拉取数据时客户端配置容易乱。还有主机名重复也会导致 Zabbix Server 拒绝数据。如果你有旧的主机记录残留又用同一个 Hostname 注册了新主机数据库里会存在冲突需要删除旧记录后重新添加。如果网络通、Agent 也在跑但还是没数据大概率是 Hostname 不匹配。把 Web 前端主机的 Host name 和 Agent 配置里的 Hostname 核对一遍这个错误出现的频率比你想的高得多。5.4 备份与恢复防患于未然Docker 部署最大的一个优势是数据在 volume 里容器删了数据还在但如果你误删了整个 volume 或磁盘损坏那就真的回天乏术了。所以定期导出数据库是必须的。我用的是 mysqldump停不停库看你的容忍度。一般小规模环境直接在运行中备份问题不大docker exec zabbix-mysql mysqldump -uroot -pRoot2024 --single-transaction --routines --triggers zabbix /data/backup/zabbix_$(date %F).sql恢复时先确认目标环境里有 Zabbix 数据库再执行cat /data/backup/zabbix_2024-01-01.sql | docker exec -i zabbix-mysql mysql -uroot -pRoot2024 zabbix备份时机上我建议至少每日一次数据库导出compose 文件和 .env 配置文件也丢进 Git 仓库管理这样整个监控平台的定义和代码一样有版本历史。真需要从裸机恢复环境就把 compose 拉下来、创建好目录、导入数据库备份、启动容器半小时内一套环境就能复原了。6. 生产环境的性能调优与长期维护建议6.1 资源规划和数据库调优Zabbix 的资源消耗受监控规模影响非常大。监控几十台机器、几千个监控项2 核 4G 内存就够用。如果监控上百台主机或者一个主机上接了上百个监控项Server 和数据库建议至少 4 核 8G。资源不够的表现通常是页面卡顿、历史数据查询慢、告警延迟。数据库是性能的绝对核心。Zabbix 历史数据表会快速增长即使只保留 30 天历史数据和一年趋势数据几十台主机跑一年也能轻易上几十 GB。Zabbix 7.0 默认支持自动分区理论上可以减缓大表性能问题但还是要关注磁盘容量。建议给数据库所在目录单独挂盘并配置 inotify 或定期脚本检查磁盘使用率。housekeeper 是 Zabbix 自动清理历史数据的机制。在 Administration - General - Housekeeping 可以调整保留时间。如果你磁盘有限可以缩短历史数据保留时间但趋势数据尽量保留久一点因为历史数据是逐条明细趋势数据是聚合后的分钟级数据对容量影响小很多。6.2 容器升级流程和数据库兼容问题Docker 化的升级确实很方便但要说清楚一个前提Zabbix 的数据库结构在不同版本间有差异升级 Server 镜像过程中容器启动时会自动执行 SQL 迁移脚本把数据库结构升级到新版本。这个动作是单向的降级不一定能恢复。所以升级前一定先备份数据库。整体流程备份数据库 - 修改 compose 里镜像 tag - docker compose pull 拉取新镜像 - docker compose up -d 重启服务 - 登录前端确认版本号和监控项正常。如果故障激进需要回滚先把旧镜像 tag 恢复再从备份恢复数据库再启动容器这样才是最稳妥的回滚路径。6.3 监控自身平台也要有人盯着最后分享一个我觉得特别重要的心得监控平台本身也需要被监控。Docker 化部署虽然让 Zabbix Server 恢复了自愈能力但磁盘满了、数据库挂了、容器被误删这些都不会自动恢复。我常用的做法是在宿主机上再装一个轻量级的 Zabbix Agent二进制方式通过固定 IP 把宿主机注册到 Zabbix 里这样宿主机本身的 CPU、内存、磁盘空间、Docker 容器状态都会被 Zabbix 纳入监控。另一条路是给容器本身频繁做健康检查compose 里通过 healthcheck 和 autoheal 之类的工具实现自动重启。如果你的团队用 Grafana也可以直接把 Zabbix 作为数据源接入 Grafana把监控数据做成更直观的业务大屏信息传达效率高很多。我在实际使用中还有一个体会docker-compose.yml 不要写一次就不管了建议把它作为基础设施的管理对象跟着 Git 仓库一起版本化。每次改动无论是新增环境变量、调整端口、还是升级镜像版本都留一条提交记录。当某天监控平台出现奇怪问题时git diff 能给你提供比记忆可靠得多的排查线索。这套模式支撑我们团队跑了大半年从 20 台主机到 80 多台主机监控平台本身没出过大问题这套部署方式在其中起了关键作用。
上一篇/下一篇内容由系统自动关联 返回资讯列表 →