最近在折腾项目的时候碰到了这个知识点,查了不少资料,索性整理出来分享给大家。
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 消息转换为钉钉可以接收的请求;- 钉钉机器人负责把消息送进指定群聊。
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:
docker --version
3. 让 Prometheus 了解 Alertmanager 在哪里
进入 Prometheus 配置文件,按当前页面配置 Alertmanager。
修改后执行:
systemctl restart prometheus
这一步的目标很明确:Prometheus 触发告警以后,要能把告警送到 Alertmanager。
后面的钉钉配置都建立在这条链已经可用的基础上。
4. 创建钉钉自定义机器人
打开钉钉群,进入右上角设置。
找到智能群助手并添加机器人。
选择自定义机器人。
点击添加。
当前示例给机器人的名称是:
prometheus告警
接下来设置机器人安全策略。
当前操作用了关键词,同时页面也给出加签或 IP 地址等安全方法。
做好以后复制生成的 Webhook URL。
这个地址后面要写进 prometheus-webhook-dingtalk 配置,于是不要把它当作普通公开链接传播。
5. 部署 prometheus-webhook-dingtalk
先创建:
dingtalk.yaml
当前单群配置如下:
cat > dingtalk.yaml 这里的 Webhook token 和 secret 属于敏感凭据,改写文件中只保留配置结构,具体值使用占位符。
targets:
ops-team:
url: https://oapi.dingtalk.com/robot/send?access_token=
secret:
dev-team:
url: https://oapi.dingtalk.com/robot/send?access_token=
secret:
然后重新启动 Webhook 容器:
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:
vi alertmanager.yml
当前配置通过一个 `broadcast` receiver 同时写入两个 Webhook 地址:
global:
resolve_timeout: 2m
主路由:所有告警走这个路径
route: group_by: ['alertname'] group_wait: 10s group_interval: 10s repeat_interval: 1h receiver: 'broadcast' # ← 指向一个组合 receiver定义 receivers
receivers:- name: 'broadcast'

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

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

这一步验证的是**同一份 Alertmanager 告警可以同时送到两个钉钉目标**。
### 8. Prometheus 和 Alertmanager 不在一个局域网怎么办?
前面的链路默认各组件之间能够直接访问。
但如果 Prometheus 在一个内网,Alertmanager 在另一台隔离主机或另一个网络,Prometheus 就可能无法直接连接 Alertmanager 的 `9093`。
这时需要解决的不是钉钉机器人,而是:
**Prometheus → Alertmanager**
这一段网络链路。
这里使用 cpolar 的作用很明确:
> 把 Alertmanager 的 9093 TCP 服务提供成另一侧 Prometheus 可以到达的公网入口。
它不参与告警分组,也不负责向钉钉发送消息。
### 9. 安装 cpolar
执行:
sudo curl https://get.cpolar.sh | sh

安装完成后检查服务状态:
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 主机上编辑:
vi prometheus.yml
当前配置为:
alerting:
alertmanagers:
- static_configs:
- targets: ["2.tcp.cpolar.top:10409"]

也就是说,Prometheus 的 Alertmanager 目标从原来的局域网地址换成:
`2.tcp.cpolar.top:10409`
当前操作记录在修改 `prometheus.yml` 后执行的是:
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 公网入口。这样比把“告警系统有问题”当成一个整体去猜,要省事得多。
本次分享就到这里。技术这东西越研究越有意思,后续有新的收获我也会继续更新。
评论 (0)
暂无评论