UPS Nut 配置教程
一、Nut 安装
这里我采用的是 Ubuntu Server 22.04 系统, 安装直接一条 apt 命令即可:
1 |
|
二、Nut 服务组成
在配置 Nut 之前需要先了解下一 Nut 的各个组件及其作用, Nut 主要包含三个核心服务:
- nut-driver: 这个服务负责通过特定放驱动来与 UPS 进行通信
- nut-server: 该服务利用 nut-dirver 沟通 UPS, 并将 UPS 状态通过网络服务发布
- nut-monitor(nut-client): 该服务连接 nut-server, 根据 UPS 状态做出特定响应
注意: nut-client 实际上是一个 systemd 软连接文件, 本质上还是 nut-monitor.
为了更容易理解这里画了一个简单的图:
1 |
|
三、Nut 基本配置
在 Nut 安装完成后会自动在 /etc/nut
目录生成配置文件, 接下来的配置工作主要是调整该目录下的各种配置文件.
3.1、nut.conf
该配置主要定义 nut 的运行模式, 只有一个配置字段 MODE=xxxx
, 该配置可选值及含义如下:
none
: Nut 未配置或使用外部系统启动 Nut 服务, 可以理解为 “啥也不干”.standalone
: 独立模式, 一般在只有一个 UPS 且只负责本地系统(不提供网络服务)的情况下使用.netserver
: 跟独立模式类似, 会启动 driver、upsd 和 upsmon 服务, 不同之处是可以提供网络服务, 其他机器上的 nut-monitor 可以通过网络来连接 Nut Server.netclient
: 仅客户端模式, 只启动 nut-monitor, 用于连接远程的 Nut 服务.
我这是为了方便后续扩展, 所以使用了最全的 netserver
模式:
1 |
|
3.2、ups.conf
该配置用于定义 nut-driver 如何连接到物理 UPS, 该配置文件的饿配置格式如下:
1 |
|
其中 nutdev1
表示该 UPS 名称, 可以随意定义; driver
用于定义连接到该 UPS 需要使用的驱动, 一般情况下如果使用 USB 连接像我这样写都是可以识别到的. 如果同样都是用 USB 连接但识别不到, 可以使用 nut-scanner
命令进行扫描, 扫描成功后会在控制台打印出 UPS 相关配置样例.
需要注意的是, 如果想要群晖或者 QNAP 能通过网络连接 UPS, 那么 UPS 的名称是有特殊要求的(群晖必须起名叫 ups
, QNAP 没有测试过可能叫 qnapups
); 因为这两个系统都写死了, 包括后面的用户名和密码也是, 具体在下文会有说明.
除了 USB 连接 UPS 之外 Nut 还支持多种驱动连接 UPS, 例如 APC 专用的驱动程序, 有关于 Nut 具体连接方式请查看官方文档:
3.3、upsd.conf
该配置文件用于控制 nut-server 的网络服务, 例如监听端口、最大连接数、证书配置等; 由于我是在内网使用, 所以只需要配置网络监听, 其他参数保持默认即可:
1 |
|
如果想要完整查看支持哪些配置, 请参考官方文档: UPSD.CONF(5)
3.4、upsd.users
upsd.users 配置文件用于定义通过网络连接到 nut-server
的用户名和密码, 该配置样例如下:
1 |
|
上面的 [xxxx]
代表用户名, 密码由 password
字段指定; 除此之外还有一些特殊参数:
actions
: 指定该用户具有哪些操作权限, 可选值SET
(更改 UPS 变量)、FSD
(设置 UPS 强制关机标志); 如果需要两个都指定, 则需要写两次actions
.instcmds
: 让用户启动的即时命令, 值ALL
代表所有, 其他的可通过upscmd -l
查看; 同样如果要指定多个需要写多次instcmds
.upsmon
: 为 upsmon 进程添加必要的操作, 可选值primary
、secondary
(一般用不到)
注意: Ubuntu Server 22.04 上的版本可能没有那么新, upsmon 实际上支持的是 master
、slave
两个参数(怀疑与某场运动有关).
关于 群晖 和 QNAP 用户: 如果期望这两个 NAS 可以直接连接到 Nut Server, 可以确认的是群晖需要保证存在用户名为 monuser
密码为 secret
的用户; QNAP 我没有验证过, 网上查询到的结果是需要保证存在用户名为 admin
密码为 123456
的用户.
四、Nut 监控配置
相较于基本配置来说, Nut 核心处理在于如何做好监控配置; Nut 对于监控策略支持大致有两种:
- 1、直接由
upsmon.conf
配置, 任何事件直接由用户指定的脚本负责处理, 没有定时器等高级特性 - 2、在
upsmon.conf
中配置执行脚本为upssched
, 任何事件先由upssched
处理, 借助于 upssched 可以实现一些高级功能, 比如选择性触发关机等
4.1、upsmon.conf
该配置主要用于配置 nut-monitor 如何监控 UPS, 同时定义 UPS 出现哪些事件要进行怎样的处理动作, 下面详细解释一下核心配置.
4.1.1、MONITOR 指令
MONITOR
指令用于定义要监控 UPS 的连接地址, 其格式如下:
1 |
|
<system>
: nut-server 链接地址, 格式为 “UPS 名称” + “@” + “nut-server 地址”, 例如myups@192.168.1.2
<powervalue>
: UPS 数量, 大多数情况你只有一个 UPS 电源, 所以写 1 就行<username>/<password>
: 在upsd.users
中定义的用户名和密码master/slave
:master
表示该系统将最后关闭, 让从属系统先关闭;slave
表示该系统立即关闭
以下为我的配置样例:
1 |
|
4.1.2、SHUTDOWNCMD
SHUTDOWNCMD
指令用于定义在 UPS 电量不足或者需要主动关机时的关机命令, 建议填写完整路径
1 |
|
4.1.3、NOTIFYCMD
NOTIFYCMD
指令是一个非常重要的指令, 该指令用于配置在发生特定事件(如市电中断、UPS 处于低电量等)时, nut-monitor
所执行的命令. 简单的说就是 NOTIFYCMD
定义了具体执行命令, 可以直接在此处配置一个自己编写的脚本, 当 UPS 有事件发生时此脚本都会被调用.
NOTIFYCMD
指令大致有两种配置方式, 一种是配置成自己的脚本, 脚本需要有可执行权限, 脚本内可以通过 NOTIFY
环境变量获取事件类型, 然后自己进行处理. 这种方式有点 “简单粗暴” 的意思, 可定制化程度完全依赖于你的脚本怎么写. 具体可以使用哪些变量请自行测试, 因为版本不同可能环境变量名称也不同.
还有一种方式是将 NOTIFYCMD
配置为执行内置的 upssched
命令; upssched
是 Nut 提供的一个带有特定策略的调度程序; 简而言之就是基于常用的功能进行了抽象, upssched
有自己单独配置, 可以实现 “如果市电在 180s 内恢复则不进行关机” 的这种高级调度策略.
这里我选择使用第二种方式, 因为自己搓脚本能力实在不怎么样:
1 |
|
4.1.4、NOTIFYFLAG
NOTIFYFLAG
同样是关键配置, 需要与 NOTIFYCMD
配合使用; NOTIFYFLAG
指令负责指定一系列的 UPS 事件应该触发何种操作, 该指令格式如下:
1 |
|
其中 <notify type>
表示事件类型, 可选类型如下:
ONLINE
: UPS 在线, 即市电恢复时会触发ONBATT
: UPS 使用电池供电, 即市电中断时会触发LOWBATT
: UPS 低电量时会触发FSD
: UPS 正在被关闭(Forced Shutdown)COMMOK
: 与 nut-server 成功建立连接时触发COMMBAD
: 与 nut-server 建立连接失败(连接丢失)时触发SHUTDOWN
: UPS 发出关机指令触发REPLBATT
: UPS 需要更换电池时触发NOCOMM
: 无法与 UPS 建立连接(UPS未就绪)时触发
对于 flag
标志通常有四种, 多种组合时用加号(+)连接:
SYSLOG
: 只打印 syslogWALL
: 在终端上弹出消息(/bin/wall)EXEC
: 调用NOTIFYCMD
指定的命令, 并传递相关事件IGNORE
: 啥也不干, 忽略该事件
如果 NOTIFYCMD
使用了自定义脚本, 则此处请根据实际需要来配置需要脚本处理的事件; 如果 NOTIFYCMD
配置为使用 upssched
, 可以将所有事件配置为 EXEC
, 然后具体过滤在 upssched
处理.
例如如果只想让 NOTIFYCMD
配置的脚本只处理市电中断和恢复事件, 同时打印 syslog, 可以这样配置:
1 |
|
由于我 NOTIFYCMD
配置的是 upssched
, 所以我这里将所有事件全部传递给 upssched
:
1 |
|
4.1.5、其他配置
除了以上的核心配置, 其他配置如果没特殊情况一般保持默认即可; 具体的配置可以参考官方文档: UPSMON.CONF(5).
4.2、upssched.conf
使用该配置的前提是 upsmon.conf
配置中的 NOTIFYCMD
指向了 upssched
, 并且 NOTIFYFLAG
为相关事件配置了 EXEC
; 该配置主要的作用是使用一些 upssched
内置的高级语法来控制特定事件的处理方式. upssched.conf
配置主要包含两部分: 头部的选项配置和尾部的规则配置.
4.2.1、选项配置
头部选项配置只包含三个配置:
CMDSCRIPT
: 该配置应该位于首行(推荐这样, 实际上是 AT 指令之前就行), 该指令用于定义事件的处理脚本; 脚本一般由用户自行编写,upssched
会根据规则将指定参数传递到此脚本并执行.PIPEFN
: 用于进程间通信的管道文件, 需要位于 AT 指令之前LOCKFN
: 互斥锁文件, 用于防止 upsmon 同时调度多个文件, 需要位于 AT 指令之前
关于 CMDSCRIPT
配置的脚本, 下面是一个样例:
1 |
|
有一点需要注意, CMDSCRIPT
配置的脚本默认是以 nut
用户运行的, 所以要处理好 nut
用户权限问题.
对于 PIPEFN
和 LOCKFN
官方推荐单独创建叫 upssched
目录, 然后文件放在这个目录里; 但是有些系统例如 Ubuntu Server 22.04, /run/nut/
是 tmpfs, 重启会丢失目录导致出现权限问题; 所以推荐直接不创建独立目录直接配置:
1 |
|
4.2.2、规则配置
使用 upssched
的好处就是内置了一个规则引擎, 我们可以通过一些简单的语法来配置复杂规则; upssched
的规则语法如下:
1 |
|
规则以 AT
开头, notifytype
用于指定需要关注的事件类型; upsname
指定 UPS 名称, 只有一个的情况下或者不想区分时可以无脑写 *
; command
部分用于指定需要执行的动作, command
大致有三种类型:
START-TIMER
: 启动一个定时器CANCEL-TIMER
: 取消一个定时器EXECUTE
: 立即执行
这部分看起来复杂实际很简单, 例如以下规则实现了: 当市电断开(UPS 使用电池供电时)启动一个名字叫 onbattwarn
的定时器, 这个定时器在 180s 后会执行 CMDSCRIPT
定义的脚本并将 onbattwarn
作为第一个参数传递给脚本; 同时如果市电在计时器的 180s 之内恢复(临时闪断), 则取消执行脚本.
1 |
|
当然也有些事件是需要立即执行的, 例如: 市电中断立即发送通知
1 |
|
五、配置参考
上面说了那么多, 下面给一个完整的我个人的配置参考:
nut.conf
1 |
|
ups.conf
1 |
|
upsd.conf
1 |
|
upsd.users
1 |
|
upsmon.conf
1 |
|
upssched.conf
1 |
|
upssched-cmd.sh
1 |
|