NAS系列-3:接入UPS

704 阅读4分钟

日常讲故事环节

上次数据库闹鬼出了些幽灵数据,以为是断电和强制关机导致的,然后又发现系统有问题。所以换了 debian 12,换完之后发现晚上还是会崩,看日志,报错全是我数据盘的,让我运行 xfs_repair,然后还发现错误里还有 nvidia 的字眼,现在有理由怀疑上次水系显卡 风扇 是不是搞坏了,这次一并换下来,先观察一阵。然后还有个一直要处理的问题,供电!

8 盘位的 nas,每次断电玩的都是心跳,都在祈祷硬盘别挂,好了,这次顺便加个 UPS 把供电问题也解决了。

选型

本来觉得只要能撑个一两分钟让我能正常关机就行,奈何市场没有这种产品,就正常找家用 NAS 的,然后发现全都是适配成品 NAS 的,输出都是直流!后面找了随便找了个 山克SK650 真没收广告费,主要不像正常的 UPS 那么丑,功率 360W 也够了。

买前问了下客服我普通 linux 能不能用,直接回答说不行。准备换一个了,然后打开浏览器又查了下,NUT 似乎又可以通信,继续问客服,说如果我懂这些可以买回来试一下,不行就 7 天无理由退款,直接就下单了。

配置

到货立刻就装上了,接着就是软件配置了。

1、安装通信工具

apt install -y nut

2、配置工作模式

# 编辑 /etc/nut/nut.conf,修改 MODE 的值
MODE=standalone

3、查找 UPS 信息

nut-scanner
# 我这款返回以下信息
[nutdev1]
        driver = "nutdrv_qx"
        port = "auto"
        vendorid = "0665"
        productid = "5161"
        product = "USB to Serial"
        vendor = "INNO TECH"
        bus = "001"

4、配置 nut-server 驱动信息

# 把上面查询到的信息全部放到 /etc/nut/ups.conf,包括 [nutdev1]
# 我这里修改 nutdev1 这个名字之后无法启动,按理说不应该的
[nutdev1]
        driver = "nutdrv_qx"
        port = "auto"
        vendorid = "0665"
        productid = "5161"
        product = "USB to Serial"
        vendor = "INNO TECH"
        bus = "001"

5、修改 nut-server 服务

# 编辑 /etc/nut/upsd.conf,添加服务端口,127.0.0.1 只会允许本地访问,所以要 0.0.0.0
LISTEN 0.0.0.0 3494

6、配置管理账号

# 编辑 /etc/nut/upsd.users,账号密码为 admin/admin
[admin]
        password = admin
        upsmon master

7、配置客户端服务

# 编辑 /etc/nut/upsmon.conf,确保存在一条 MONITOR 记录,且与 /etc/nut/upsd.users 匹配
MONITOR nutdev1@localhost 1 admin admin master

8、重启服务

systemctl restart nut-server    # 实际上就是 upsd
systemctl restart nut-monitor   # 实际上就是 upsmon
# 配置开机启动
systemctl enable nut-server
systemctl enable nut-monitor

完成以上配置后执行 upsc nutdev1@localhost 应该就可以看到 UPS 返回的数据。

web 服务

直接配个 docker 来用,其他方式自行查询配置方法,以下配置有问题请看本系列前几篇,有类似配置过程,这里不再赘述。

nutweb:
    container_name: nutweb
    image: ghcr.nju.edu.cn/superioone/nut_webgui:latest
    restart: unless-stopped
    environment:
      UPSD_ADDR: 192.168.1.254  # 实际就是宿主机内网地址
      UPSD_USER: nutdev1
      UPSD_PASS: admin
    networks:
      - nginx_ipv4

nginx 反代

server {
     listen 443 ssl;
     server_name nut.example.cn;
​
     client_max_body_size 0;
​
     # SSL
     ssl_certificate /etc/nginx/ssl/example.cn_ecc/fullchain.cer;
     ssl_certificate_key /etc/nginx/ssl/example.cn_ecc/example.cn.key;
​
     # security headers
     include /etc/nginx/conf.d/security.conf;
​
​
     # reverse proxy
     location / {
         # 仅允许内网访问,先生,你也不想别人打开了你的网站然后对服务器直接发个关机指令吧
         allow 192.168.1.0/24;
         deny all;
         proxy_pass http://nutweb:9000;
         proxy_set_header Host                         $host;
         proxy_set_header X-Real-IP                    $remote_addr;
         proxy_set_header X-Forwarded-For      $proxy_add_x_forwarded_for;
     }
 }

优化

上述配置完成后还需要优化以下内容:

1、UPS 默认的满电电压是 13V,但是实际返回的是 13.5V

2、UPS 可用时长测算;

3、设置自动关机的低电量阈值。

4、双保险起见,根据测算可用时长,小于 5 分钟时自动关机

解决方式:

1、/etc/nut/ups.conf 的驱动配置项中添加 override.battery.voltage.high = 13.5

2、根据客服回复,50W 左右续航大概 30~40 分钟,满负载 360W 大概十分钟,我 NAS 54W ,负载 15%,因此/etc/nut/ups.conf 的驱动配置项中添加runtimecal = 600,100,1800,15,即 <满负载持续时长(秒)>,<满负载100%>,<15%负载持续时长(秒)>,<15%负载>

3、/etc/nut/ups.conf 的驱动配置项中添加 override.battery.charge.low = 20

4、/etc/nut/ups.conf 的驱动配置项中添加 battery.runtime.low = 300

设置 override.ups.beeper.status = "disable" 试图关闭断电后的蜂鸣器告警,果然客服没骗我,关不掉

最终配置文件内容为:

[nutdev1]
        driver = "nutdrv_qx"
        desc = "shanke-bk650"   # 描述信息,自定义,不能为中文
        port = "auto"
        vendorid = "0665"
        productid = "5161"
        vendor = "INNO TECH"
        bus = "001"
        runtimecal = "600,100,1800,15"
        override.battery.voltage.high = 13.5
        override.battery.charge.low = 20
        override.battery.runtime.low = 300
        override.ups.beeper.status = "disable"

成品展示

PixPin_2025-05-12_21-45-39.jpg

联动关机

  • 默认方式

    # 需要配置 NOTIFYFLAG,编辑 /etc/nut/upsmon.conf,确保以下内容正确
    NOTIFYFLAG LOWBATT  EXEC+SYSLOG
    
  • upssched 方式

    • 配置 /etc/nut/upsmon.conf
    # 调用 /usr/sbin/upssched
    NOTIFYCMD /usr/sbin/upssched
    NOTIFYFLAG LOWBATT  EXEC+SYSLOG
    
    • 配置 /etc/nut/upssched.conf
    CMDSCRIPT /etc/nut/upssched-cmd
    PIPEFN /var/run/nut/upssched.pipe
    LOCKFN /var/run/nut/upssched.lock
    ​
    # 低电量触发 /etc/nut/upssched-cmd 脚本,传入 poweroff 参数
    AT LOWBATT * EXECUTE poweroff
    
    • 新建 /etc/nut/upssched-cmd 联动脚本
    #!/bin/sh
    case $1 in
        poweroff)
            sudo /sbin/shutdown -h +0
            ;;
        *)
            logger -t upssched "Unknown command: $1"
            ;;
    esac
    

以上就是分配关机权限,因为脚本默认使用 nut 用户执行,没有 shutdown 的权限,因此两种方式都需要把关机权限分配给 nut,同时注意 /etc/nut/upssched-cmd 中关机指令需要添加 sudo,添加权限方式为修改 /etc/sudoers

# 先添加写权限 sudo chmod +w /etc/sudoers
# 添加以下行
nut ALL=(ALL) NOPASSWD:/sbin/shutdown
# 恢复权限 sudo chmod -w /etc/sudoers

结论

这款 UPS 还是可以跟 debian 这种原生 linux 联动的,只是配置麻烦点而已,三个插座,再挂个路由器,能撑半个小时 (存疑,就断电听个蜂鸣器的功夫就剩71%了)300 不到,要啥自行车。

自动关机还没触发过,希望不要有下文