Prometheus + Grafana 跑了快一年,机器层面的问题基本都能及时发现。但上个月出了件事:AdGuard Home 的进程不知为何退出了,那个 LXC 本身好好的,CPU、内存、磁盘一切正常,Grafana 上一片祥和——可全家都上不了网。我是被家里人问“网怎么又断了”才知道的。
这件事让我意识到,“机器活着”和“服务能用”是两回事。前者归指标监控管,后者需要有个东西站在用户的角度,定期去访问一下。Uptime Kuma 就是干这个的:一个带网页界面的可用性监控工具,支持 HTTP、TCP 端口、DNS、Ping、Docker 容器等多种检查方式,配置全在网页上点,还能做状态页。
部署
监控程序不能和被监控的东西放在一起,否则 Docker 虚拟机一挂,监控也跟着挂,谁也不报警。所以我把它放在了跑 Jellyfin 的那台 N100 小主机上(192.168.10.30),它和笔记本上的 Proxmox 是两台独立的物理机。
# /srv/compose/uptime-kuma/compose.yaml
services:
uptime-kuma:
image: louislam/uptime-kuma:2 # 固定大版本,小版本随 pull 更新
restart: unless-stopped
volumes:
- ./data:/app/data
# 想监控本机容器的运行状态才需要这一行,见下文
- /var/run/docker.sock:/var/run/docker.sock:ro
ports:
- "3001:3001"
environment:
TZ: Asia/Shanghai
镜像只固定到大版本 2,平时 docker compose pull 就能拿到 2.x 里的最新小版本,跨大版本升级时再手动改。docker compose up -d 之后打开 http://192.168.10.30:3001,第一次进去会先让你选数据库类型、再创建管理员账号,家用选内置的 SQLite 就够了。
我加的监控项
| 类型 | 目标 | 说明 |
|---|---|---|
| DNS | 用 192.168.10.53 解析 nas.home.example.com | AdGuard Home 能不能正常解析 |
| HTTP(s) | http://192.168.10.21:2283 | Immich 网页 |
| HTTP(s) - 关键字 | http://192.168.10.30:8096/health | Jellyfin,响应里要有 Healthy |
| HTTP(s) | http://192.168.10.21:3000 | Grafana |
| TCP 端口 | 192.168.10.20:3493 | NAS 上的 NUT 服务 |
| Ping | 192.168.10.5 | Proxmox 宿主机 |
| Push | 备份脚本主动上报 | 下文细说 |
DNS 监控是这次的重点:解析服务器填 192.168.10.53,记录类型选 A,查的是在 AdGuard Home 里配过 DNS 重写的内网域名,这样既不依赖外网,结果也是确定的。Home Assistant(部署过程见这篇)也加了一个 HTTP 检查,看 8123 端口的网页能不能打开。
每个监控项的检查间隔设为 60 秒,重试次数 3 次。重试很重要,不然容器升级重启的那几十秒也会触发一次告警,狼来了几次之后,就没人再看告警了。
通知方式选 ntfy,填上家里 ntfy 服务的地址和主题,勾上“默认开启”和“应用到所有现有监控项”,以后新加的监控也会自动带上。
用 Push 监控定时任务
最有用的其实是 Push 类型。前面几种都是 Uptime Kuma 主动去检查别人,Push 反过来:Uptime Kuma 给你一个专属地址,被监控的一方定期来访问它,超过设定时间没来,就判定为故障。
这正好解决了 restic 备份那篇结尾留下的问题:备份失败了没人知道。这个备份脚本后来按 systemd timer 那篇改成了由 timer 定时触发,我在脚本末尾加了一行:
# /usr/local/bin/restic-backup.sh 的最后
# 脚本开头有 set -euo pipefail,前面任何一步失败都走不到这里
curl -fsS -m 10 --retry 3 \
"http://192.168.10.30:3001/api/push/替换成你的Token?status=up&msg=OK&ping=" \
> /dev/null
Push 监控的心跳间隔设成 25 小时:备份每天跑一次,多留一个小时的余量,超过 25 小时没收到上报就告警。不管是脚本报错、timer 没触发,还是整台机器没开机,都能发现。
踩过的坑
1. 谁来监控监控者? Uptime Kuma 自己挂了怎么办?它自带一个 Prometheus 格式的 /metrics 接口,在设置里生成 API Key 之后,让 Prometheus 带上认证去抓取,再在 Grafana 里配一条抓取失败的告警。两套系统互相盯着,同时挂掉的概率就很低了。
2. 数据目录别放在 NFS 上。 我一开始图省事,把 data 放在了 NAS 挂过来的目录里,用了几天就开始报数据库被锁。官方文档写得很清楚,不支持把数据放在 NFS 这类网络文件系统上,挪回本地磁盘就好了。
3. docker.sock 的风险。 要监控本机容器的运行状态,得把 Docker 的 socket 挂进去。注意后面那个 :ro 只是让挂载点只读,并不能限制通过 socket 调用 API,拿到 socket 基本就等于拿到了宿主机的 root。我权衡之后只在这台机器上这么做了,其他机器上的服务都用 HTTP 或端口检查代替。
4. 维护时的告警轰炸。 有一次给 Proxmox 升级重启,一口气收到十几条告警。后来学会了用“维护”功能:提前建一个维护窗口,期间相关的监控项暂停告警,状态页上也会显示正在维护。
5. DNS 检查别太频繁。 我一度把 DNS 检查调到了每 10 秒一次,AdGuard Home 的查询日志里全是 Uptime Kuma 的请求,翻起来很不方便。改回 60 秒,再在 AdGuard Home 的查询日志设置里把这个检查用的域名加进忽略列表,清净多了。
小结
Uptime Kuma 和 Prometheus 并不冲突:一个回答“服务能不能用”,一个回答“机器状态怎么样”。加上 Push 监控之后,家里的定时任务也有了兜底。我还给家里人做了一个简单的状态页,下次再“断网”,他们可以先看一眼是哪个服务出了问题——当然,最好是我先收到通知。