news 2026/9/17 3:48:28

Zabbix 7.0容器化部署实战:OpenEuler信创环境避坑指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Zabbix 7.0容器化部署实战:OpenEuler信创环境避坑指南

先说结论:这套方案我已经在OpenEuler22.03 LTS上完整跑通了。如果你正在给国产化环境选监控系统,或者公司有信创要求必须用OpenEuler,又想用上Zabbix 7.0的新特性,那这一篇你直接抄作业就行。真要用起来,最大的感受是:Zabbix 7.0的容器化部署并没有想象中那么复杂,但坑是真不少。特别是OpenEuler和CentOS的细微差异、Docker-Compose的安装方式、数据库初始化时区这些细节,官方文档基本不会告诉你,等到你踩进去,一个晚上就没了。

这篇文章我会从环境准备、镜像选型、Compose配置、初始化落地、常见故障排查五个方面完整展开,每个步骤都给出我实测过的配置和参数,并解释为什么这么写。适合有一定Linux基础、用过Docker、想尽快把Zabbix 7.0跑起来的运维同学,也适合正在做信创迁移、需要在OpenEuler上落地监控体系的项目组参考。

1. 环境准备:OpenEuler上Docker与Compose的安装细节

1.1 OpenEuler 22.03 LTS的软件源与基础环境

OpenEuler 22.03 LTS的底层兼容性做得比很多人想象中好,官方文档说它和CentOS生态兼容,实际用下来yum仓库里的软件包确实和RHEL系列高度重叠。但这不代表直接yum install docker就能完美跑起来,我遇到的第一个坑就在这里。

OpenEuler默认没有启用Docker官方源,系统自带的仓库里虽然有docker相关的包,但是版本比较旧,而且依赖的容器运行时组件(containerd、runc)可能和最新的Docker Engine不匹配。我的建议是直接通过dnf安装基础依赖,然后从官方源装最新版本:

sudo dnf install -y yum-utils device-mapper-persistent-data lvm2 sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install -y docker-ce docker-ce-cli containerd.io sudo systemctl enable --now docker

这里有个关键点:在OpenEuler上添加Docker官方源时,地址要使用centos仓库路径,不要用openeuler路径。因为Docker官方并没有单独为OpenEuler发布仓库,而OpenEuler 22.03 LTS与CentOS 8系列在glibc和内核特性上兼容性很好,直接用centos8的源安装不会有问题。我一开始自作聪明去网上找所谓“OpenEuler专用源”,反而装出来一堆依赖问题,来回折腾了两小时。

装完之后一定要验证一下:

sudo docker run hello-world

如果这一步能跑通,说明Docker daemon、镜像加速、内核网络都正常。另外建议顺手配置一下镜像加速器,国内网络环境拉取Docker Hub镜像经常超时,这一点尤其影响后面Zabbix和PostgreSQL镜像的拉取速度。修改/etc/docker/daemon.json

{ "registry-mirrors": ["https://docker.m.daocloud.io"] }

修改后重启Docker生效:

sudo systemctl restart docker

1.2 Docker-Compose的安装方式选择:在线与离线

Docker-Compose的安装可以说是整个环境准备阶段最容易踩坑的环节,尤其是在内网环境或没有外网权限的服务器上。OpenEuler默认仓库里其实有一个docker-compose包,但版本是2.x还是1.x因系统版本而异,而且很多情况下版本太老,根本不适配Zabbix 7.0的compose文件格式。

我实测下来最稳定的安装方式是从GitHub官方仓库下载二进制文件。在OpenEuler x86_64环境下:

sudo curl -L "https://github.com/docker/compose/releases/download/v2.24.0/docker-compose-linux-x86_64" -o /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-compose

如果要部署的机器是在完全离线内网,那需要在一台能上外网的机器上下载好二进制包,然后通过U盘或内网传输工具拷过去,放到/usr/local/bin/docker-compose并赋可执行权限即可。这里没有额外依赖,一个单文件就能跑,所以在离线环境下反而比用系统包管理安装要省事得多。

验证安装:

docker-compose --version

这里给一个我的切身体会:不要把docker-compose和docker compose(Docker 26+内置的插件形式)混为一谈。OpenEuler自带的Docker版本如果是20.10或更旧,可能不支持docker compose子命令,而docker-compose独立二进制兼容性更好,推荐在脚本和自动化工具里统一用docker-compose。等到后面要上systemd管理容器生命周期的时候,命令一致性会让配置简单很多。

1.3 重点:为什么我推荐在OpenEuler上优先用容器化部署Zabbix 7.0

很多从传统运维转过来的同学习惯在宿主机上直接装Zabbix,rpm包一装、数据库一建、web一配,思路清晰。但我在OpenEuler 22.03上走了一轮原生部署以后,发现容器化几乎是最优解。

首先,OpenEuler的软件包版本和Zabbix官方仓库的匹配度不算高。Zabbix官方为RHEL/CentOS提供了rpm仓库,但OpenEuler虽然兼容,官方并不保证可以直接用。我尝试强行配置zabbix官方repo安装server端,过程中遇到libpcre2版本过旧、libcurl被系统包锁定等问题,最后虽然能用yum参数强行降级解决,但这种操作在生产环境里无异于埋雷,下次yum update可能就搞崩了。

其次,Zabbix监控系统本身组件多、依赖重。server端需要PHP、前端需要Nginx和PHP-FPM、数据库需要PostgreSQL/MySQL,再加上agent,纯手工部署至少要调整六七个配置文件,任何一个环节版本不一致都会引入奇怪的问题。而容器化方案下,每个组件都是独立镜像,官方镜像里的版本组合是经过测试的,直接把复杂性封装在镜像内部。

第三也是最重要的:升级与备份。Zabbix 7.0是LTS版本,后面会有小版本迭代。容器化部署下升级只需拉取新镜像重建容器,数据卷保留,数据库升级脚本在server容器启动时自动执行。这在传统rpm部署下需要手动执行一堆数据库迁移脚本,效果差远了。如果你的目标是“在生产环境稳定运行三五年”,容器化是更省心的选择。

2. Zabbix 7.0镜像选型与架构理解

2.1 官方镜像拆分逻辑:server、web、agent各司其职

Zabbix 7.0时代的官方镜像已经非常成熟了,它们不是把整个栈打在一个镜像里,而是按照服务角色拆分成了多个镜像。理解了这套镜像的拆分逻辑,部署的时候就不会懵。

我使用的镜像主要是这几个:

  • zabbix/zabbix-server-pgsql:Zabbix Server核心进程,负责数据采集、触发器计算、告警发送。
  • zabbix/zabbix-web-nginx-pgsql:Web前端 + Nginx + PHP-FPM,通过PG的connection信息连接同一个数据库。
  • zabbix/zabbix-agent:被监控端采集代理,配置为被动模式,由server主动拉数据。
  • postgres:16-alpine:Zabbix 7.0的后端数据库,使用官方PostgreSQL 16版本。

选择-pgsql后缀版本而不是-mysql,是因为Zabbix 7.0+PostgreSQL是官方优化最好的组合。这里多说一句:网上有帖子讨论Zabbix 7.0能否用OceanBase这类国产数据库作为后端,从技术上说Zabbix官方在流通版本里对PostgreSQL和MySQL的兼容性是最成熟的,而OceanBase虽然兼容MySQL协议,但Zabbix对它的支持目前还不是官方认证路径。所以生产环境里最稳妥的组合仍然是PostgreSQL,这也是为什么我坚持用zabbix-server-pgsql镜像的原因。

很多初次部署的同学喜欢直接搜zabbix/zabbix-appliance这种all-in-one镜像,觉得一条命令把所有事情都解决了。这个镜像确实方便,但是有两个问题:一是它把所有组件跑在同一个容器里,后续扩容、迁移、单组件升级都很痛苦;二是appliance镜像内部自带的数据库数据卷管理比较隐蔽,一旦容器被删除重建,历史监控数据很可能直接消失。我强烈建议在正规的监控体系里,把server、web、db拆成三个容器。

2.2 Zabbix 7.0相比旧版本的几个重要变化

Zabbix 7.0是LTS版本(长期支持版本),意味着它会得到至少5年的官方维护。相比6.0等旧版本,7.0有几个值得关注的改进,也直接影响部署方式。

第一个变化是Web界面的大规模重构,仪表盘和可视化配置响应速度快了很多,这也是Zabbix近些年被吐槽的痛点之一。7.0的前端UI不再那么“老气”,对于做数据展示和领导汇报的场景,体验提升明显。

第二个变化是内置的模板体系更丰富了,特别是对主流数据库、中间件、云原生环境的监控模板成熟度提高。例如Zabbix 7.0原生对MySQL的监控可以直接套用MySQL by Zabbix agent 2模板,对Redis、Nginx、Kafka等也都有相对完善的模板,减少了自定义监控项的编写成本。

第三个变化是对加密传输的支持更完善了。Zabbix Server和Agent之间支持PSK(预共享密钥)和证书加密方式,在容器化部署中可以通过环境变量配置,7.0在这方面配置比6.0清晰不少,后面我会讲具体配置方法。

这些变化带来的结果是:如果你之前用的是Zabbix 5.0或6.0,迁移到7.0的容器化方案后,监控能力上限提升了一个量级,特别是在大批量监控项和仪表盘展示上都更顺畅。

2.3 为什么选择PostgreSQL而不是MySQL作为数据库

这里我想专门展开说一下数据库选型,因为这是Zabbix 7.0部署里争议比较大的一个点。

Zabbix 7.0官方文档对数据库的要求中,PostgreSQL和MySQL都支持,但在高并发场景下PostgreSQL的查询优化能力和复杂SQL性能是优于MySQL的。Zabbix的监控数据写入和读取模式非常特殊:高频率的时序数据写入,加上频繁的聚合查询和报表查询,这种混合负载对数据库的优化器要求很高。PostgreSQL的查询计划器在处理这类复杂JOIN和聚合时,长期表现优于MySQL,尤其是监控节点和监控项数量上来以后,差距会越来越明显。

另一个考虑因素是分区表的自动管理。Zabbix的history和trends表会随数据量剧增,如果不做分区管理,数据库会在几个月内膨胀到失控。PostgreSQL 12以后的声明式分区和Zabbix官方提供的分区管理脚本配合得很好,而MySQL在分区管理和Zabbix的兼容性支持上相对弱一些。

最后是运维便利性:PostgreSQL的容器镜像在数据卷挂载、权限管理、初始化脚本执行方面做得非常规范和稳定。postgres:16-alpine镜像体积小、启动快、资源占用低,作为监控系统的后端非常合适。

3. Docker-Compose完整配置:直接复用的生产级方案

3.1 目录结构与数据卷规划

在动手写compose之前,先规划好目录结构和数据卷。我的方案是在宿主机上创建统一的目录:

sudo mkdir -p /srv/zabbix sudo mkdir -p /srv/zabbix/postgresql sudo mkdir -p /srv/zabbix/server sudo mkdir -p /srv/zabbix/web

为什么单独创建目录而不是完全依赖Docker命名卷?因为命名卷用docker volume inspect虽然也能管理,但在需要备份、迁移、巡检时,绑定挂载目录的透明度和可操作性更高。尤其是postgresql的数据目录,直接挂载到宿主机目录,备份的时候用rsync或者tar一把梭就行,不用先进容器再执行pg_dump,排查问题时也方便很多。

另一个需要注意的点是目录权限。PostgreSQL容器在启动时会以postgres用户身份运行,如果宿主机目录权限配置不当,容器会因为无法写入数据目录而启动失败。最简单的办法是设置合适的属主:

sudo chown -R 999:999 /srv/zabbix/postgresql

注意PostgreSQL官方镜像里postgres用户的UID是999,这个值在不同版本中基本固定。我把权限设置成999:999后,容器启动就不会再报权限问题了。

3.2 完整docker-compose.yml配置与关键参数说明

这是我实测通过的完整配置文件,每个服务的环境变量和参数都标注了实际作用:

version: "3.8" services: postgres: image: postgres:16-alpine container_name: zabbix-postgres restart: always environment: POSTGRES_USER: zabbix POSTGRES_PASSWORD: zabbix_pass_2024 POSTGRES_DB: zabbix TZ: "Asia/Shanghai" volumes: - /srv/zabbix/postgresql:/var/lib/postgresql/data networks: zabbix-net: ipv4_address: 172.20.0.10 healthcheck: test: ["CMD-SHELL", "pg_isready -U zabbix -d zabbix"] interval: 10s timeout: 5s retries: 5 start_period: 20s zabbix-server: image: zabbix/zabbix-server-pgsql:7.0-ubuntu-5.0 container_name: zabbix-server restart: always environment: DB_SERVER_HOST: postgres POSTGRES_USER: zabbix POSTGRES_PASSWORD: zabbix_pass_2024 POSTGRES_DB: zabbix ZBX_STARTPOLLERS: "10" ZBX_STARTPOLLERS_UNREACHABLE: "2" ZBX_STARTPREPROCESSORS: "5" ZBX_CACHESIZE: "128M" ZBX_HISTORYCACHESIZE: "64M" ZBX_TRENDCACHESIZE: "64M" ZBX_HISTORYINDEXCACHESIZE: "16M" ZBX_TIMEOUT: "4" ZBX_LOGLEVEL: "3" ZBX_TLSCONNECT: "psk" ZBX_TLSACCEPT: "psk" ZBX_TLSCPSKIDENTITY: "zabbix_psk_001" ZBX_TLSCPSKFILE: "/etc/zabbix/psk.key" TZ: "Asia/Shanghai" volumes: - /srv/zabbix/server/psk.key:/etc/zabbix/psk.key:ro - /etc/localtime:/etc/localtime:ro depends_on: postgres: condition: service_healthy networks: zabbix-net: ipv4_address: 172.20.0.20 ports: - "10051:10051" - "10051:10051/udp" zabbix-web: image: zabbix/zabbix-web-nginx-pgsql:7.0-ubuntu-5.0 container_name: zabbix-web restart: always 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" ZBX_SERVER_NAME: "OpenEuler-Zabbix-7.0" TZ: "Asia/Shanghai" depends_on: zabbix-server: condition: service_started networks: zabbix-net: ipv4_address: 172.20.0.30 ports: - "8080:8080" zabbix-agent: image: zabbix/zabbix-agent:7.0-ubuntu-5.0 container_name: zabbix-agent restart: always environment: ZBX_SERVER_HOST: zabbix-server ZBX_HOSTNAME: "OpenEuler Host" ZBX_SERVER_ACTIVE: zabbix-server ZBX_PASSIVE_ALLOW: "true" ZBX_ACTIVE_ALLOW: "true" ZBX_TLSCONNECT: psk ZBX_TLSACCEPT: psk ZBX_TLSPSKIDENTITY: "zabbix_psk_001" ZBX_TLSPSKFILE: "/etc/zabbix/psk.key" TZ: "Asia/Shanghai" volumes: - /srv/zabbix/server/psk.key:/etc/zabbix/psk.key:ro - /etc/localtime:/etc/localtime:ro depends_on: zabbix-server: condition: service_started networks: zabbix-net: ipv4_address: 172.20.0.40 ports: - "10050:10050" networks: zabbix-net: driver: bridge ipam: config: - subnet: "172.20.0.0/24"

这个文件里每个配置项都是我实际跑过的,有几个地方是踩了坑之后才总结出来的,重点说下。

第一是健康检查。postgres服务的healthcheck非常关键,它决定了整个依赖链能不能正确启动。Zabbix Server容器在启动时要连接数据库执行初始化脚本,如果数据库还没就绪,server容器就会直接报连接失败然后退出。用depends_on配合condition: service_healthy可以很好地控制启动顺序,避免手动等待。如果你用的是旧版本docker-compose不支持condition语法,那就要在server容器里额外写一个wait-for-it脚本,麻烦很多。

第二是PSK加密配置。ZBX_TLSCONNECT: pskZBX_TLSACCEPT: psk表示server端主动连接agent时使用PSK加密,同时也接受agent用PSK加密连接回来。这里最关键的是PSK文件,需要在宿主机上提前生成,并且server和agent容器都要挂载同一个文件:

openssl rand -hex 64 > /srv/zabbix/server/psk.key

生成后文件内容是一串64字节的十六进制字符串,也就是128个字符。两个容器挂载同一个文件,PSK身份标识保持一致,通信才能建立。如果不启用加密,Zabbix 7.0默认的明文通信在跨网段监控时会存在安全隐患,尤其监控数据经过核心交换机时,明文传输很容易被截获分析。虽然启用加密会带来一点点性能损耗,但相比安全收益完全可以忽略。

第三是web服务的端口。Zabbix Web默认服务端口是8080,我在compose里映射成了8080:8080。如果你宿主机上还有别的服务占用了8080,果断改成18080:8080之类的映射,这个根据实际情况调整即可。

3.3 启动命令与初始化验证

配置文件写好之后,启动命令很简单:

cd /srv/zabbix docker-compose up -d

第一次启动会拉取大量镜像,postgres:16-alpine大约80MB,zabbix-server和zabbix-web镜像加起来大约1GB左右,根据网络情况可能需要几分钟到十几分钟不等。启动完成后看一下所有服务的状态:

docker-compose ps

正常情况下四个服务都应该是Up状态。如果某个服务不断重启,用下面的命令查看日志:

docker-compose logs -f zabbix-server

这里我要特别强调:Zabbix Server容器首次启动时会执行数据库schema初始化,这个过程可能持续2到5分钟。如果用docker-compose ps看到server容器一直显示“restarting”或者还在“starting”,不要急着删了重来,先看日志里是否在打印初始化SQL语句。一旦初始化和升级完成,server会产生突破性的“Zabbix server started”日志。如果日志里反复出现“FATAL: password authentication failed”,那就要检查数据库容器里的账号密码是否和compose文件里的配置一致。

整个启动完成后,在浏览器访问http://<服务器IP>:8080,看到Zabbix的登录页面,默认账号是Admin,密码是zabbix,这一步就算一半成功。登录进去以后第一件事是修改默认密码,这一点不用我多提醒,Zabbix默认密码在公网环境下基本等于裸奔。

4. Zabbix 7.0核心功能落地:邮件告警与MySQL监控

4.1 邮件告警配置:从媒介到动作的完整链路

Zabbix装好只是第一步,真正让它发挥价值的是告警能力。我项目上经常需要给客户配置邮件告警,Zabbix 7.0里邮件告警的配置链路比旧版本清晰了不少,但新手还是有容易卡住的地方。

首先要在“管理 → 报警媒介类型”里配置SMTP服务器。Zabbix 7.0内置的Email媒介类型已经支持SMTP认证和SSL/TLS,不需要额外安装脚本。配置时注意几个关键字段:

  • SMTP服务器:填写你公司邮件网关的地址,比如smtp.example.com
  • SMTP服务器端口:常用的有465(SSL)、587(STARTTLS)、25(明文),根据邮件服务器配置选择。实测很多企业邮箱使用465端口效果最稳定。
  • SMTP HELO:填写本机或监控服务器的域名,格式比如zabbix.example.com,这个值必须和SMTP服务器的反解记录匹配,否则部分网关会拒信。
  • 加密方式:如果端口是465就选SSL/TLS,是587就选STARTTLS。
  • 认证:开启后填写发件邮箱账号和授权码。这里特别强调:大多数企业邮箱不能用登录密码做SMTP认证,要用客户端授权码,很多人在这一步卡住。去邮箱后台开启SMTP服务并生成授权码后再填入。

媒介类型保存后,下一步是给用户配置告警媒介。路径是“管理 → 用户 → 选择Admin用户 → 报警媒介 → 添加”,在这里选择刚才配置好的Email媒介,填入收件人邮箱地址,告警时间范围默认全天即可。

最后也是最容易忽略的一步:创建告警动作。在“告警 → 动作 → 创建动作”里配置触发条件,比如触发器严重性≥警告,然后添加操作,操作类型选择“发送消息”,收件人选择“用户群组”,媒体类型选择刚才的Email。很多人配置完媒介就以为会收到告警,结果什么都没收到,问题就出在动作没创建。

测试方法很简单:可以手动停掉一个被监控服务,等触发器触发后看“告警 → 问题”里是否正常生成条目,以及“报告 → 动作日志”里邮件发送的日志状态。如果动作日志显示发送失败,去查一下SMTP配置的认证信息和端口,这是最常在的点。

4.2 监控MySQL数据库:模板应用与账号授权

Zabbix 7.0内置的MySQL监控模板叫“MySQL by Zabbix agent 2”,这个模板走的是agent 2的插件机制,比旧版本用外部脚本的方式稳定得多。要在被监控的MySQL实例上做两件事:创建监控账号、配置agent插件。

MySQL端创建账号的授权SQL如下:

CREATE USER 'zabbix'@'%' IDENTIFIED BY 'zabbix_monitor_pass'; GRANT SELECT, PROCESS, REPLICATION CLIENT ON *.* TO 'zabbix'@'%'; FLUSH PRIVILEGES;

这里强调一下:PROCESS权限是必须的,否则模板里的很多监控项会返回“Access denied”。REPLICATION CLIENT权限用于获取主从复制状态,如果只监控单实例,不配置也不影响核心监控项,但为了模板完整建议都加上。

然后需要在被监控主机上安装Zabbix Agent 2,并配置MySQL插件参数。agent 2的配置文件默认在/etc/zabbix/zabbix_agent2.conf,需要新增以下配置:

Plugins.Mysql.Uri=tcp://127.0.0.1:3306 Plugins.Mysql.User=zabbix Plugins.Mysql.Password=zabbix_monitor_pass

如果MySQL不在本机,把Uri改成对应主机的IP和端口。重启agent后,在Zabbix Web界面的“数据采集 → 主机”里为这台机器添加模板,选择“MySQL by Zabbix agent 2”,然后等一个采集周期(默认60秒),在“监测 → 最新数据”里筛选主机就能看到大量MySQL监控指标。

这里必须提醒一个实际遇到过的问题:很多生产数据库出于安全考虑,限制了本机回环之外的MySQL连接。如果你的agent和MySQL不在同一台机器上,光在SQL层面授权还不够,还要检查MySQL的bind-address配置和防火墙策略,确保agent所在主机可以TCP访问MySQL的3306端口。

5. 常见故障与避坑实录

5.1 故障速查表

这一节直接用一个表格把我在这套部署中遇到的故障现象、原因和解决办法列出来,方便后续排查时直接对照参考。

故障现象根本原因解决办法
zabbix-server容器反复重启,日志报database is down数据库初始化未完成或连接参数不一致确认POSTGRES_USER/PASSWORD和数据库容器环境变量一致;首次启动等待3-5分钟;用docker-compose logs postgres看数据库日志
Web界面访问提示Unable to connect to databaseweb容器与数据库的网络连通性异常检查compose网络配置,确认web容器可以ping通postgres;检查数据库账号密码是否匹配;用docker exec -it zabbix-web ping postgres排查
仪表盘所有图表显示时间为UTC,差8小时容器默认时区未配置在所有服务环境变量里设置TZ: "Asia/Shanghai",并挂载/etc/localtime到容器
重启宿主机后所有容器没有自动启动缺少restart: always策略在compose文件中为所有服务添加restart: always,或者用docker update --restart always <容器名>批量设置
agent被动监控项全部返回ZBX_NOTSUPPORTEDagent连接server失败或PSK配置不一致检查10051端口监听和防火墙;确认server和agent挂载的PSK文件一致、身份标识相同
邮件告警发送失败,动作日志提示SMTP connection refusedSMTP端口被防火墙屏蔽或邮件网关拒绝转发测试从宿主机telnet smtp.example.com 465看端口连通性;检查是否用过时的密码而非授权码
数据库目录占用空间快速增长未清理历史数据配置Zabbix历史数据保留策略,或使用分区表脚本定期清理history表

5.2 时区问题的全面排查思路

时区问题在这套部署里非常高频,值得专门展开说一下。Zabbix 7.0容器化部署涉及三种“时间”概念:宿主机时间、容器系统时间、数据库时间。如果三者不一致,就会看到监控数据采集正常但图表显示时间偏移8小时。

我的排查顺序是:

第一步看宿主机时间:

date

如果宿主机时间正常,第二步进容器看:

docker exec -it zabbix-server date

如果容器显示UTC时间,那就是环境变量TZ没有生效。注意老版本的镜像对TZ环境变量的支持不完全一致,稳妥起见同时挂载/etc/localtime

/usr/share/zoneinfo/Asia/Shanghai:/etc/localtime:ro

第三步看数据库时间:

docker exec -it zabbix-postgres psql -U zabbix -d zabbix -c "SELECT NOW();"

PostgreSQL的时间如果也是UTC,需要在postgres容器中也设置TZ环境变量。只要三个层面都统一为北京时间,图表上的时间就正常了。

5.3 容器网络与防火墙的典型坑

OpenEuler 22.03 LTS默认开启了firewalld服务,这会导致Docker映射端口外部无法访问。我遇到过用户反馈Web页面打不开,结果排查半天发现是firewalld拦住了8080端口。

解决办法有两种:一种是直接放行端口:

sudo firewall-cmd --permanent --add-port=8080/tcp sudo firewall-cmd --permanent --add-port=10051/tcp sudo firewall-cmd --permanent --add-port=10050/tcp sudo firewall-cmd --reload

另一种是如果内网环境信任所有来源,可以临时关闭firewalld,但生产环境不建议。更优雅的做法是把Docker的bridge网段加入firewalld的信任区:

sudo firewall-cmd --permanent --zone=trusted --add-interface=docker0 sudo firewall-cmd --reload

这种方法适用于所有Docker映射端口都需要对宿主机网络开放的情况,避免了逐个端口放行的繁琐操作。

另外还有一个隐藏问题:当agent与server在不同宿主机时,agent的ZBX_SERVER_HOST要填写server宿主机的IP,不能填容器IP。因为agent是被动模式下由server主动向agent的10050发起TCP连接,agent需要知道server从哪里来,但不需要真正主动连到server(主动模式除外)。如果填写容器IP,agent在被动模式下不影响,但ZBX_SERVER_ACTIVE配置的主动检查就无法连上server了。

5.4 容器内存限制与性能调优经验

Zabbix 7.0对内存的需求比旧版本略高,尤其是PHP-FPM进程和Zabbix Server的缓存。我在OpenEuler上遇到过一个问题:部署完毕后Web界面偶尔出现502 Bad Gateway,重启web容器能恢复,但过两天又出现。最终排查是容器内存不足,PHP-FPM进程被OOM Killer杀掉。

当时的宿主机器内存只有8GB,PostgreSQL加上Zabbix Server加上Web,三个容器加起来吃掉了将近5GB。解决办法是在compose配置里给每个服务设置内存上限:

deploy: resources: limits: memory: 2G

同时调整PHP-FPM进程数,在web容器的环境变量中设置:

environment: PHP_MAX_CHILDREN: "20" PHP_START_SERVERS: "5" PHP_MIN_SPARE_SERVERS: "2" PHP_MAX_SPARE_SERVERS: "5"

这套参数的含义是:最多启动20个PHP-FPM进程处理Web请求,初始启动5个,最少保留2个空闲进程,最多保留5个空闲进程。对于几十个节点的中小型监控环境,这个配置足够流畅。如果节点数上百,建议把宿主机内存加到16GB以上,PHP_MAX_CHILDREN可以调到30。

6. 最后再说几句大实话

整套Zabbix 7.0在OpenEuler 22.03 LTS上容器化部署,从我接触这个组合到彻底跑通,前前后后花了差不多两个完整工作日。大部分时间其实不是花在Zabbix上,而是花在环境差异的适配和不知道去哪查问题的过程里。官方文档写的是通用情况,但每个发行版都有自己的脾气,OpenEuler更不例外。

我个人操作下来的体会是:如果预算和团队精力允许,直接用这套容器化方案作为生产环境的标准部署方式,不要再走rpm手工安装的老路。容器化带来的可复现性、升级便利性和故障恢复速度,在长期运维中节省的时间绝对值得前期这几天的折腾。

最后再分享一个小技巧:这套compose配置尽量保存到Git仓库里,版本化管理。后面如果有机器需要批量部署,把配置拉下来改一下IP和密码就能直接用。我后面的项目里凡是新装监控,基本都是直接复用这套模板,从拉代码到监控页面能登录,半小时以内就能搞定。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/17 3:47:34

行星齿轮组动力学建模与ode45求解实践

简介&#xff1a;面向机械工程、车辆工程与齿轮动力学方向的学习者和研究者&#xff0c;这份MATLAB代码资源聚焦行星齿轮组微分方程组的建模与数值求解。资源将太阳轮、行星轮、行星架和内齿圈构成的多体动力学问题转化为ODE初值问题&#xff0c;并通过ode45进行求解&#xff1…

作者头像 李华
网站建设 2026/9/17 3:45:57

Java类与对象深度解析:从封装设计到内存机制实战

1. 从复制代码到设计代码&#xff1a;类和对象思维到底转变在哪1.1 先别背定义&#xff0c;看看类和对象在业务里长什么样我在带新人或者帮同事review代码的时候&#xff0c;经常遇到一种情况&#xff1a;刚学Java的人能把"类是抽象模板&#xff0c;对象是具体实例"这…

作者头像 李华
网站建设 2026/9/17 3:45:15

土壤水势传感器CG-36:原理、安装与灌溉决策实战指南

1. 先弄懂水势是什么&#xff1a;为什么“含水率够”不等于“作物不渴”1.1 从“存水量”到“取水难度”的思维转变种过地的人都知道一个看似矛盾的现象&#xff1a;有时候明明测出来土壤含水率还挺高&#xff0c;作物却已经蔫了。反过来&#xff0c;有些沙土地看着干得不行&am…

作者头像 李华
网站建设 2026/9/17 3:41:31

基于OpenMV与Python的车牌识别系统实现

简介&#xff1a;这是一份基于Python与OpenMV的车牌检测毕业设计资源包&#xff0c;面向计算机视觉、嵌入式方向的本科毕业生及入门开发者。项目围绕小车摄像头实时识别车牌展开&#xff0c;覆盖车牌定位与内容识别两条核心链路&#xff0c;并选用Haar级联作为检测方案。资源共…

作者头像 李华