把威联通 NAS 接进 Prometheus 监控

本文最后更新于:2026年10月12日 上午

前言

终于等来了国庆长假!宅在家折腾自己的 HomeLab、 K8s、 NAS 服务器集群的感觉真爽!这次长假真的是折腾了好多东西,感兴趣的读者请期待后续的爆更,等不及的话也可以直接看我的 repo - east4ming/homelab2 的 PR 和 Commits。

homelab2 里有一台 QNAP NAS,跑了好几年,一直是块心病:它不在监控里。

集群里的 node、pod、中间件、URL 监控都齐了,偏偏这台 NAS 是个黑盒。它上面躺着我的照片、备份、电视、电影,盘什么时候开始报错、卷什么时候快满了,全靠我偶尔登 Web 控制台瞄一眼。典型的「防御式运维」,出事了才知道。

这件事放在待办清单里至少快 2 年了,趁国庆把这套补上。折腾完之后发现,坑比我想的多得多,尤其是那个 **「面板有曲线但数据是假的」** 的静默失效,说实话有点费劲。

先交代下对象:

项目 值
型号 QNAP TS-453Bmini(NAS33657A)
系统 QTS 5.2.10 / kernel 5.10.60-qnap / x86_64
内存 16GB
LAN 192.168.3.216
盘位 4 个内置 + 1 个 USB 外接盘
存储卷 5 个

最终效果图

先放几张最终效果图:

NAS Dashboard 1

NAS Dashboard 2

NAS Prometheus Alertrules

手机收到 NAS 告警

方案:Container Station 跑两个只读 exporter

NAS 上没法装 K8s agent,但 QNAP 有 Container Station(本质是个 docker)。所以思路很直接:

  1. NAS 侧跑两个 exporter,走 host 网络,让集群直接按 IP:Port 抓;
  2. 集群侧在 Prometheus 里加两个静态 job;
  3. 告警和面板都在集群侧统一管理。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# metal/nas/docker-compose.yml
services:
nas-node-exporter:
image: quay.io/prometheus/node-exporter:v1.8.2
container_name: nas-node-exporter
network_mode: host
restart: unless-stopped
pid: host
privileged: true
command:
- --path.rootfs=/host
- --collector.filesystem.mount-points-exclude=^/(dev|proc|sys|run|mnt/snapshot|share/NFSv=4)($|/)
volumes:
- /:/host:ro,rslave

nas-smartctl-exporter:
image: docker.io/prometheuscommunity/smartctl-exporter:v0.14.0
container_name: nas-smartctl-exporter
network_mode: host
restart: unless-stopped
privileged: true
user: "0:0"
command:
- --smartctl.device=/dev/sda;sat
- --smartctl.device=/dev/sdb;sat
- --smartctl.device=/dev/sdc;sat
- --smartctl.device=/dev/sdd;sat
- --smartctl.device=/dev/sde;sat

📝Notes: restart: unless-stopped 是必须的,NAS 断电重启后要能自动恢复采集,不然又是一次静默盲区。

实测开销:node-exporter 3101 条序列 / 19.89MiB,镜像 23.3MB;smartctl-exporter 496 条序列 / 6.449MiB,镜像 32.2MB。对 16GB 内存的 NAS 来说基本无感。

🐾 注意: 镜像源要挑。实测 quay.io/prometheus-community/smartctl-exporter 返回 unauthorized,docker.io/prometheuscommunity/smartctl-exporter 才是可用的。node-exporter 走 quay.io 没问题。

坑一:温度恒为 0 的静默失效 😱

这是最阴的一个。

第一版 compose 里,我偷懒没指定设备,让 exporter 自己扫:

1
2
3
4
5
smartctl --scan-open
# /dev/sda -d scsi
# /dev/sdb -d scsi
# /dev/sdc -d scsi
# /dev/sdd -d scsi

4 块 SATA 机械盘,全被识别成 SCSI。后果是什么?

  • smartctl_device_temperature 恒为 0;
  • ATA 属性(通电时间、重映射扇区、SMART 各项原始值)全部缺失;
  • 但 exporter 照常输出、Grafana 面板照常画曲线。😑

这就叫静默失效,比没数据危险得多。没数据你会去查,有数据你会信。要是哪天盘真过热了,我的告警规则永远触发不了。

修法:强制 SAT 类型。

1
--smartctl.device=/dev/sda;sat

📝Notes: <device>;<type> 这个语法要求镜像 ≥ v0.14.0。我先用 v0.12.0 试的,直接报 No such device,白折腾半小时。

改完之后温度才正常:sda 46°C、sdb 49°C、sdc 45°C、sdd 44°C、sde 44°C,5 块盘 smart_status 全为 1。

坑二:设备不可见 + 容器跑在 nobody

强制指定 /dev/sdX 之后,第二个坑立刻撞上来:/dev/sd* 在普通容器里根本不存在。

加上 privileged: true 才出现。但出现之后还打不开 —— 容器默认 UID 是 nobody,而 /dev/sda 的权限是 brw------- root:root。

所以这两行必须同时存在:

1
2
privileged: true
user: "0:0"

📝Notes: 这是我个人比较不喜欢的那种组合:privileged + root。但 SMART 读取本质上就是特权操作,绕不过去。缓解措施是容器只读挂载宿主 /,不挂 docker.sock,不监听公网,端口只开在 LAN IP 上。

坑三:挂载点噪声

node-exporter 挂宿主根目录,会带出一堆垃圾:

  • 25 个 /mnt/snapshot/<pool>/<snap> 快照视图
  • /share/NFSv=4/* 重导出
  • /share/CACHEDEV*_DATA/.qpkg/* QPKG 沙箱
  • 宿主自己的 /sys、/proc

不排除的话,容量面板能给你刷出几十行,全是假的。

排除之后 node_filesystem_size_bytes 恰好剩 10 个挂载点,其中真实存储卷 6 个:/share/CACHEDEV1..5_DATA 加上 /share/external/DEV3303_1。

1
2
- --collector.filesystem.mount-points-exclude=^/(dev|proc|sys|run|mnt/snapshot|share/NFSv=4)($|/)
- --collector.filesystem.fs-types-exclude=^(autofs|binfmt_misc|cgroup|configfs|debugfs|devpts|devtmpfs|fusectl|hugetlbfs|mqueue|nsfs|overlay|proc|procfs|pstore|rpc_pipefs|securityfs|selinuxfs|squashfs|sysfs|tracefs)$

盘位标签:为什么要硬编码

磁盘告警只说 /dev/sdc 没用,我要的是「bay1 那块盘」。盘位映射依据实测:

1
2
3
4
5
qcli_storage -d
# sdc → bay1
# sdd → bay2
# sda → bay3
# sdb → bay4

在 metric_relabel_configs 里逐条静态映射:

1
2
3
4
5
6
metric_relabel_configs:
- source_labels: [device]
regex: /dev/sdc
target_label: disk
replacement: bay1
# ... 其余三块同理

🤔 有同学会问:为什么不用 relabel_configs 的 labelmap 批量映射?

因为 separator 是全局参数,批量映射出来是 /dev/sdc;bay1 这种,拿不到干净的 disk=bay3。这种小场景,老老实实写四行反而最省事。

告警:两处「上线即永久误报」

6 条规则:卷容量两级阈值、卷被重挂只读、RAID 失去冗余、SMART 健康失败、磁盘高温。抓取中断直接复用既有的 TargetDown,不重复定义。

但写完跑 promtool check rules 通过,不代表规则能上线。用真实环境样本一评估,两条规则是永久误报:

误报一:/mnt/ext

它是 436MB 的固件 DOM(/dev/md13),实测可用只剩 7.69%。这是 QNAP 的固定布局,不可配置。卷容量规则必须限定排除掉固件 DOM:

1
2
3
expr: |
node_filesystem_avail_bytes{mountpoint=~"/share/.+"}
/ node_filesystem_size_bytes{mountpoint=~"/share/.+"} < 0.15

误报二:md9 / md13

这俩是 32 槽位的固件 DOM 镜像,实际只用 4 槽,所以 node_md_disks{state="active"} < node_md_disks_required 恒成立。RAID 规则必须硬编码范围,并且用 on (device) 做向量匹配:

1
2
3
expr: |
node_md_disks{state="active", device=~"md1|md2|md256|md322"}
< on (device) node_md_disks_required

修正后,6 条规则在当前环境全部 inactive(数据卷可用 29%–90%,SMART 全为 1,最高盘温 49°C)。

📝Notes: 这两条属于领域约束,不是 bug。你不能改 QNAP 的固件 DOM 设计,只能把范围限制硬编码进规则。写告警的时候,光看语法过没过是远远不够的,必须拿真实样本逐条评估。

GitOps 的边界:ArgoCD 管不了集群外的容器

集群侧所有资源(scrape config、rules、dashboard)全部走 ArgoCD,这个没争议。争议在 NAS 侧。

我逐条否决了几条路:

方案 否决原因
NAS 上装 k3s 当节点 4 盘位家用 NAS,为了跑两个 exporter 装个 K8s,杀鸡用牛刀
ArgoCD ConfigManagementPlugin 还是要落容器到 NAS,问题没解决
自建 webhook 控制器 维护成本远超收益
Entware 非容器安装 无版本锁定、无回滚、污染 QTS 系统

最终方案:compose 入库 + Container Station 人工导入。

好处是配置有版本、可追溯、可 review;代价是导入这一步得手动 —— 改了 compose,得去 Container Station 重建应用。

说实话这个代价我认了。ArgoCD 的管辖边界就是「集群内」,硬要把它伸到集群外的设备上,只会搞出一堆更脆的胶水。NAS 不是集群节点,也不该被塞进 metal/inventories/prod.yml。所以 NAS 的采集定义单独放 metal/nas/,各归各的。

没采到的指标,也交代一下

  • 机箱温度、风扇转速:QNAP 控制器不通过 hwmon 暴露,/sys/class/hwmon 下只有 CPU coretemp。所以温度监控只覆盖硬盘。
  • qcli_hdd:需要交互式 QCLI 登录,会引入管理员凭据,否决。
  • get_hd_smartinfo:实测无输出,依赖私有库,否决。
  • NAS 上不存在 smartctl 和 snmpd。

参考了两个仓库(zottelbeyer/QNAP-collectd-influxdb-grafana 走 collectd 推送 InfluxDB,sandrotosi/qnap-dashboards 依赖 SNMP),跟本仓库的 Prometheus 拉取模型都不兼容,只作指标维度参考,没采用。

运维要点

  1. 增删硬盘:要更新 compose 里的 --smartctl.device 列表并在 Container Station 重建应用。显式指定设备后,exporter 不再自动重扫。
  2. QTS 升级导致盘符变化:按 qcli_storage -d 复核盘位。
  3. NAS 换 IP:更新 values.yaml 里的两个静态目标。
  4. 硬盘休眠:SMART 读取可能把盘唤醒,介意的话要权衡采集频率。

总结

把 NAS 接进监控只是表面,真正让我长记性的是那些静默失效。

面板上有曲线、指标有输出,不等于数据是对的。SCSI 误判、UID 打不开设备、挂载点噪声、固件 DOM 的永久误报,每一个都不会报错,只会安安静静地骗你。

纸上得来终觉浅,绝知此事要躬行。规则语法过了、promtool 过了,都只是第一步;真正让规则可信的,是拿实测样本一条条去跑、去对、去证伪。

现在这套跑在 homelab2 上:13 个面板的 nas.json,6 条告警规则全 inactive,5 块盘温度 44–49°C,数据卷可用 29%–90%。终于不用再登 Web 控制台了。🎉

以上。

📚️参考文档


把威联通 NAS 接进 Prometheus 监控
https://ewhisper.cn/posts/10638/
作者
东风微鸣
发布于
2026年10月10日
许可协议