Prometheus 告警怎么推到钉钉?从单群通知到跨网络 Alertmanager 实战

Prometheus 告警怎么推到钉钉?从单群通知到跨网络 Alertmanager 实战

前言

监控系统真正有价值的时刻,不是图表看起来多完整,而是异常发生以后,负责的人能不能及时收到一条足够清楚、能够继续处理的告警。Prometheus 负责发现问题,Alertmanager 负责分组、路由和通知,但钉钉并不是它直接支持的通知目标,所以中间还需要一层 prometheus-webhook-dingtalk。我比较在意这种链路能不能一段一段验证,而不是一上来就把"生产可用、高可靠"写在标题里。告警系统最怕的不是配置多,而是链路长:任何一环没通,最后表现出来都只是"群里没消息",所以越是这种跨组件集成,越应该先把每层职责拆开。我也不希望因为最终能收到一条消息,就默认中间所有环节都稳定可靠;只有逐层看清输入和输出,真正出问题时才知道应该从哪一段开始查。

这次的实操从 Prometheus 关联 Alertmanager 开始,先创建钉钉自定义机器人,再用 Docker 启动 prometheus-webhook-dingtalk,把 Alertmanager 的 Webhook 指向 8060 服务,并实际看到钉钉收到告警;随后继续扩展到两个钉钉群。最后再处理一个更容易被忽略的场景:Prometheus 和 Alertmanager 不在同一个局域网时,用 cpolar 把 Alertmanager 的 9093 端口提供成 TCP 公网入口,再让另一侧 Prometheus 指向这个地址。整篇只围绕一件事展开:告警从 Prometheus 出发,经过 Alertmanager 和 Webhook 中转,最后真正到达钉钉。

1. 先把整条告警链看清楚

这套方案里,各组件的职责并不复杂:

Prometheus → Alertmanager → prometheus-webhook-dingtalk → 钉钉机器人

其中:

  • Prometheus 负责采集指标,并根据规则触发告警;
  • Alertmanager 负责告警分组、路由、重复通知和恢复通知;
  • prometheus-webhook-dingtalk 负责把 Alertmanager 的 Webhook 消息转换为钉钉能够接收的请求;
  • 钉钉机器人负责把消息送进指定群聊。

我更愿意先把这四层分开理解,因为出了问题以后,排查顺序会清楚很多:是 Prometheus 没触发、Alertmanager 没收到、Webhook 服务没转发,还是钉钉机器人拒绝了消息。

2. 部署前先确认基础条件

当前流程要求:

  1. 本机已经部署 Prometheus 和 Alertmanager;
  2. 有一个可用的钉钉群,并具备管理员权限;
  3. 可以创建钉钉自定义机器人;
  4. Webhook 部署节点具备外网访问能力;
  5. Alertmanager 与 prometheus-webhook-dingtalk 网络互通;
  6. 准备 Docker 或 systemd,以及 curl、jq、vim / nano 等调试和编辑工具。

如果 Alertmanager 和 Webhook 服务在同一主机,还要留意 Docker 网络隔离。当前说明建议不要直接假定 127.0.0.1 一定可用,而是根据部署方式选择宿主机 IP 或 Docker 自定义网络。

先确认 Docker:

shell 复制代码
docker --version

3. 让 Prometheus 知道 Alertmanager 在哪里

进入 Prometheus 配置文件,按当前页面配置 Alertmanager。

修改后执行:

shell 复制代码
systemctl restart prometheus

这一步的目标很明确:Prometheus 触发告警以后,要能把告警送到 Alertmanager。

后面的钉钉配置都建立在这条链已经可用的基础上。

4. 创建钉钉自定义机器人

打开钉钉群,进入右上角设置。

找到智能群助手并添加机器人。

选择自定义机器人。

点击添加。

当前示例给机器人的名称是:

prometheus告警

接下来设置机器人安全策略。

当前操作使用了关键词,同时页面也提供加签或 IP 地址等安全方式。

完成以后复制生成的 Webhook URL。

这个地址后面要写进 prometheus-webhook-dingtalk 配置,因此不要把它当作普通公开链接传播。

5. 部署 prometheus-webhook-dingtalk

先创建:

dingtalk.yaml

当前单群配置如下:

shell 复制代码
cat > dingtalk.yaml <<EOF
targets:
  webhook1:
    url: https://oapi.dingtalk.com/robot/send?access_token=你的_access_token
EOF

这里的 webhook1 是后面 Alertmanager URL 中会使用到的目标名称。

然后启动 Docker 容器:

shell 复制代码
docker run -d \

  --name dingtalk-webhook \

  -p 8060:8060 \

  -v $(pwd)/dingtalk.yaml:/etc/prometheus-webhook-dingtalk/config.yml \

  --restart always \

  timonwong/prometheus-webhook-dingtalk:latest

当前服务监听:

8060

端口。

到这里,链路中间多了一层:

Alertmanager → 8060 → prometheus-webhook-dingtalk → 钉钉 Webhook

6. 配置 Alertmanager,把告警交给钉钉中转服务

打开 Alertmanager 配置:

shell 复制代码
vi alertmanager.yml

当前配置如下:

shell 复制代码
global:
  resolve_timeout: 2m

route:
  group_by: ['alertname']
  group_wait: 10s
  group_interval: 10s
  repeat_interval: 1h
  receiver: 'dingtalk-webhook'

receivers:
- name: 'dingtalk-webhook'
  webhook_configs:
  - url: 'http://<你的服务器IP> :8060/dingtalk/webhook1/send'
    send_resolved: true

这里几个参数值得单独看:

  • group_by: ['alertname']
  • group_wait: 10s
  • group_interval: 10s
  • repeat_interval: 1h
  • receiver:dingtalk-webhook
  • send_resolved: true

其中 send_resolved: true 表示恢复状态也会继续通过当前通知链发送。

配置完成后执行:

shell 复制代码
systemctl restart alertmanager

当前 URL 代码块中写的是:

http://<你的服务器IP> :8060/dingtalk/webhook1/send

其中 <你的服务器IP> 需要换成实际运行 Webhook 服务的主机地址;当前记录里 IP 与 :8060 之间还保留了一个空格,复现时要结合自己的实际配置确认请求地址。

随后已经能看到钉钉告警。

这一步真正验证的是:

Prometheus → Alertmanager → prometheus-webhook-dingtalk → 单个钉钉群

已经连通。

7. 多个钉钉群怎么处理?

如果运维、开发或安全团队需要分别接收告警,可以继续配置多个钉钉目标。

先编辑:

shell 复制代码
vi dingtalk.yaml

当前多目标结构如下。

这里的 Webhook token 和 secret 属于敏感凭据,改写文件中只保留配置结构,具体值使用占位符。

shell 复制代码
targets:
  ops-team:
    url: https://oapi.dingtalk.com/robot/send?access_token=<your_access_token>
    secret: <your_secret>
  dev-team:
    url: https://oapi.dingtalk.com/robot/send?access_token=<your_access_token>
    secret: <your_secret>

然后重新启动 Webhook 容器:

shell 复制代码
docker run -d \
  --name dingtalk-webhook \
  -p 8060:8060 \
  -v $(pwd)/dingtalk.yaml:/etc/prometheus-webhook-dingtalk/config.yml \
  --restart always \
  timonwong/prometheus-webhook-dingtalk:latest

接着编辑 Alertmanager:

shell 复制代码
vi alertmanager.yml

当前配置通过一个 broadcast receiver 同时写入两个 Webhook 地址:

shell 复制代码
global:
  resolve_timeout: 2m

# 主路由:所有告警走这个路径
route:
  group_by: ['alertname']
  group_wait: 10s
  group_interval: 10s
  repeat_interval: 1h
  receiver: 'broadcast'   # ← 指向一个组合 receiver

# 定义 receivers
receivers:
- name: 'broadcast'
  webhook_configs:
    # 发给 ops 钉钉群
    - url: 'http://<你的服务器IP>/dingtalk/ops-team/send'
      send_resolved: true
    # 发给 dev 钉钉群
    - url: 'http://<你的服务器IP>/dingtalk/dev-team/send'
      send_resolved: true

这里要留意一个现有配置差异:Webhooks 服务前面映射的是 8060:8060,但这两个多群 URL 当前没有写 :8060。这里保持现有配置不改,复现时需要根据自己的网络和监听方式确认实际可达地址。

配置后执行:

shell 复制代码
 systemctl restart alertmanager

等待告警触发后,当前测试里两个群都收到了消息。

这一步验证的是同一份 Alertmanager 告警可以同时送到两个钉钉目标。

8. Prometheus 和 Alertmanager 不在一个局域网怎么办?

前面的链路默认各组件之间能够直接访问。

但如果 Prometheus 在一个内网,Alertmanager 在另一台隔离主机或另一个网络,Prometheus 就可能无法直接连接 Alertmanager 的 9093。

这时需要解决的不是钉钉机器人,而是:

Prometheus → Alertmanager

这一段网络链路。

这里使用 cpolar 的作用很明确:

把 Alertmanager 的 9093 TCP 服务提供成另一侧 Prometheus 可以到达的公网入口。

它不参与告警分组,也不负责向钉钉发送消息。

9. 安装 cpolar

执行:

shell 复制代码
sudo curl https://get.cpolar.sh | sh

安装完成后检查服务状态:

shell 复制代码
sudo systemctl status cpolar

服务正常以后,通过主机 IP + 9200 进入 cpolar Web 管理页面。

当前页面同时出现:

http://ip:9200

和链接目标:

http://localhost:9200/

实际使用时,以当前环境真正可以打开的地址为准。

10. 先为 Alertmanager 创建随机 TCP 入口

创建隧道时,当前设置为:

  • 隧道名称:alertmanager
  • 协议:tcp
  • 本地地址:9093
  • 端口类型:随机临时 TCP 端口
  • 地区:China Top

创建完成以后,当前生成的公网地址是:

  • 域名:2.tcp.cpolar.top
  • 端口:10409

因此远端 Prometheus 需要连接的是:

2.tcp.cpolar.top:10409

11. 把远端 Prometheus 指向这个公网 Alertmanager 地址

在 Prometheus 主机上编辑:

shell 复制代码
vi prometheus.yml

当前配置为:

shell 复制代码
alerting:
  alertmanagers:
    - static_configs:
        - targets: ["2.tcp.cpolar.top:10409"]

也就是说,Prometheus 的 Alertmanager 目标从原来的局域网地址换成:

2.tcp.cpolar.top:10409

当前操作记录在修改 prometheus.yml 后执行的是:

shell 复制代码
systemctl restart alertmanager

这里保持当前步骤不变。实际复现时,应根据自己的服务管理方式确认新配置是否已经被对应进程加载。

当前测试中,重启之后钉钉仍然继续收到告警。

这说明在当前环境里:

Prometheus → cpolar TCP → Alertmanager 9093 → Webhook → 钉钉

这条跨网络链路能够继续工作。

12. 长期使用再保留固定 TCP 地址

随机 TCP 适合先验证,但如果 Prometheus 配置文件长期指向这个目标,固定地址会更方便。

进入 TCP 地址预留页面。

当前页面存在一个地区显示差异:

  • 下拉菜单选择:China VIP

  • 已保留记录显示:China Top

  • 固定地址:3.tcp.cpolar.top:11755

然后回到 cpolar 隧道列表。

当前文字说明里写的是找到:

ssh

隧道,但前面实际创建的隧道名称是:

alertmanager

复现时应以列表中实际指向 9093 的那条隧道为准。

把端口类型改成固定 TCP,并填写已经保留的 TCP 地址。

更新以后,在线隧道列表会显示固定 TCP 地址。

到这里,Alertmanager 的公网入口就不再依赖随机 TCP 端口。

总结

这套配置最值得保留的,不是"Prometheus 告警终于能发钉钉"这一句话,而是把整条链拆开以后,每一段都能独立验证。

实际跑通的核心路径是:

Prometheus → Alertmanager → prometheus-webhook-dingtalk:8060 → 钉钉机器人 → 单群告警 → 双群告警 → cpolar → Alertmanager 9093 → 2.tcp.cpolar.top:10409 → 固定 TCP 3.tcp.cpolar.top:11755。

如果以后告警没有到钉钉,我会按这个顺序查:先看 Prometheus 有没有触发,再看 Alertmanager 有没有收到,再看 Webhook 服务是否可达,最后才看钉钉机器人安全策略。跨网络场景再额外检查 9093 公网入口。这样比把"告警系统有问题"当成一个整体去猜,要省事得多。

相关推荐
cpolar技术支持2 天前
外网测试机的异常传不回内网?自托管 Sentry,用 cpolar 打通错误上报链路
python·nginx·docker·cpolar·sentry
cpolar技术支持2 天前
Spring Boot 接口本地正常,异地前端却报跨域?用 cpolar 跑通 CORS 预检与白名单
java·springboot·cpolar·前后端分离·cors
cpolar技术支持5 天前
本地数据库客户端只能自己用?用 cpolar 安全访问 NAS 上的 PostgreSQL 管理台
postgresql·内网穿透·cpolar·nas·pgadmin
adminwolf6 天前
钉钉群消息自动转发怎么搞?
钉钉
cpolar技术支持10 天前
服务器上的 Nginx 只想改配置却不敢动?把 Nginx-UI 跑起来,用 MCP 让 AI 助手帮你安全改配置,再用 cpolar 把面板短时开给自己
nginx·ai·cpolar·mcp·nginx-ui
cpolar技术支持18 天前
本地 Playwright 测试报告怎么远程复盘?Trace Viewer 跑起来后,用 cpolar 分享失败现场
前端·自动化测试·测试工具·cpolar·playwright
池央19 天前
通勤听书不想来回切 App?用 Audiobookshelf 搭一个自己的有声书库
智能手机·cpolar
禁默19 天前
没有公网 IP 怎么远程抓取服务器指标?node_exporter + Prometheus + cpolar 实战
人工智能·cpolar
cpolar技术支持21 天前
本地登录正常,公网却掉线?Express Session 经 cpolar HTTPS 访问的 Cookie 排障实战
node.js·express·cpolar·cookie·session