ARTICLE DETAIL

资讯详情

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

Docker部署Zabbix监控平台:从环境搭建到告警配置全指南

Docker部署Zabbix监控平台:从环境搭建到告警配置全指南 做运维这行最怕的不是故障本身而是故障发生了却没人第一时间知道。业务方比你先发现系统挂了那种被动的滋味体验过一次就再也不想有第二次。Zabbix 作为老牌的企业级监控与告警平台恰好就是解决这个问题的利器而用 Docker 部署 Zabbix则是我在多个环境里折腾过之后觉得最省心、最可复现的一套做法。这篇文章就从实际落地的角度把环境准备、容器编排、主机接入、告警通知的完整链路一条条掰开讲清楚连参数为什么这么写、报错怎么排查都会说到。想快速拥有一套能监控服务器、数据库、网络设备并自动告警的平台的同行尤其是刚接触 Zabbix 的运维新手按这篇的步骤走一遍基本都能把平台跑起来。1. 方案选型与整体架构先弄明白 Zabbix 在 Docker 里跑着什么1.1 为什么选 Docker 部署 Zabbix早年装 Zabbix 是个体力活。要配官方仓库、装 PHP、装数据库驱动、改一堆配置文件稍不注意版本就对不上。我记得第一次在 CentOS 7 上折腾 Zabbix 4.0光依赖冲突就解了一天更别说以后升级大版本还得小心翼翼地停服、备份、迁移数据库。后来用上 Docker这件事的复杂度直接降了一个量级。用 Docker 部署 Zabbix 的核心收益是把“环境一致性”这个最折磨人的问题交给镜像去解决。官方镜像zabbix/zabbix-server-pgsql、zabbix/zabbix-web-nginx-pgsql把这些组件的依赖关系都打包好了你拉下来起容器就能跑。升级的时候换一个 tag回滚的时候换回旧 tag整个操作几分钟完成。测试环境验证完生产环境用同一套 compose 文件行为基本一致这比手写一堆安装命令可预测得多。当然没有银弹。Docker 化之后也有代价数据必须靠 volume 持久化否则容器一删全没了日志在容器里排查问题要多一步docker logs端口映射做得不好还容易跟宿主机现有服务冲突。所以这篇文章里我会把网络规划、数据卷、端口映射这些细节都讲清楚踩过的坑不会再让你踩一遍。1.2 Zabbix 核心组件与数据流向Zabbix 不是一个单体程序它是一组组件协作跑起来的。理解这一点后面排错会轻松很多。我用一个表格梳理一下组件作用对应 Docker 镜像Zabbix Server核心调度服务负责采集任务分发、触发器计算、告警生成zabbix/zabbix-server-pgsql数据库存配置、历史数据、趋势数据、事件记录postgres:16-alpineZabbix WebPHP 前端供人查看监控数据和操作配置zabbix/zabbix-web-nginx-pgsqlZabbix Agent部署在被监控主机上按 Server 要求采集指标zabbix/zabbix-agent或系统包安装整个数据流可以这样理解Server 告诉 Agent 去采集哪些指标Agent 把数据回传Server 拿到数据后判断是否落在触发器的阈值范围内如果触发了就生成告警事件通过配置好的告警媒介把消息推给指定的人。所有采集到的历史数据和事件都会写入数据库Web 前端再从数据库里取出来画图、展示。所以数据库一旦出问题整个平台就瘫了这也是后面备份要重点照顾数据库的原因。值得多说一句的是 Agent 的“被动”和“主动”两种模式。被动模式下Server 定期向 Agent 发起请求拉数据默认走 10050 端口主动模式下Agent 自己定时把数据推到 Server走 10051 端口。小规模环境用默认的被动模式就够了主机多了之后可以考虑把某些采集项改成主动模式减轻 Server 压力。1.3 版本、数据库与硬件要求怎么定版本这块我的建议是直接用当前 LTS 版本。Zabbix 7.0 LTS 是 2024 年发布的长期支持版支持周期长功能上比 6.0、6.4 都完善Web 界面也不一样了。如果公司有历史包袱必须兼容老版本再考虑 6.0 LTS。选版本就一个原则能上新就不守旧但不要盲目追最新非 LTS 版。数据库我推荐 PostgreSQL。原因不复杂官方对 pgsql 镜像的维护最积极社区里踩坑记录也多是围绕 MySQL 的。Zabbix 官方同时提供zabbix-server-mysql和zabbix-server-pgsql两套镜像只要把 compose 里的镜像和后端数据库对应上就行混搭会连不上这是新手最常见的低级错误。硬件要求真不高。一个 2 核 4G 内存、20G 磁盘的虚拟机监控几十台主机绰绰有余。Docker Engine 版本建议 20.10 以上docker-compose 插件用 v2 语法。系统我常用 Ubuntu 22.04/24.04Debian 也可以CentOS 7 由于内核和 Docker 兼容性问题不建议再作为宿主机了。2. 五步吃透 docker-compose从空目录到可访问的监控平台2.1 网络与数据卷规划动手写 compose 之前先把两件事规划好网络和数据卷。网络方面我会创建一个自定义 bridge 网络让三个容器在内部通过服务名互相访问。为什么不用 host 网络一是端口冲突风险大Web、数据库都直接暴露在宿主机网络上安全性和灵活性都差二是自定义 bridge 网络内置 DNS 解析容器之间直接用服务名通信配置里写DB_SERVER_HOST: zabbix-db就能连通非常省事。数据卷方面数据库的目录必须挂在宿主机上。PostgreSQL 官方镜像的数据目录是/var/lib/postgresql/data把它映射到一个本地 volume 或者宿主机目录比如/opt/zabbix/zbx-db-data。另外务必备份/etc/localtime到容器里保持容器时间和宿主机一致否则告警时间、图表时间全都会偏移排查问题的时候特别容易误导人。我习惯把整套部署文件放在/opt/zabbix目录下结构清晰备份也好操作/opt/zabbix/ ├── docker-compose.yml └── zbx-db-data/ # 数据库数据目录volume 实际存储2.2 编写 docker-compose.yml 并逐个解释关键参数下面是我实际在用的 compose 文件Zabbix 7.0 LTS PostgreSQL 16你可以直接复制改密码version: 3.8 networks: zbx-net: driver: bridge volumes: zbx-db: driver: local services: zabbix-db: image: postgres:16-alpine container_name: zbx-postgres restart: always environment: POSTGRES_USER: zabbix POSTGRES_PASSWORD: zabbix2024 POSTGRES_DB: zabbix volumes: - zbx-db:/var/lib/postgresql/data networks: - zbx-net zabbix-server: image: zabbix/zabbix-server-pgsql:alpine-7.0-latest container_name: zbx-server restart: always environment: DB_SERVER_HOST: zabbix-db POSTGRES_USER: zabbix POSTGRES_PASSWORD: zabbix2024 POSTGRES_DB: zabbix ports: - 10051:10051 volumes: - /etc/localtime:/etc/localtime:ro depends_on: - zabbix-db networks: - zbx-net zabbix-web: image: zabbix/zabbix-web-nginx-pgsql:alpine-7.0-latest container_name: zbx-web restart: always environment: ZBX_SERVER_HOST: zabbix-server DB_SERVER_HOST: zabbix-db POSTGRES_USER: zabbix POSTGRES_PASSWORD: zabbix2024 POSTGRES_DB: zabbix PHP_TZ: Asia/Shanghai ports: - 8080:8080 depends_on: - zabbix-server - zabbix-db networks: - zbx-net zabbix-agent: image: zabbix/zabbix-agent:alpine-7.0-latest container_name: zbx-agent restart: always environment: ZBX_SERVER_HOST: zbx-server ZBX_HOSTNAME: zbx-server ports: - 10050:10050 depends_on: - zabbix-server networks: - zbx-net这里的关键参数我逐个说下含义环境变量作用常见坑DB_SERVER_HOST告诉 Server/Web 后端数据库在哪填服务名zabbix-db不要填 localhostPOSTGRES_USER/PASSWORD/DB数据库连接凭据和库名三个服务的凭据必须完全一致ZBX_SERVER_HOSTWeb 和 Agent 连接的 Server 地址写服务名zabbix-serverPHP_TZWeb 界面时区不设的话默认 UTC时间显示差 8 小时端口映射要理解透10051是 Zabbix Server 的 trapper 端口外部 Agent 主动上报数据要靠它必须映射出来10050是 Agent 被动采集端口如果只在 Zabbix 本机监控自己的容器可以不用映射但要监控外部主机不建议把 Agent 容器暴露出去正确做法是直接在目标主机上装系统原生 agent后面第三章会说。Web 端口我习惯映射到8080避免跟宿主机上的 80 端口打架。2.3 启动服务、初始化数据库与 Web 登录验证文件写好进入目录执行cd /opt/zabbix docker compose up -d第一次启动会拉镜像需要一点时间。之后用docker compose ps确认所有容器都是 Up 状态再用docker compose logs -f zabbix-server观察日志。如果看到类似server #0 started [main process]之类的输出说明 Server 已经正常起来了。数据库初始化是自动完成的Zabbix Server 容器首次启动时会自动建表并导入 schema不需要手动执行 SQL。等 Web 容器起来之后浏览器访问http://宿主机IP:8080看到 Zabbix 登录页就成功了。默认账号是Admin密码是zabbix登录后第一件事就是改密码。登录后强烈建议先去右上角头像 - User profile - Language把语言调成 Chinese再进入Reports - System information确认页面上 Zabbix server 状态显示绿色 Running。如果这里显示Zabbix server is not running: the information displayed may not be current.说明 Web 和 Server 之间的健康检查有问题这个报错太经典了第五章我会专门展开讲。3. 把你手头的主机都纳进来Linux、MySQL、Nginx、交换机3.1 添加被监控主机界面操作全流程Web 界面能打开了接下来最核心的一件事把需要监控的机器加进来。在 Zabbix 里“添加主机”不是一个简单的 IP 录入动作而是要告诉系统三件事这台机器叫什么、通过什么方式采集数据、套用哪些监控模板。以一台 Linux 服务器为例操作路径是Data collection - Hosts - Create host关键配置如下Host name填一个容易识别的名称比如web-01后面所有图表、触发器都会用这个名字。Host groups至少选一个组方便后续批量管理和配置告警动作。建议提前建好Linux servers、Databases这类分组。Interfaces添加一个 Agent 接口IP 填被监控主机的实际 IP端口默认 10050。Templates在Link new templates里搜索并关联Linux by Zabbix agent模板会自动带进来一整套 CPU、内存、磁盘、网络、系统服务的监控项和触发器省得自己一条条配。保存后等 30 到 60 秒回到列表页看ZBX列是否变成绿色可用状态再看Latest data里有没有出现数据。第一次做这一步的新人十有八九会漏了 Host groups 或者忘了点模板导致主机加进去却没有任何监控项记住这两点能少走很多弯路。3.2 Linux 主机安装 zabbix-agent 并完成自监控Agent 的安装本身不复杂难在配置和通路上。以 Ubuntu 22.04 为例我是直接用官方仓库安装# 下载并安装官方仓库包 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装完改配置/etc/zabbix/zabbix_agentd.conf重点就三个参数Server10.0.0.10 ServerActive10.0.0.10 Hostnameweb-01Server填 Zabbix Server 的 IP作用是被动模式下允许谁过来拉数据ServerActive是主动模式下 Agent 往哪上报Hostname必须和 Zabbix Web 后台里创建的主机名完全一致如果对不上主动模式的数据会跑到一个叫Hostname的未知主机上去这是特别容易忽略的坑。然后启动并验证systemctl enable --now zabbix-agent # 放行防火墙视你的网络策略而定 ufw allow 10050/tcp # 在 Zabbix Server 所在机器上实测采集 zabbix_get -s 10.0.0.11 -p 10050 -k system.hostname如果zabbix_get能返回主机名说明链路是通的回到 Web 界面刷新一下图标很快会变绿。这里我强烈建议养成一个习惯任何一台主机接入后先zabbix_get测通链路再保存配置别一股脑全靠界面去猜。3.3 数据库与中间件监控MySQL、Nginx 模板实战光监控主机指标还远远不够业务的核心在数据库和中间件上。Zabbix 官方模板覆盖很全但前提是你得给这些服务开好“监控入口”。MySQL 监控的入口是一个专用账号。官方模板MySQL by Zabbix agent需要数据库里有zbx_monitor用户并且授予特定的最小权限CREATE USER zbx_monitor% IDENTIFIED BY Zabbix123; GRANT REPLICATION CLIENT, PROCESS, SHOW DATABASES, SHOW VIEW ON *.* TO zbx_monitor%;然后在 Zabbix 后台给 MySQL 主机链接模板并配置宏指明连接串例如{$MYSQL.DSN}设为tcp://10.0.0.20:3306{$MYSQL.USER}设为zbx_monitor{$MYSQL.PASSWORD}设为对应用户密码。模板里几十个监控项会自动开始跑从查询数、连接数到缓存命中率、慢查询基本覆盖日常巡检需求。Nginx 更轻量只需要在服务端配置里暴露一个状态页。在 nginx 配置中加入server { listen 80; location /basic_status { stub_status; allow 127.0.0.1; allow 10.0.0.0/24; # 按需放行 Zabbix Server 网段 deny all; } }然后在 Zabbix 里给 Nginx 主机关联Nginx by Zabbix agent模板把{$NGINX.STUB_STATUS.SCHEME}和{$NGINX.STUB_STATUS.PORT}宏按实际情况改一下。验证方式很简单浏览器直接访问http://IP/basic_status能看到Active connections: 12这样的输出说明入口通了。模板关联后稍等片刻请求数、连接数、流量这些指标就自己进库了。3.4 网络设备监控SNMP 与 ICMP 接入服务器和中间件搞定之后交换机、路由器这类网络设备在 Zabbix 里同样可以管起来。网络设备一般不支持装 agent接入靠的是 SNMP 协议原理和设备本身开放一个只读的 SNMP agentZabbix Server 定期去轮询。添加方式和普通主机差不多在Interfaces选项卡里新增一个 SNMP 接口端口默认 161然后在Templates里关联Network device by SNMP模板。模板默认会把 CPU、内存、接口流量、接口状态这些常用 OID 都采集进来写入{$SNMP_COMMUNITY}宏对应的团体名即可默认public生产环境务必修改设备的 SNMP 只读团体名这个弱口令太危险了。另外还有个实用技巧给设备同时关联Ping by ICMP模板这样即使设备 SNMP 挂了只要 ICMP 能通至少知道设备在线两个模板一起用一个管可用性一个管性能分工明确。我在实际项目中监控过几十台接入交换机Zabbix 的自动发现规则能直接把所有接口和 VLAN 识别出来基本不需要手工干预。4. 告警闭环让监控真正替你半夜值班4.1 配置邮件告警媒介监控数据有了如果没有告警半夜出问题还是没人知道等于白搭。Zabbix 的告警链路是触发器产生事件 - 动作匹配事件 - 通过告警媒介把消息发出去。所以第一步是先把“告警媒介”配好。以邮件为例进入Administration - Media types - Email配置 SMTP 参数。我常用的配置是SMTP server 填邮箱服务商的地址比如企业邮箱填smtp.company.com端口 465 选 SSL勾选 Authentication填发件账号和密码。这里有个常见的坑很多邮箱服务商对第三方 SMTP 有专门的授权码机制不能用登录密码得去邮箱设置里生成授权码否则会一直报认证失败。配置完一定要点右下角的Test填一个收件地址发测试邮件。测试通过再保存这一步能省去后面所有“为什么没收到告警”的排查时间。另外在字段设置里可以把Subject和Message改成包含主机名、触发器和严重级别的模板比如[告警] {EVENT.NAME} on {HOST.NAME}收到邮件一眼就知道是什么状态、哪台机器出了问题。4.2 创建告警动作与用户通知媒介配好只是“能用”真正把邮件发给谁、什么条件下发靠的是动作。在Configuration - Actions - Trigger actions里系统默认有一条动作但往往不满足生产需求建议新建一条。操作路径是Create action我一般这样配置Name生产环境告警通知Conditions设置触发条件比如Host group Linux servers或者按严重级别过滤避免测试环境的信息刷屏。Operations添加操作Send message给指定用户组媒体类型选 Email。同时要记得在Administration - Users里给对应账号配置媒体地址。具体做法是编辑用户进入Media选项卡添加一条 Email 媒介填接收邮箱勾选接收哪些严重级别的告警以及通知时间段。我习惯把告警级别至少设为Warning及以上把Information级别的信息留给界面查看不然邮件真的会变成轰炸。最后还有个细节动作里除了Operations第一操作还有Recovery operations恢复操作和Update operations确认操作分别对应“故障恢复时通知”和“人工确认告警时通知”。把恢复操作也勾上这样故障解决了相关人员能收到一条“已恢复”的通知整个告警生命周期才完整。4.3 触发器、维护窗口与告警降噪告警配置到最后真正考验水平的是降噪。你不想凌晨三点因为一条误报爬起来更不想因为告警风暴把手机震没电。先从触发器说起。模板自带的触发器已经覆盖 90% 的常规场景但业务定制场景要自己写表达式。比如要监控 Nginx 的并发连接数连续 3 次超过 200就在Configuration - Hosts - Triggers - Create trigger里写last(/web-01/nginx.active.connections) 200精确点用min函数配合周期min(/web-01/net.if.in[eth0],5m) 500000这表示 eth0 网卡 5 分钟内的平均入流量大于 500KB/s 就触发。表达式里的last、min、max、avg这几个聚合函数是高频使用项配合时间后缀5m、1h能做出非常精准的告警条件。维护窗口是我最想强调的功能。比如每周日凌晨 2 点跑批任务期间 CPU 飙高是正常现象不处理就会误报。在Configuration - Maintenance里创建维护期选择主机和周期点击激活后维护期内的所有触发器和告警都会被抑制。我接手的每个 Zabbix 项目第一件降噪的事就是盘点定期任务窗口把它们全部纳入维护计划。严重级别的划分也要上心。我见过很多团队把什么都设成High结果真正的故障被淹没在红色海洋里。合理划分能让人在收到告警时下意识判断优先级磁盘快要满了是 Warningnginx 进程挂了是 High机房断网导致大面积主机不可达才是 Disaster。级别不合理的告警体系等于没有告警体系。5. 生产环境避坑备份、性能与经典报错排查5.1 数据备份与恢复定期 pg_dump监控平台最不能丢的是数据库里的历史数据和配置。容器跑起来之后备份方案很简单用 PostgreSQL 官方工具在容器里直接导出docker exec zbx-postgres pg_dump -U zabbix -d zabbix | gzip /backup/zabbix_backup_$(date %F).sql.gz这条命令把整个zabbix库导出并压缩到宿主机/backup目录下。配合 crontab 每天凌晨跑一次保留最近 30 天基本就能覆盖日常需求。恢复也不难gunzip -c zabbix_backup_2025-01-01.sql.gz | docker exec -i zbx-postgres psql -U zabbix -d zabbix这里有一个重要提醒恢复后如果版本不一致比如从 6.0 的备份恢复到 7.0很可能因为数据库 schema 结构变化导致 Web 报错。跨大版本升级正确做法是先在新版本环境里跑一遍备份恢复的演练确认没问题再动生产。5.2 性能与资源限制调优监控平台本身也是服务不能让它把自己所在的宿主机吃垮。compose 文件里可以给每个服务加上资源限制deploy: resources: limits: cpus: 2 memory: 1G这行配置放在服务定义下配合restart: always可以把容器对宿主机的影响控制在预设范围内。另外容器日志默认是用 docker 的 json-file 驱动长期不清理会越来越大建议在 compose 的每个服务里加上logging: driver: json-file options: max-size: 50m max-file: 3数据量大的场景还要关注 Zabbix 内部的缓存参数。在 Server 容器的环境变量里可以设置CacheSize、HistoryCacheSize、TrendCacheSize等比如environment: - CacheSize128M - HistoryCacheSize64M - TrendCacheSize64M我把这组参数理解为 Zabbix 自己的“内存缓冲池”采集到的数据先攒在内存里再批量写入数据库。监控主机多、指标密的话默认值会不够用日志里会出现cache allocation failed的报错。调参没有标准答案按主机数量和监控项规模逐步加大即可改完重启 Server 容器生效。5.3 经典报错排查实录server is not running、access denied、不出数这部分我把这些年遇到的高频问题整理成速查表每一个都是真实场景报错/现象可能原因排查与解决页面上方提示Zabbix server is not runningWeb 容器连不上 Server或 Server 内部组件异常先docker compose ps看服务状态再docker compose logs zabbix-server看日志常见原因是数据库没起来或者三个容器不在同一网络、无法互相解析服务名数据库连接报access denied for user replace_userlocalhost (using password: YES)compose 里各服务的数据库账号密码不一致或数据库 volume 里残留了旧凭据把POSTGRES_USER、POSTGRES_PASSWORD在 db/server/web 三个服务里设置成完全一致如果是复用旧 volume建议删掉 volume 重新初始化前提是已有备份主机状态一直灰色zabbix_get无输出防火墙未放行 10050或 agent 配置里Server没填 Zabbix Server 的 IP先本机 netstat -tlnp主机能 ping 通但 SNMP 监控无数据团体名不对或设备 SNMP 未开启只读模式用snmpwalk -v2c -c public IP验证能返回 OID 树说明 SNMP 是通的模板里把{$SNMP_COMMUNITY}改成实际的团体名主动模式数据跑到“未知主机”Agent 的Hostname与 Web 后台的主机名不一致统一两端主机名注意大小写严格一致改完重启 agent告警邮件没收到SMTP 认证失败或用户没有绑定媒介在媒介配置里先点 Test 发测试邮件检查用户Media是否绑定了邮箱并勾选了告警级别这里多说一句那个Zabbix server is not running它不一定是 Server 真的挂了。Zabbix Web 每 5 秒会请求一次 Server 内部的状态页只要 Web 容器和 Server 容器之间网络不通哪怕 Server 本身活得好好的也会提示这个。所以排查第一步永远是看容器网络而不是重启。5.4 事后再看几个值得尽早养成的习惯平台跑顺之后有几件事是我每做一个新环境都会提醒自己先做好的。容器命名和网络规划要统一。compose 里container_name我习惯用zbx-前缀统一命名配合端口映射表写进项目 README这样半年后回来维护光看名字就知道每个容器是干嘛的。监控平台最容易坏的地方往往不是 Zabbix 本身而是“没人记得它当初是怎么搭的”。升级前永远先备份、先做小范围验证。我见过太多人直接docker compose pull docker compose up -d结果 Zabbix 跨大版本升级后数据库迁移失败整个平台起不来。正确的做法永远是备份数据库 - 在测试环境验证 - 再升级生产。最后记得定期检查监控平台自身的健康状况。Zabbix 有个内置的Zabbix server主机默认会监控自己我在上面额外加了一个触发器如果zabbix[queue]这个 key 的延迟数量超过预期值说明采集任务堆积就该扩容或者优化了。连监控平台自己都监控不住那就谈不上企业级监控了。我个人的经验是这套 Docker 部署方式跑了两三年都很稳真正的功夫都花在“接入更多场景”和“让告警更聪明”上这些内容以后有机会再单独聊聊。
返回列表