1317 字
7 分钟
PVE + 群晖联动非标HID UPS安全关机全流程配置

本指南适用于将山寨/公模 USB-HID 芯片(VID: 0001, PID: 0000)的 UPS 接入 Proxmox VE(PVE 8+)作为 NUT Server,并由群晖 Synology DSM 作为 NUT Client 进行网络联动。

时序策略:市电中断 30 秒群晖先行进入安全模式;中断 60 秒(或电量低于 30%)PVE 优雅关闭所有虚拟机并下电宿主机。


阶段一:PVE 宿主机安装与基础权限配置#

1. 安装 NUT 软件包#

在 PVE 终端执行:

Terminal window
apt-get update
apt-get install -y nut nut-client nut-server

2. 配置 udev 规则(解决底层权限)#

由于该设备 ID(0001:0000)属于非标公模,系统默认不会授予非特权组访问权。需手动创建 udev 规则:

Terminal window
cat << 'EOF' > /etc/udev/rules.d/99-nut-ups.rules
SUBSYSTEM=="usb", ATTR{idVendor}=="0001", ATTR{idProduct}=="0000", MODE="0666", GROUP="nut"
SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0001", ATTRS{idProduct}=="0000", MODE="0666", GROUP="nut"
EOF

重载并生效规则(建议随后重新拔插一次 UPS 的 USB 数据线):

Terminal window
udevadm control --reload-rules
udevadm trigger

阶段二:PVE 宿主机 NUT Server 核心配置#

NUT 配置文件均存放在 /etc/nut/ 目录下。

1. /etc/nut/nut.conf(工作模式)#

配置为网络服务端模式:

MODE=netserver

2. /etc/nut/ups.conf(驱动与协议核心)#

该公模芯片实为 Q1 变种协议套壳,必须使用 nutdrv_qx 驱动并配合 protocol = "hunnox",否则会出现状态卡死在 OB 或电压不刷新的问题:

pollinterval = 2
maxretry = 3
[ups]
driver = "nutdrv_qx"
port = "auto"
vendorid = "0001"
productid = "0000"
protocol = "hunnox"
langid_fix = "0x0409"
novendor
desc = "Home UPS"
override.battery.charge.low = 30

3. /etc/nut/upsd.conf(网络监听端口)#

监听本地及所有局域网接口的 3493 端口:

LISTEN 0.0.0.0 3493

4. /etc/nut/upsd.users(账户隔离体系)#

群晖系统写死了 NUT 账户为 monuser / secret;PVE 本地使用独立的 pve_mon 账户作为 Master:

# PVE 本地监控 Master
[pve_mon]
password = YourPveLocalSecret
upsmon master
# 群晖 DSM 专用 Slave 账户
[monuser]
password = secret
upsmon slave

阶段三:PVE 本地监控、定时关机与日志脚本#

1. /etc/nut/upsmon.conf(本地监控守护)#

MONITOR ups@localhost 1 pve_mon YourPveLocalSecret master
MINSUPPLIES 1
SHUTDOWNCMD "/sbin/shutdown -h now"
POLLFREQ 2
POLLFREQALERT 1
HOSTSYNC 15
DEADTIME 15
NOTIFYCMD /usr/sbin/upssched
NOTIFYFLAG ONBATT SYSLOG+WALL+EXEC
NOTIFYFLAG ONLINE SYSLOG+WALL+EXEC
NOTIFYFLAG LOWBATT SYSLOG+WALL+EXEC

2. /etc/nut/upssched.conf(60秒关机调度器)#

使用标准的 EXECUTE 语法触发日志,并启动 60 秒倒计时:

CMDSCRIPT /etc/nut/upssched-cmd
PIPEFN /var/run/nut/upssched.pipe
LOCKFN /var/run/nut/upssched.lock
# 停电瞬间:执行日志命令,同时启动 60 秒计时器
AT ONBATT * EXECUTE start-countdown
AT ONBATT * START-TIMER early-shutdown 60
# 来电瞬间:取消 60 秒计时,并记录日志
AT ONLINE * CANCEL-TIMER early-shutdown
AT ONLINE * EXECUTE cancel-countdown
# 紧急电量保护:低于 30% 立即触发下电
AT LOWBATT * EXECUTE forced-shutdown

3. /etc/nut/upssched-cmd(下电执行脚本)#

cat << 'EOF' > /etc/nut/upssched-cmd
#!/bin/sh
LOGFILE="/var/log/upssched.log"
case $1 in
start-countdown)
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [UPS 停电] 60秒关机倒计时已启动!" >> "$LOGFILE"
logger -t upssched-cmd "[UPS 停电] 60秒关机倒计时已启动!"
;;
cancel-countdown)
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [UPS 来电] 市电恢复,关机倒计时已取消。" >> "$LOGFILE"
logger -t upssched-cmd "[UPS 来电] 市电恢复,关机倒计时已取消。"
;;
early-shutdown)
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [UPS 关机] 停电满60秒,发起 PVE 宿主机优雅关机..." >> "$LOGFILE"
logger -t upssched-cmd "[UPS 关机] 停电满60秒,发起 PVE 宿主机优雅关机..."
/sbin/shutdown -h now
;;
forced-shutdown)
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [UPS 紧急] 电池低于 30%,立即强制关机!" >> "$LOGFILE"
logger -t upssched-cmd "[UPS 紧急] 电池低于 30%,立即强制关机!"
/sbin/shutdown -h now
;;
*)
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 未知事件: $1" >> "$LOGFILE"
;;
esac
EOF
chmod +x /etc/nut/upssched-cmd
touch /var/log/upssched.log
chmod 666 /var/log/upssched.log

4. 优化宿主机 Systemd 关机等待(防止虚拟机拖死电池)#

Terminal window
sed -i 's/#DefaultTimeoutStopSec=90s/DefaultTimeoutStopSec=35s/' /etc/systemd/system.conf
sed -i 's/DefaultTimeoutStopSec=60s/DefaultTimeoutStopSec=35s/' /etc/systemd/system.conf
systemctl daemon-reload

5. 启动 PVE 端服务并自检#

Terminal window
systemctl restart nut-server
systemctl restart nut-client
systemctl enable nut-server nut-client

执行状态验证:

Terminal window
upsc ups@localhost

正常输出标志:

  • ups.status: OL(插市电时)
  • battery.charge: 100(或当前电量)
  • input.voltage: 22x.x

阶段四:群晖 DSM 客户端配置(30秒休眠)#

  1. 进入 DSM -> 控制面板 -> 硬件和电源 -> 不断电系统 (UPS)。
  2. 勾选 启用 UPS 支持。
  3. UPS 类型:下拉选择 Synology 不断电系统服务器(底层即 NUT Client)。
  4. 网络不断电系统服务器 IP 地址:输入 PVE 宿主机内网 IP(例如 192.168.31.79)。
  5. DiskStation 进入待机模式之前的时间:选择 自定义时间,填入 30 秒。
  6. 启用网络 UPS 服务器:保持不勾选。
  7. 点击右下角 应用 保存。
  8. 点击 设备信息 确认状态:显示 已联机 且电池容量显示为真实百分比(如 100%)即代表连接完全成功。

阶段五:运行逻辑与验证流程#

场景时间/条件群晖 (NAS) 状态与动作PVE 宿主机及各虚拟机动作
市电中断T = 0 秒UPS 状态切为 OB,开始 30 秒计时感知断电,upssched 启动 60 秒关机倒计时并记录日志
瞬断恢复T < 30 秒恢复正常供电,重置计时收到 ONLINE 信号,立即取消倒计时
群晖休眠T = 30 秒进入待机安全模式,卸载所有硬盘卷(耗时约 10 秒)继续稳定供电运行,倒计时剩余 30 秒
PVE 下电T = 60 秒存储已处于卸载只读状态,无损断网触发关机,依序发送 ACPI 信号优雅关闭各 VM 并安全落盘下电
电量突降电量 < 30%同步感知断电保护立即触发紧急关机,不等待满 60 秒

日志验证命令:

  • PVE 查看倒计时与下电记录:tail -f /var/log/upssched.log
  • 监控服务即时日志:journalctl -u nut-client -f
PVE + 群晖联动非标HID UPS安全关机全流程配置
https://iiii.fun/posts/pve/pve-synology-nut-ups-shutdown/
作者
庆灵
发布于
2026-10-02
许可协议
CC BY-NC-SA 4.0