06 Uptime Kuma 服务状态监控
定位:CloudLab 的"服务可用性监控 + 对外状态页",面试官能直接看到服务实时运行状态
服务器:华为云 Flexus · 目录/opt/cloudlab/uptime-kuma
日期:2026-10-19
一、项目介绍
Uptime Kuma 是一个开源的服务可用性监控工具:定时探测目标(网站/端口/主机),判断是否在线,记录响应时间和可用率,挂了可触发告警,并能生成对外公开的只读状态页。
- 技术栈:Docker、Node.js、Uptime Kuma、HTTP/HTTPS 探测、WebSocket
- 运行环境:Docker 容器,端口 3001
- 规划域名:
status.cloud321.cloud - 与"主机资源监控"的分工:Kuma 管服务/网站是否可用(黑盒探测);Grafana 管主机 CPU/内存等指标(白盒指标,见后续 08)。
部署架构
flowchart TD
V[访客/面试官] --> NPM[NPM 反向代理网关]
NPM -->|status.cloud321.cloud<br/>80/443| Kuma[Uptime Kuma 容器:3001]
Kuma -->|每60秒 HTTP探测| Vault[Vaultwarden<br/>vault.cloud321.cloud]
Kuma -->|每60秒 HTTP探测| Baidu[百度<br/>www.baidu.com]
Kuma --> Data[("./data 持久化<br/>监控配置与历史")]
监控原理
flowchart LR
A[按心跳间隔<br/>60s] --> B[向目标发请求]
B --> C{预期状态码?<br/>如200}
C -->|是| D[Up 绿色<br/>记录响应时间]
C -->否/超时| E[按重试次数复测]
E --> F[仍失败 → Down 红色<br/>可触发告警]
二、要做什么(功能清单)
- Docker 部署 Uptime Kuma 容器,数据持久化
- 创建管理员账号
- 添加监控项(Vaultwarden + 百度外部对照)
- 创建对外公开状态页
- 在 NPM 配置子域名反代 + HTTPS
三、可能遇到的问题(部署前预告)
- 镜像标签过时:
:1/:latest停留在不再维护的 v1 - 新监控显示 N/A:容易误以为是"没放行"
- 81 端口:NPM 管理后台,不开放则无法配置反代
- HTTPS 证书 HTTP 验证失败:验证路径被转发给后端
- 域名 80/443 最终被"未备案"阻断
四、实际部署经历
1. 编写编排文件、启动容器
mkdir -p /opt/cloudlab/uptime-kuma && cd /opt/cloudlab/uptime-kuma
cat > docker-compose.yml << 'EOF'
services:
uptime-kuma:
image: louislam/uptime-kuma:1
container_name: uptime-kuma
restart: unless-stopped
ports:
- '3001:3001'
volumes:
- ./data:/app/data
EOF
docker-compose up -d
- 容器内默认端口 3001,映射宿主机 3001;
- 挂载
./data:/app/data,配置和历史数据落盘; - 放行端口:
iptables -I INPUT -p tcp --dport 3001 -j ACCEPT && service iptables save,并在华为云安全组入方向添加 3001。
2. 踩坑:镜像标签过时 → 升级到 v2
- 现象:页面提示
This Uptime Kuma version is outdated! Current Version: 1.23.17 (Outdated!),:1标签指向 v1,已停止维护; - 查证:Uptime Kuma 发布 v2,官方推荐标签
:2; - 解决:
sed -i 's|louislam/uptime-kuma:1|louislam/uptime-kuma:2|' docker-compose.yml
docker-compose up -d
标签知识:
| 标签 | 含义 |
|---|---|
| :1 / :latest | 均指向 v1(1.23.17),已弃用 |
| :2 | v2 最新稳定版,自动更新,推荐 |
| :2.x.x | 锁定具体版本,便于变更控制 |
| :2-slim | 精简版(无内置数据库,适合外接 DB) |
经验:网上教程标签可能过时,要对照官方 Wiki(Docker Tags)。
3. 初始化管理员账号
- 先访问
http://公网IP:3001创建管理员账号,先验证服务本身、再配反代; - 这样把"应用可用"和"反代配置"分开,出问题能快速定位;
- Kuma 账号是它自己的,与 Vaultwarden 无关。
4. 添加监控项(核心)
Uptime Kuma 支持的监控类型:
| 类型 | 监控什么 |
|---|---|
| HTTP(s) | 定时请求网址,看状态码(最常用) |
| TCP Port | IP:端口是否连通 |
| Ping | 主机能否 ping 通 |
| Keyword | 请求页面并检查关键词 |
| DNS | 域名解析是否正常 |
| Docker | 容器运行状态 |
| 其他 | gRPC、Redis、MySQL、Mqtt 等 |
① Vaultwarden(被监控的自有服务)
- 类型 HTTP(s)、URL https://vault.cloud321.cloud、心跳间隔 60s、重试 1;
- 结果:100% Up、200 OK;
- 响应时间:首个点 230ms(首次 DNS+TCP+TLS 握手),后续稳定 20~30ms(Kuma 复用连接,只发请求)——属于正常现象。
② 百度(外部对照)
- 类型 HTTP(s)、URL https://www.baidu.com;
- 初次显示 N/A、心跳全白,一度以为是"没放行";
- 澄清(出站 vs 入站):
- "放行端口"控制的是外部能否访问你(入站);
- Kuma 主动连百度是出站,云服务器出方向默认允许,容器经 Docker NAT 共享宿主机 IP 上网,无需放行;
- N/A 只是尚未完成第一个心跳周期,等待约 60s 后变绿;
- 最终结果:100% Up,当前 30ms,平均 36.5ms,证书有效期 97 天。
外部对照的作用:所有自有服务都红、但百度绿 → 是你服务器问题;连百度都红 → 可能断网或 Kuma 本身故障。
5. 创建公开状态页
- 仪表盘(Dashboard):带增删改的管理后台,不对外;
- 状态页(Status Page):只读,专门对外发布;
- 操作:右上角"状态页面" → 新建状态页:
- 标题
CloudLab 服务状态 - Slug
cloudlab(决定网址.../status/cloudlab) - 勾选展示 Vaultwarden、百度
- "编辑状态页/前往仪表盘"按钮只有登录管理员可见,访客看到的是只读页。
6. NPM 反代 + HTTPS
- 在状态页编辑里设置 Custom Domain =
status.cloud321.cloud(让 Kuma 知道该域名对应哪个状态页); - 81 端口:NPM 管理后台,关闭后无法登录配置,需在安全组/iptables 临时放行,配完可关;
- 第一次 HTTP 验证失败:
- 现象:certbot 报
Invalid response ... /.well-known/acme-challenge/...: 403; - 根因:现有 Proxy Host 把验证路径也转发给 Kuma,Kuma 作为 SPA 对未知路径返回 HTML,Let's Encrypt 拿不到验证文件;
- 验证:
curl -I http://status.cloud321.cloud/.well-known/acme-challenge/test123返回 Kuma 页面(200/1200字节),证实路径被转发; - 改用 DNS 验证(成功):
- 建 RAM 子用户
dns-certbot(仅 OpenAPI 访问),授权AliyunDNSFullAccess,取 AccessKey ID/Secret; - NPM 编辑 SSL 时选"申请新证书" → 勾选 Use a DNS Challenge → Provider 选 Aliyun → 填凭证;
- 不依赖 80 端口,证书申请成功(还可申请通配符
*.cloud321.cloud)。
7. 最终:备案阻断(当前状态)
- 证书成功后,域名 80/443 仍打不开,排查定位到未 ICP 备案被合规阻断(详见 07 网站ICP备案);
- 服务器内部一切正常,当前对外演示用
http://公网IP:3001; - 备案通过后,
https://status.cloud321.cloud即可正常访问。
五、Kuma 使用补充
- 添加监控:选类型 → 填目标/心跳 → 保存,等一个心跳周期;
- 重试设置:失败后按 Retries 复测,避免网络抖动误报 Down;
- 通知(进阶):可在 Settings → Notifications 配置邮件/钉钉/企微/Telegram,挂了自动推送;
- 状态页自定义:可改主题、图标、描述、自定义 CSS;
- 关键监控建议:所有对外服务都用公开域名监控(端到端真实),自有服务 + 外部对照搭配。
六、踩坑记录与关键经验
| 问题 | 根因 | 解决 |
|---|---|---|
| 提示版本过时 | :1/:latest 停留在 v1 |
换 :2 标签 |
| 百度显示 N/A | 未到首个心跳周期;属出站非入站 | 等待即可,无需放行 |
| 证书 403 | acme-challenge 被转发给后端 | 改用 DNS 验证 |
| 域名最终打不开 | 未 ICP 备案 | 走备案(07) |
核心经验:
1. 监控要区分入站/出站,出站默认允许、不需要放行;
2. 首响时间包含 TLS 握手、后续复用连接,是正常变化;
3. 反向代理申请证书优先"创建即申请",已有转发规则会干扰 HTTP 验证;
4. 内部正常、外部不通要想到合规层。
七、项目不足与扩展
- 仅做黑盒可用性探测,不含主机资源指标(交给后续 Grafana,08);
- 尚未配置通知渠道,告警可扩展邮件/钉钉;
- 状态页默认样式,可进一步美化;
- 对外正式访问依赖 ICP 备案(07)。
评论