最近添置了一台主力机器,连接到 UPS 之后需要配置应急关机,正好记录一下。

结构

UPS 通过 USB 连接到 NAS 上,NAS 是 UNRAID 系统,电源插在 UPS 上。NAS 上安装了 Network UPS Tools (NUT) for UNRAID:UNRAID NUT app 并且启用 NUT 服务,配置好用户名和密码。 其他机器也将电源接入 UPS,并通过 NUT 协议通过网络连接到这台 UNRAID 机器上。 网络设备(光猫、路由器、交换机等)将电源接入 UPS,保证断电时有网络可用,便于发送告警通知。 当意外停电时,NAS 会通过 USB 首先收到通知,然后其他机器通过网络收到通知。使用 NUT 的机器会先触发关机,NAS 会在最后关机,关机后会关闭 UPS 电源供应。

本文仅描述 NUT 客户端侧的配置。

NUT 配置

以其中一台 PVE 宿主机为例。PVE 是基于 Debian 的 Linux 系统。

首先安装 NUT 软件:

1
apt update && apt install nut

UPS 服务不需要配置其他内容:

1
2
cat /etc/nut/ups.conf | grep -v '^#' | grep -v '^\s*$'
maxretry = 3

将 NUT UPS 配置为客户端模式:

1
2
cat /etc/nut/nut.conf | grep -v '^#' | grep -v '^\s*$'
MODE=netclient

可以启动监控服务了:

1
systemctl enable --now nut-monitor.service

配置 UPS 监控:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
cat /etc/nut/upsmon.conf  | grep -v '^#'|grep -v '^\s*$'
RUN_AS_USER root
MONITOR UPSNAME@NUT_SERVER_IP 1 USERNAME PASSWORD secondary
MINSUPPLIES 1
SHUTDOWNCMD "/sbin/shutdown -h +0"
NOTIFYCMD /usr/sbin/upssched
POLLFREQ 5
POLLFREQALERT 5
HOSTSYNC 15
DEADTIME 15
POWERDOWNFLAG /etc/killpower
NOTIFYFLAG ONLINE       SYSLOG+WALL+EXEC
NOTIFYFLAG ONBATT       SYSLOG+WALL+EXEC
NOTIFYFLAG LOWBATT      SYSLOG+WALL+EXEC
NOTIFYFLAG FSD          SYSLOG+WALL+EXEC
NOTIFYFLAG COMMOK       SYSLOG+WALL+EXEC
NOTIFYFLAG COMMBAD      SYSLOG+WALL+EXEC
NOTIFYFLAG SHUTDOWN     SYSLOG+WALL+EXEC
NOTIFYFLAG REPLBATT     SYSLOG+WALL+EXEC
NOTIFYFLAG NOCOMM       SYSLOG+WALL+EXEC
NOTIFYFLAG NOPARENT     SYSLOG+WALL+EXEC
RBWARNTIME 43200
NOCOMMWARNTIME 300
FINALDELAY 5

其中 UPSNAME 是 UPS 的名字,可以随便起名。NUT_SERVER_IP 是 NUT 服务所在机器(本例中 UNRAID NAS)的 IP 地址,USERNAME 是 slave 用户的用户名,PASSWORD 是 slave 用户的密码。

配置 UPS 告警:

1
2
3
4
5
6
7
8
cat /etc/nut/upssched.conf  | grep -v '^#'|grep -v '^\s*$'
CMDSCRIPT /bin/upssched-cmd-custom
PIPEFN /run/nut/upssched.pipe
LOCKFN /run/nut/upssched.lock
AT ONBATT * START-TIMER onbattwarn 30
AT ONLINE * CANCEL-TIMER onbattwarn
AT ONLINE * EXECUTE ups-back-on-line
AT LOWBATT * EXECUTE lowbatt

其中 /bin/upssched-cmd-custom 是一个脚本,其中可以记录一些日志,或者发送告警通知。本例中因为告警通知已由 UNRAID 系统发送,因此只记录本机日志:

 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
29
30
#!/usr/bin/env bash

set -ex

exec >> /var/log/upssched-cmd.log 2>&1

echo "执行 ID: $(id)"

function xpoweroff(){
        logger -t upssched-cmd '准备关闭PVE节点"XXX"'
        /usr/sbin/shutdown now
}


case $1 in
    onbattwarn)
        logger -t upssched-cmd 'UPS 已经切换到电池供电, 准备安全关闭系统...'
        xpoweroff
        ;;
    ups-back-on-line)
        logger -t upssched-cmd '市电已恢复...'
        ;;
    lowbatt)
        logger -t upssched-cmd 'UPS 电量不足, 立即关闭系统...'
        xpoweroff
        ;;
    *)
        logger -t upssched-cmd "Unrecognized command: $1"
        ;;
esac

配置完成后通知监控服务重新读取:

1
upsmon -c reload

在 UNRAID 的 NUT 配置中可以查看连接的 slave 的 IP 地址。如果启用了 NUT footer 界面,也可以在页面的底部查看: UNRAID NUT footer