igozhang

——

    Zabbix 6(K8S-SOLO)配置电话告警

    1. 目标与约定

    在 K8s 单节点上的 Zabbix 6 中,通过 ConfigMap 挂载拨号脚本到 Server,再用 UI 配置脚本媒介类型、用户媒介与 Warning 及以上触发器动作,实现按主机 IP 前缀映射基地名后的电话 TTS 告警。

    说明
    平台 Zabbix 6.0,Helm 部署于单节点 K8s(SOLO)
    方式 脚本 + ConfigMap 挂载;媒介类型 / 用户媒介 / 动作尽量 UI 配置
    范围 全部主机;严重性 Warning 及以上
    号码 固定号码(本文示例:13088888888
    主机名 与 IP 相同
    基地 按 IP 前两段映射,写入语音文案中的基地名

    基地映射(示例,仅 3 条示意,按实际环境扩展):

    IP 前缀 基地
    10.10 基地甲
    10.20 基地乙
    10.30 基地丙

    语音文案格式:

    {基地}服务器{IP}告警,{告警内容},请检查
    

    2. 环境前提(只读确认)

    在 K8s 控制节点执行。

    确认 Server 工作负载与 AlertScripts 路径:

    kubectl --request-timeout=10s -n zabbix get deploy zabbix-zabbix-server \
      -o jsonpath='{.metadata.annotations.meta\.helm\.sh/release-name}{"\n"}'
    
    kubectl --request-timeout=10s -n zabbix exec deploy/zabbix-zabbix-server -c zabbix-server -- bash -c \
      'grep -E "^AlertScriptsPath" /etc/zabbix/zabbix_server.conf; ls -la /usr/lib/zabbix/alertscripts'
    

    预期:

    • Helm release 名为 zabbix
    • AlertScriptsPath=/usr/lib/zabbix/alertscripts
    • 目录初始可为空

    确认容器内 HTTP 客户端与电话接口连通性(仅 TCP,不拨号):

    kubectl --request-timeout=10s -n zabbix exec deploy/zabbix-zabbix-server -c zabbix-server -- bash -c \
      'command -v wget; timeout 5 bash -c "echo >/dev/tcp/10.10.10.10/8080" >/dev/null 2>&1 && echo TCP_OK || echo TCP_FAIL'
    

    说明:本环境 Zabbix Server 镜像无 curl,有 wget;电话 TTS 接口示例地址为 http://10.10.10.10:8080/call/tts


    3. 创建告警脚本 ConfigMap(变更)

    脚本由 Zabbix 传入 3 个参数:

    1. {ALERT.SENDTO} → 电话号码
    2. {ALERT.SUBJECT} → 主机 IP(与主机名相同)
    3. {ALERT.MESSAGE} → 告警内容
    kubectl --request-timeout=10s -n zabbix create configmap zabbix-alertscripts \
      --from-file=call_phone.sh=/dev/stdin <<'EOF'
    #!/bin/bash
    set -euo pipefail
    
    PHONE="${1:-13088888888}"
    HOST_IP="${2:-}"
    ALERT_CONTENT="${3:-}"
    
    if [ -z "$HOST_IP" ]; then
      echo "ERROR: empty host/ip parameter" >&2
      exit 1
    fi
    
    PREFIX="$(printf '%s' "$HOST_IP" | cut -d. -f1-2)"
    case "$PREFIX" in
      10.10) BASE="基地甲" ;;
      10.20) BASE="基地乙" ;;
      10.30) BASE="基地丙" ;;
      *)     BASE="未知基地" ;;
    esac
    
    json_escape() {
      printf '%s' "$1" | perl -pe 's/\\/\\\\/g; s/"/\\"/g; s/\r/\\r/g; s/\n/\\n/g; s/\t/\\t/g'
    }
    
    INFO="${BASE}服务器${HOST_IP}告警,${ALERT_CONTENT},请检查"
    INFO_ESCAPED="$(json_escape "$INFO")"
    POST_DATA="{\"called_number\":\"${PHONE}\",\"called_show_number\":\"01000000000\",\"tts_code\":\"TTS_XXXXXXXXX\",\"tts_param\":\"{\\\"info\\\": \\\"${INFO_ESCAPED}\\\"}\"}"
    
    TMP_FILE="$(mktemp)"
    trap 'rm -f "$TMP_FILE"' EXIT
    printf '%s' "$POST_DATA" > "$TMP_FILE"
    
    wget -q -O - --timeout=8 \
      --header="Content-Type: application/json" \
      --post-file="$TMP_FILE" \
      "http://10.10.10.10:8080/call/tts"
    echo
    EOF
    

    4. 挂载到 zabbix-server(变更)

    将 ConfigMap 挂到 AlertScriptsPath。会滚动重启 Server Pod。

    若后续 helm upgrade 未带上同等 extraVolumes / extraVolumeMounts,挂载可能被覆盖,需同步写入 values。

    kubectl --request-timeout=10s -n zabbix patch deploy zabbix-zabbix-server --type=strategic -p '{
      "spec": {
        "template": {
          "spec": {
            "volumes": [
              {
                "name": "alertscripts",
                "configMap": {
                  "name": "zabbix-alertscripts",
                  "defaultMode": 493
                }
              }
            ],
            "containers": [
              {
                "name": "zabbix-server",
                "volumeMounts": [
                  {
                    "name": "alertscripts",
                    "mountPath": "/usr/lib/zabbix/alertscripts",
                    "readOnly": true
                  }
                ]
              }
            ]
          }
        }
      }
    }'
    

    defaultMode: 493 即八进制 0755,保证脚本可执行。

    推荐写入 Helm values(便于以后升级保留):

    zabbixServer:
      extraVolumes:
        - name: alertscripts
          configMap:
            name: zabbix-alertscripts
            defaultMode: 493
      extraVolumeMounts:
        - name: alertscripts
          mountPath: /usr/lib/zabbix/alertscripts
          readOnly: true
    

    校验:

    kubectl --request-timeout=10s -n zabbix rollout status deploy/zabbix-zabbix-server --timeout=10s
    
    kubectl --request-timeout=10s -n zabbix exec deploy/zabbix-zabbix-server -c zabbix-server -- bash -c \
      'ls -la /usr/lib/zabbix/alertscripts/..data/; test -x /usr/lib/zabbix/alertscripts/call_phone.sh && echo EXEC_OK'
    

    预期:call_phone.sh-rwxr-xr-x,输出 EXEC_OK


    5. UI 配置(Zabbix 6.0 菜单)

    Zabbix 6.0 无顶层 Alerts 菜单,路径如下。

    5.1 媒介类型

    Administration → Media types → Create media type

    字段
    Name Phone call
    Type Script
    Script name call_phone.sh
    Script parameters(顺序) {ALERT.SENDTO}
    {ALERT.SUBJECT}
    {ALERT.MESSAGE}

    Message templates → Problem

    字段
    Subject {HOST.HOST}
    Message {TRIGGER.NAME}

    启用并保存。

    说明:Script 媒介类型参数侧以 {ALERT.*} 为主;主机 IP 与告警内容分别放在 Subject / Message,由动作或媒介消息模板填充后传入脚本。

    5.2 用户媒介

    Administration → Users → 选用户 → Media → Add

    字段
    Type Phone call
    Send to 13088888888
    When active 1-7,00:00-24:00
    Use if severity Warning 及以上

    5.3 触发器动作

    Configuration → Actions(事件源 Triggers)→ Create action

    字段
    Name Phone call warning+
    Condition Trigger severity is greater than or equals Warning
    Operations 发送给对应用户/用户组;Send only to Phone call
    Recovery operations 不配置(恢复不拨号)

    启用并保存。

    5.4 关于两处严重性

    位置 作用
    动作条件 主开关:是否进入本动作的发送流程
    用户媒介 Use if severity 第二道过滤:该用户此媒介是否接听该级别

    只需一处限制到 Warning+ 即可满足需求;两边都设为 Warning+ 更稳妥。推荐至少保留动作条件


    6. 测试(会真实拨号)

    Administration → Media types → Phone call → Test

    字段 示例
    Send to 13088888888
    Subject 10.10.10.10
    Message UI test alert

    预期语音类似:基地甲服务器10.10.10.10告警,UI test alert,请检查


    7. 故障排查(可选)

    查看 Server 告警脚本相关日志(每次不超过 60 行):

    kubectl --request-timeout=10s -n zabbix logs deploy/zabbix-zabbix-server -c zabbix-server --tail=60 \
      | grep -E -i 'alert|script|call_phone|failed' || true
    

    常见问题:

    现象 排查
    测试无电话 媒介类型/用户媒介/动作是否 Enabled;严重性是否匹配
    脚本未执行 挂载路径、可执行位、Script name 是否为 call_phone.sh
    接口失败 Pod 到 10.10.10.10:8080 连通性;wget 是否可用
    helm upgrade 后失效 values 是否包含 extraVolumes / extraVolumeMounts

    MP3