Podman 部署 Zabbix 7.0 解决 ICMP (fping) 权限问题笔记

1. 问题现象

在 Podman 环境中通过 Compose 部署 Zabbix 7.0 架构(PostgreSQL + Zabbix Server + Zabbix Web)后,在前端配置主机 ICMP 监控时无法使用,查看日志或执行测试时报错:

sh: /usr/sbin/fping: Operation not permitted

2. 原因分析

  • Podman 的安全机制: 与 Docker 默认行为不同,Podman 为了提升安全性(尤其在 Rootless 模式下),默认对容器施加了严格的 Linux Capabilities 限制。
  • fping 的权限需求: Zabbix 的 ICMP 检查依赖系统内的 fping 命令,该命令在运行时需要创建原始套接字(Raw Socket),这要求容器必须具备内核的 CAP_NET_RAW 能力。由于 Podman 默认禁用了此能力,导致程序报权限不足错误。
  • 执行主体: 在 Zabbix 架构中,ICMP 检查是由 Zabbix Server(或 Proxy)容器实际执行的,而非 Zabbix Web 容器。

3. 解决方案

3.1 容器编排文件配置 (podman-compose)

通过在 zabbix-server 服务下添加 cap_add 来赋予网络底层权限。如果宿主机开启了 SELinux(如 CentOS/RHEL/Rocky Linux),还需要同时添加 security_opt 关闭安全标签限制。

修改后的 docker-compose.ymlpodman-compose.yml 关键片段如下:

version: '3.5'

services:
  zabbix-db:
    image: docker.io/library/postgres:16-alpine
    container_name: zabbix-db
    environment:
      - POSTGRES_USER=zabbix
      - POSTGRES_PASSWORD=zabbix_password
      - POSTGRES_DB=zabbix
    volumes:
      - zabbix-db-data:/var/lib/postgresql/data
    networks:
      - zabbix-net

  zabbix-server:
    image: docker.io/zabbix/zabbix-server-pgsql:alpine-7.0-latest
    container_name: zabbix-server
    restart: always
    ports:
      - "10051:10051"
    # ---- 核心解决 fping 报错的配置 ----
    cap_add:
      - NET_RAW
    security_opt:
      - label=disable
    # --------------------------------
    environment:
      - DB_SERVER_HOST=zabbix-db
      - POSTGRES_USER=zabbix
      - POSTGRES_PASSWORD=zabbix_password
      - POSTGRES_DB=zabbix
    networks:
      - zabbix-net

  zabbix-web:
    image: docker.io/zabbix/zabbix-web-nginx-pgsql:alpine-7.0-latest
    container_name: zabbix-web
    ports:
      - "8080:8080"
    environment:
      - DB_SERVER_HOST=zabbix-db
      - POSTGRES_USER=zabbix
      - POSTGRES_PASSWORD=zabbix_password
      - POSTGRES_DB=zabbix
      - ZBX_SERVER_HOST=zabbix-server
    networks:
      - zabbix-net

networks:
  zabbix-net:
    driver: bridge

3.2 独立重新部署 Server 端

微服务架构中各组件相互独立。由于调整仅涉及 Server 端的权限,不需要重新部署 Web 端或数据库端。只需单独销毁并重建 Server 容器即可,已有的监控配置和历史数据不会受到影响。

执行以下命令重新部署 Server:

# 1. 停止并删除旧的 server 容器
podman-compose stop zabbix-server
podman-compose rm -f zabbix-server

# 2. 重新启动 server(自动加载新加入的权限配置)
podman-compose up -d zabbix-server

3.3 验证修复结果

可以通过进入 Server 容器内部手动执行 fping 命令来验证权限是否恢复:

# 进入 server 容器
podman exec -it zabbix-server sh

# 在容器内测试 ping 外部网络
fping 114.114.114.114

若返回 114.114.114.114 is alive,则代表权限配置成功。

4. Zabbix 前端键值优化建议

在排查阶段,曾尝试将 ICMP 相关的监控项键值进行如下调整:

监控项尝试修改后的键值
ICMP pingicmpping[{HOST.HOST}]
ICMP lossicmppingloss[{HOST.HOST}]
ICMP response timeicmppingsec 修改为 icmppingsec[{HOST.HOST}]

建议:修改回原版键值(删除参数),改回后,主机监控没数据了,之前你把键值改成 icmpping[{HOST.HOST}] 时,Zabbix 会把你的“主机名称”带入进去。而你的主机名称刚好填的就是 IP 地址 192.168.1.9,所以 fping 192.168.1.9 就能直接跑通。换回原版留空的 icmpping 后,Zabbix 必须强制依赖监控项自身绑定的 Interface。因为是从模板直接拉过来的,它默认没有和任何接口连上(处于 None 状态),所以才会一直提示找不到目标。删除主机,重新添加后,正常。

在容器权限修复后,强烈建议将键值改回原版留空状态(即 icmppingicmppinglossicmppingsec),原因如下:

  1. 原版机制: Zabbix 的简单检查(Simple Checks)中,如果键值的第一个参数留空,系统会自动填充当前主机在“接口(Interface)”中所配置的 IP 地址,这属于标准设计而非 Bug。
  2. 潜在风险:{HOST.HOST} 代表的是 Zabbix 中的“主机名称”,而不是 IP 地址。如果主机名称包含中文、特殊字符,或者是一个无法被本地 DNS 解析的内部代号,手动指定 [{HOST.HOST}] 会导致 fping 因无法解析域名而报错。只有在“主机名称”与“IP/可用域名”完全一致时该修改才能工作。

因此,在确认 NET_RAW 权限开通后,恢复原版留空的键值是最高效、稳定的最佳实践。

标签: none

添加新评论