香橙派 2核2G 环境 Zabbix + PG + Grafana 轻量化部署笔记

一、 环境与架构说明

  • 硬件限制:CPU 2核,内存 2GB(ARMv8 / Allwinner H618)。磁盘介质通常为 MicroSD 卡或 eMMC,I/O 性能极弱。
  • 部署工具:Podman / Podman-compose
  • 优化核心
  • 数据驱动优先:Grafana 尽量采用原生插件(如 Sun and Moon)或数据源驱动,避免使用高内存消耗的组件。
  • 抹平磁盘 I/O:彻底关闭容器标准输出日志,关闭数据库 fsync 强行刷盘,降低 Zabbix 与 Grafana 日志级别。
  • 内存严控:大幅缩减 Zabbix 和 PHP-FPM 的并发进程数,控制 PostgreSQL 缓存。

二、 容器服务调优配置

1. PostgreSQL 16 数据库配置

  • 优化策略:通过命令行参数强制覆盖默认配置。关闭 fsyncsynchronous_commit,牺牲断电时的极端数据安全性,换取闪存卡寿命;严控 work_mem 防止高并发查询导致 OOM。
  • 数据持久化:必须进行宿主机卷挂载(:Z 用于 Podman/SELinux 权限适配)。
  postgres:
    image: docker.io/library/postgres:16-alpine
    container_name: postgres
    # 通过 -c 参数直接在启动命令中注入核心调优,覆盖默认配置文件
    command: >
      postgres
      -c fsync=off                          # 强制关闭同步刷盘,极大延长 SD 卡寿命
      -c synchronous_commit=off             # 事务异步提交,降低磁盘写入高频等待
      -c shared_buffers=256MB                # 共享缓冲区大小,限制为系统总内存的 1/8
      -c work_mem=4MB                        # 单个内部排序操作和哈希表使用的内存,防止并发高时内存溢出
      -c maintenance_work_mem=32MB           # 维护性操作(如创建索引、VACUUM)的最大内存
      -c effective_cache_size=512MB          # 估算可用于评估计划的磁盘高速缓存大小
      -c wal_level=minimal                   # 将预写日志(WAL)降到最低,只保留崩溃恢复所需信息
      -c max_wal_senders=0                   # 关闭主从流复制线程,释放 CPU 与内存
      -c checkpoint_completion_target=0.9    # 三级检查点刷新目标,平摊 I/O 写入压力
      -c max_wal_size=512MB                  # 限制最大 WAL 日志体积,防止撑爆磁盘
      -c min_wal_size=80MB                   # 最小 WAL 日志体积
      -c logging_collector=off               # 关闭 PG 内部的日志收集器
      -c log_min_messages=panic              # 仅记录导致服务器崩溃的灾难性错误,保持完全安静
    environment:
      - POSTGRES_DB=zabbix                  # 初始化自动创建的数据库名称
      - POSTGRES_USER=zabbix                # 数据库超级用户名
      - POSTGRES_PASSWORD=your_secure_password # 数据库密码
    volumes:
      - /home/orangepi/pg_data:/var/lib/postgresql/data:Z # 宿主机持久化目录挂载
    deploy:
      resources:
        limits:
          memory: 600M                      # 严格限制该容器最大可用内存
    logging:
      driver: none                           # 丢弃容器标准输出日志,避免产生 JSON 日志文件

2. Zabbix Server 7.0 配置

  • 优化策略:将日志级别压到最低。大幅裁撤不必要的常驻轮询进程(如关闭自动发现、Web 监测),控制历史数据写入线程数量(ZBX_STARTDBSYNCERS=2),减少数据库锁争抢。
  • 持久化说明:Server 容器为无状态,所有主机配置、触发器、监控项数据均由核心调优后的 PostgreSQL 承载,容器自身无需做持久化。
  zabbix-server:
    image: docker.io/zabbix/zabbix-server-pgsql:alpine-7.0-latest
    container_name: zabbix-server
    environment:
      - ZBX_DEBUGLEVEL=0                    # 关闭 Zabbix Server 内部的常规 Debug 日志
      - ZBX_LOGLEVEL=2                      # 调整日志输出级别,只打印错误和警告信息
      - ZBX_STARTPOLLERS=3                  # 常规主动/被动检测的轮询器线程数(从默认值大幅调低)
      - ZBX_STARTPINGERS=2                  # ICMP Ping 检查的线程数
      - ZBX_STARTPOLLERSUNREACHABLE=1       # 不可达设备检查的线程数
      - ZBX_STARTTRAPPERS=1                 # 接收 Agent 主动上报数据的线程数
      - ZBX_STARTDISCOVERERS=0              # 网络自动发现线程数(若固定设备监控,直接关闭设为0)
      - ZBX_STARTHTTPPOLLERS=0              # Web 场景监测线程数(不使用自带网页探测则关闭设为0)
      - ZBX_STARTDBSYNCERS=2                # 数据同步器线程数(控制从内存缓存同步到 PG 的并发,缓解I/O)
      - ZBX_HISTORYCACHESIZE=16M            # 存储历史数据的内存缓存大小
      - ZBX_HISTORYINDEXCACHESIZE=4M        # 存储历史数据索引的内存缓存大小
      - ZBX_TRENDCACHESIZE=8M               # 存储趋势(聚合)数据的内存缓存大小
      - ZBX_VALUECACHESIZE=16M              # 存储触发器计算历史值的内存缓存大小
      - DB_SERVER_HOST=postgres             # PostgreSQL 数据库的容器连接地址
      - POSTGRES_USER=zabbix                # 数据库连接用户名
      - POSTGRES_PASSWORD=your_secure_password # 数据库连接密码
      - POSTGRES_DB=zabbix                  # 目标数据库名
    deploy:
      resources:
        limits:
          memory: 400M                      # 严格限制该容器最大可用内存
    logging:
      driver: none                           # 丢弃容器标准输出日志,保护闪存卡

3. Zabbix Web (Nginx + PHP-FPM) 配置

  • 优化策略:严格限制 PHP_MAX_CHILDREN 数量,从默认值调低至 3,防止多图表同时请求时内存激增。
  • 持久化说明:Web 前端为无状态。配置的自定义仪表盘(Dashboards)、用户界面布局均保存在 PostgreSQL 数据库中。重建容器仅会导致当前浏览器 Session 失效(需重新登录)以及容器内临时追加的特殊字体丢失。

3.1 Nginx 配置覆盖 (access_log off)

  • 变量作用:彻底关闭 Nginx 引擎对每次页面刷新、API 请求的访问日志记录。
  • 技术背景:Zabbix 7.0 官方 Alpine 镜像移除了传统的 /etc/nginx/conf.d/ 目录,改用主配置文件 nginx.conf 中的 include /etc/nginx/includes/access-log.conf; 来引入访问日志。
  • 实现策略:无需重写复杂的 Nginx 虚拟主机配置,直接在宿主机生成一个空文件,强制挂载并覆盖容器内的 access-log.conf。此方案最安全,100% 保持官方网页服务的核心转发逻辑,且不影响后续版本升级。

3.2 在香橙派宿主机上创建空配置文件

执行以下命令,在宿主机指定工作目录下生成一个用于覆盖的完全空白的文件:

mkdir -p /home/orangepi/zabbix_nginx
touch /home/orangepi/zabbix_nginx/empty_access_log.conf
# 赋予该空文件全员可读写权限,否则容器报错起不来
chmod 666 /home/orangepi/zabbix_nginx/empty_access_log.conf

3.3 更新 podman-compose.yml 编排文件

  zabbix-web:
    image: docker.io/zabbix/zabbix-web-nginx-pgsql:alpine-7.0-latest
    container_name: zabbix-web
    volumes:
      - /home/orangepi/zabbix_nginx/empty_access_log.conf:/etc/nginx/includes/access-log.conf:Z
    environment:
      - ZBX_MAXEXECUTIONTIME=150            # PHP 脚本最大执行超时时间
      - PHP_MAX_CHILDREN=3                  # PHP-FPM 最大子进程数(从5降到3,极限压榨内存开销)
      - ZBX_DEBUGLEVEL=0                    # 关闭前端页面的调试日志
      - ZBX_LOGLEVEL=2                      # 减小CPU 计算资源和内存,调整日志输出级别,只保留严重错误,阻断容器标准输出
      - DB_SERVER_HOST=postgres             # PostgreSQL 数据库的容器连接地址
      - POSTGRES_USER=zabbix                # 数据库连接用户名
      - POSTGRES_PASSWORD=your_secure_password # 数据库连接密码
      - POSTGRES_DB=zabbix                  # 目标数据库名
    deploy:
      resources:
        limits:
          memory: 300M                      # 严格限制该容器最大可用内存
    logging:
      driver: none                           # 丢弃容器标准输出日志,防止 Nginx 的 access.log 刷盘

4. Grafana 配置

  • 优化策略:彻底关闭内部日志落盘、官方动态新闻及匿名数据上报。强制锁定全局中文(zh-Hans),允许加载未签名的 Zabbix 官方插件。同步配置上海时区,防止时序数据及天气组件出现 8 小时时差。

4.1 权限冲突原因说明

  • 容器内部:Grafana 官方镜像默认以 grafana 用户(UID 472)和 root 组(GID 0)运行。
  • 宿主机内部:以 root 用户提取文件后,文件的所有者通常为宿主机的 root:root0:0)。
  • 后果:若不调整权限,容器启动后写数据库时会触发 Permission denied 错误。

4.2 调整宿主机权限命令

在 Podman Root 模式下,容器内外 UID 映射是一致的。需要在香橙派宿主机上将数据目录的所有者修改为 472:0

chown -R 472:0 /data/gra/gdata

修改后,宿主机中该目录下的文件所有者将显示为数字 472grafana(若宿主机存在同名用户),容器即可获得完整的读写权限。

4.3 Grafana 编排配置

  grafana:
    image: docker.io/grafana/grafana:main-slim
    container_name: grafana
    logging:
      driver: none  # 告诉 Podman 这个容器不需要 any 标准输出日志,直接抛弃
    tmpfs:
      - /var/lib/grafana/png:size=30M  # 限制 30M 供图表快照图片缓存使用
      - /var/lib/grafana/csv:size=10M  # 限制 10M 供临时数据导出使用
    volumes:
      - /data/gra/gdata/plugins:/var/lib/grafana/plugins:Z    # 插件目录
      - /data/gra/gdata/grafana.db:/var/lib/grafana/grafana.db:Z   # 数据库文件
    environment:
      - TZ=Asia/Shanghai                                                # 强制设定容器内部时区为北京时间
      - GF_SECURITY_ALLOW_EMBEDDING=true                                # 允许 Grafana 仪表盘被 iframe 嵌入外部网页
      - GF_USERS_ALLOW_SIGN_UP=false                                    # 关闭前端注册功能,防止非授权人员注册
      - GF_AUTH_ANONYMOUS_ENABLED=true                                  # 开启匿名(免密)访问功能
      - GF_AUTH_ANONYMOUS_ORG_NAME=Main Org.                            # 匿名访问关联的默认组织
      - GF_AUTH_ANONYMOUS_ORG_ROLE=Viewer                               # 匿名用户的权限限制(只读查看者)
      - GF_LOG_MODE=console                                             # 强制日志仅输出到标准控制台,不写入本地文件
      - GF_LOG_LEVEL=critical                                           # 仅在发生灾难性系统崩溃时才记录日志
      - GF_ANALYTICS_REPORTING_ENABLED=false                            # 关闭官方的匿名使用数据及崩溃信息上报
      - GF_DASHBOARDS_NEWS_FEED_ENABLED=false                           # 彻底关闭首页右侧的 Grafana 最新动态新闻
      - GF_DASHBOARDS_BLOG_FEED_URL=                                    # 清空官方博客更新地址,阻断后台轮询请求
      - GF_SECURITY_ADMIN_USER=aaaa                                     # 默认管理员初始账号
      - GF_SECURITY_ADMIN_PASSWORD=aaaaa                                # 默认管理员初始密码
      - GF_USERS_DEFAULT_THEME=dark                                     # 锁定全局默认主题为暗黑模式(降低屏幕开销与功耗)
      - GF_FEATURE_TOGGLES_ENABLE=internationalization,languageChooser   # 启用多语言支持特性开关
      - GF_INTERNATIONALIZATION_DEFAULT_LANGUAGE=zh-Hans                # 设置国际化组件默认语言为简体中文
      - GF_ANALYTICS_DEFAULT_LANGUAGE=zh-Hans                           # 设置分析组件默认语言为简体中文
      - GF_USERS_DEFAULT_LANGUAGE=zh-Hans                               # 设置默认新用户语言为简体中文
      - GF_SERVER_OVERRIDE_LANGUAGE=true                                # 强制覆盖用户浏览器本地语言,统一锁定中文显示
      - GF_PLUGINS_ALLOW_LOADING_UNSIGNED_PLUGINS=alexanderzobnin-zabbix,alexanderzobnin-zabbix-app,alexanderzobnin-zabbix-datasource # 强制允许加载未经过官方安全签名的 Zabbix 核心插件
    deploy:
      resources:
        limits:
          memory: 250M                      # 严格限制该容器最大可用内存
    logging:
      driver: none                           # 丢弃容器标准输出日志,降低 I/O 开销

三、 生活信息大屏组件(天气/日出日落/日历)实现方案

在数据驱动的插件方案下,Grafana 可通过安装轻量化插件实现监控以外的信息看板功能。

1. 基础插件安装命令

在香橙派宿主机终端执行以下命令安装核心组件(安装后需重启 Grafana 容器):

# 安装本地经纬度算力数据源(计算日出日落)
podman exec -it grafana grafana-cli plugins install fetzerch-sunandmoon-datasource

# 安装 JSON API 解析插件(用于抓取天气数据)
podman exec -it grafana grafana-cli plugins install marcusolsson-json-datasource

# 注:新版 Grafana 已内置 Calendar(日历)面板,无需额外安装

2. 各组件具体配置方法

A. 日出日落时间(Sun and Moon 插件)

  • 原理:纯本地算法,依靠经纬度计算,零网络 I/O。
  • 数据源配置:添加 Sun and Moon 数据源,输入当地经纬度(如北京:Latitude 39.9, Longitude 116.4)。
  • 面板配置:添加 Stat(大数字)面板,Metric 选择 Sun,Field 选择 SunriseSunset。在 Standard options -> Unit 中将其格式化为 Date & time -> Time (HH:mm:ss)

B. 实时天气看板(JSON API 数据源)

  • 原理:调用第三方网络 API(如和风天气、OpenWeatherMap),通过 JSON 驱动原生面板,避免加载复杂的外部 HTML iframe 网页。
  • 数据源配置:添加 JSON API 数据源,填入天气 API 基础 URL(如和风天气 https://devapi.qweather.com/v7/weather/now)。
  • 面板配置:在 Query Params 中传入城市 ID 和 API Key。在 Fields 属性中通过 JsonPath 提取当前温度($.now.temp)和天气文本($.now.text),并配合 Stat 面板 进行呈现。
  • 优化频率:在 Query options -> Min interval 中强制限制最小刷新间隔为 30m(30分钟),降低高频网络请求和内存损耗。

C. 交互日历面板(内置 Calendar 组件)

  • 原理:Grafana 内置 Calendar 面板可通过标准时间序列或 SQL 行数据自动绘制日程。
  • 数据接入:可直接连接现有的 PostgreSQL 数据库。
  • SQL 映射规范:编写 SQL 检索日程表时,必须通过 AS 关键字将字段重命名为规范的别名,以便 Calendar 组件识别:
SELECT 
  task_start_time AS time, -- 时间戳绑定
  task_name AS text,       -- 日历单元格显示的文本内容
  priority AS tags         -- 可选:分类标签,用于多色彩日程标记
FROM my_todo_list
WHERE $__timeFilter(task_start_time)

四、 运维避坑与注意事项

  1. 容器重建与配置生效:使用 podman-compose up -d 刷新配置时,无持久化的 zabbix-serverzabbix-web 容器会被删除并重建,属于正常行为。只要 PostgreSQL 映射了本地目录,核心资产(仪表盘、监控主机等)就不会丢失。
  2. 安全性审计:由于启用了匿名免密只读访问(GF_AUTH_ANONYMOUS_ENABLED=true),必须进入 Zabbix Web 控制台,为 Grafana 创建一个专用的、仅具有 Read-Only(只读)权限的用户。绝对禁止直接将 Zabbix 的 Super Admin 账号暴露在公共大屏的 Grafana 数据源中。
  3. 刷新率红线:为了防止香橙派 CPU 被高频查询卡死,Grafana 所有的仪表盘默认自动刷新频率(Refresh interval)严禁设置为 5s10s,建议统一放宽至 1m(1分钟)或 5m

标签: none

添加新评论