Skip to content
> 0x2d.dev
Назад

Настройка ИБП на сервере Proxmox


ИБП (UPS — Uninterruptible Power Supply) в домашнем сервере — это не просто “коробка с батарейкой”. Это элемент инфраструктуры, который защищает данные, оборудование и обеспечивает корректное завершение работы системы при отключении электричества.

Основные типы протоколов ИБП

  1. USB HID Power Device (лучший вариант)
  1. Megatec / Voltronic / Q1 / Mustek
  1. Проприетарные протоколы
  1. SNMP / Network UPS

Поиск ИБП в системе

Рассмотрим настройку на примере Proxmox VE 9, но на дистрибутивах основанных на Debian все будет аналогично. Подключите ИБП к серверу по USB и подключитесь по SSH.

Note

Дальнейшие команды будут выполняться из под пользователя root, для выполнения под обычным пользователем иногда понадобится использовать sudo

Проверка определился ли ИБП в системе

lsusb

Если ваш ИБП HID UPS — он обычно определяется как HID UPS Battery, Power Device, usbhid, например:

Bus 001 Device 005: ID 1234:5678 APC UPS

Если ИБП использует протоколы Megatec / Voltronic / Q1 / Mustek, то устройство будет назваться примерно как в нашем случае (бюджетный ИБП EXEGATE NEO Smart 850):

Bus 001 Device 005: ID 0665:5161 Cypress Semiconductor USB to Serial

Значения ID это vendorId и productId, они понадобятся нам для дальнейшей настройки.

Как найти нужный драйвер, если у вас не HID UPS

Получите подробное описание USB устройств командой: lsusb -v. В нашем случае для устройства Bus 001 Device 005: ID 0665:5161 Cypress Semiconductor USB to Serial не видим стандартный свойств для ИПБ:

Interface Class: Human Interface Device
Usage: Power Device

Но видим косвенные признаки по свойствам, что устройство — HID, но НЕ Power Device. Это означает производитель использует HID-обёртку поверх собственного протокола.

Interface Class: Human Interface Device
iInterface: Smart USPS

Запускаем сканер:

nut-scanner -U

И видим что он предлагает нам использовать nutdrv_qx — это универсальный драйвер для: Megatec / Q1 / Mustek / Voltronic.

Scanning USB bus.
[nutdev1]
        driver = "nutdrv_qx"
        port = "auto"
        vendorid = "0665"
        productid = "5161"
        product = "USB to Serial"
        vendor = "WCHCH544"
        bus = "001"
        device = "005"
        busport = "006"
        ###NOTMATCHED-YET###bcdDevice = "0002"

Пробуем в nano /etc/nut/ups.conf указать универсальный драйвер:

[exegate]
    driver = nutdrv_qx
    port = auto
    vendorid = 0665
    productid = 5161
    subdriver = armac

И запустить его в ручную в дебаг режиме:

/usr/lib/nut/nutdrv_qx -a exegate -DD -x subdriver=armac -x vendorid=0665 -x productid=5161 -x bus=001 -x device=002

По логу видно что драйвер открывает устройство, но командам, которые он пытается слать (QGS, QS, D, M), устройство не отвечает → идут interrupt read timeout → потом I/O error.

Значит: либо не тот subdriver, либо интерфейс/endpoint другой, либо этот UPS вообще не “qx/armac”-совместимый с NUT.

0.431273 [D2] armac: unsupported cmd: D 0.431275 [D2] qx_process_answer: short reply (input.voltage) 
1.533920 [D1] interrupt read error: Operation timed out (-7) 
2.908550 [D1] interrupt read error: Operation timed out (-7)

Дальше перебираем subdriver’ы из nutdrv_qx, но по одному. Для этого узнаем список доступных subdriver и запускаем драйвер с каждым из них, например с cypress:

~# /usr/lib/nut/nutdrv_qx -h | grep -i subdriver -n
134:Acceptable values for 'subdriver' via -x or ups.conf in this driver: cypress, phoenixtec, phoenix, ippon, krauler, fabula, hunnox, fuji, sgs, snr, ablerex, armac

~# /usr/lib/nut/nutdrv_qx -a exegate -DD -x subdriver=cypress -x vendorid=0665 -x productid=5161 -x bus=001 -x device=002
5.252375 [D2] voltronic_qs_protocol: invalid protocol [(234.4 234.4 235.4 015 50.0 13.8 --.- 00001001] 
9.764465 [D2] voltronic_qs_protocol: invalid protocol [(234.9 234.9 236.1 015 50.0 13.8 --.- 00001001] 
18.788860 Using protocol: Mustek 0.08
35.321315 [D1] Quick update... 
35.813318 [D2] qx_process_answer: short reply (ups.status) 
35.813329 [D1] Communications with the UPS lost: status read failed!

С subdriver=cypress драйвер начал получать осмысленные строки (видно напряжение ~234В и т.п.) и даже написал: Using protocol: Mustek 0.08. Но дальше он периодически теряет статус (status read failed).

Фиксируем в /etc/nut/ups.conf

[myups]
    driver = nutdrv_qx
    port = auto
    vendorid = 0665
    productid = 5161
    subdriver = cypress
    protocol = mustek
    pollfreq = 15 # частота опроса ИБП в секундах
    novendor # отключает попытку читать данные производителя
    norating # отключает чтение "паспортных" параметров UPS, убирает ошибки типа: invalid start character, non numerical value
    ignoresab # отключает ложные триггеры "shutdown state"/etc/nut/ups.conf

После этого рекомендуется перезагрузить машину, чтобы исключить перехваты USB endpoint запущенным вручную драйвером.

Установка и настройка NUT

Network UPS Tools — это популярный бесплатный программный комплекс с открытым исходным кодом, предназначенный для мониторинга и управления источниками бесперебойного питания.

apt update
apt install nut -y
find /etc/nut/ -maxdepth 1 -name "*.conf" -exec cp -v {} {}.bak \;

После установки сразу делаем резервную копию всех файлов конфигурации NUT.

В файле nut.conf нужно найти и раскомментировать строку MODE или добавить, если ее нет.

MODE=standalone/etc/nut/nut.conf

MODE=standalone означает драйвер + upsd + upsmon на одной машине

Настройка UPS

В файле ups.conf пропишите конфигурацию вашего ИПБ, добавив в конце файла следующую секцию.

HID UPS

Можете указать vendorid и productid, которые вам выдала команда lsusb, но обычно это не нужно.

[myups] # любое имя для вашего ИБП
    driver = usbhid-ups
    port = auto
    vendorid = 1234
    productid = 5678/etc/nut/ups.conf

Mustek

В нашем примере мы определили что у ИБП EXEGATE NEO Smart 850 subdriver = cypress и protocol = mustek. Так же укажите vendorid и productid, которые вам выдала команда lsusb.

[myups] # любое имя для вашего ИБП
    driver = nutdrv_qx
    port = auto
    vendorid = 0665
    productid = 5161
    subdriver = cypress
    protocol = mustek
    pollfreq = 15 # частота опроса ИБП в секундах
    novendor # отключает попытку читать данные производителя
    norating # отключает чтение "паспортных" параметров UPS, убирает ошибки типа: invalid start character, non numerical value
    ignoresab # отключает ложные триггеры "shutdown state"/etc/nut/ups.conf

Проверка драйвера

~# upsdrvctl stop
~# upsdrvctl start
Network UPS Tools - UPS driver controller 2.8.1
Network UPS Tools - Generic Q* USB/Serial driver 0.36 (2.8.1)
USB communication driver (libusb 1.0) 0.46
Using protocol: Mustek 0.08

Настройка сервера (upsd)

Определяем по какому адресу и порту NUT будет отдавать данные. Найдите в файле LISTEN и исправьте ее или добавьте в конец:

LISTEN 127.0.0.1 3493 # для локального доступа 
# LISTEN 0.0.0.0 3493 # для доступа в сети/etc/nut/upsd.conf

Добавляем пользователя для управления состоянием. Добавьте в конец файла:

[monuser] # можете указать любой логин
  password = password # укажите свой пароль
  upsmon primary/etc/nut/upsd.users

Перезапускаем сервисы и проверяем:

systemctl restart nut-driver
systemctl restart nut-server
upsc myups@localhost # вместо myups укажите имя вашего ИБП, которое вы прописали в /etc/nut/ups.conf

Последняя команда должна вывести информацию о драйвере и показатели ИБП:

Init SSL without certificate database
battery.voltage: 13.4
device.type: ups
driver.debug: 0
driver.flag.allow_killpower: 0
driver.flag.ignoresab: enabled
driver.flag.norating: enabled
driver.flag.novendor: enabled
driver.name: nutdrv_qx
driver.parameter.pollfreq: 15
driver.parameter.pollinterval: 2
driver.parameter.port: auto
driver.parameter.productid: 5161
driver.parameter.protocol: mustek
driver.parameter.subdriver: cypress
driver.parameter.synchronous: auto
driver.parameter.vendorid: 0665
driver.state: quiet
driver.version: 2.8.1
driver.version.data: Mustek 0.08
driver.version.internal: 0.36
driver.version.usb: libusb-1.0.28 (API: 0x100010a)
input.frequency: 50.0
input.voltage: 236.4
input.voltage.fault: 236.4
output.voltage: 237.5
ups.beeper.status: enabled
ups.delay.shutdown: 30
ups.delay.start: 180
ups.load: 18
ups.productid: 5161
ups.status: OL
ups.type: offline / line interactive
ups.vendorid: 0665

Мониторинг NUT

Далее настроим NUT монитор, который будет сообщать системе о состоянии и отправлять сигнал выключения при низком заряде аккумулятора. Если вы создали резервную копию файла, то удобней очистить текущий upsmon.conf и указать только нужные параметры:

RUN_AS_USER nut # пользователь, под которым работает nut

# Главная строка конфигурации, указывает какой ИБП мониторить
# myups@localhost - имя ИБП и адрес сервера, укажите свое имя, которое создавали в файле /etc/nut/ups.conf
# 1 - это вес источника, для одного ИБП всегда 1
# upsmon password - логин и пароль, который создавали в файле /etc/nut/upsd.users
# primary - сервер имеет право инициировать завершение работы UPS

MONITOR myups@localhost 1 upsmon password primary

MINSUPPLIES 1 # Сколько источников питания должно оставаться доступными

SHUTDOWNCMD "/sbin/shutdown -h now" # Команда, которую выполнит NUT при необходимости выключить сервер

POLLFREQ 5 # Как часто upsmon опрашивает upsd
POLLFREQALERT 5 # Частота опроса во время аварии

HOSTSYNC 15 # После получения сигнала на завершение работы сервер ждёт пока остальные серверы тоже подтвердят завершение
DEADTIME 15 # Время после, которого ИБП считается потерянным

POWERDOWNFLAG /etc/killpower # Файл-маркер для финального выключения UPS

RBWARNTIME 43200 # Как часто сообщать о замене батареи. 43200 секунд = 12 часов
NOCOMMWARNTIME 300 # Как часто сообщать о потери связи с ИБП - каждые 5 минут

FINALDELAY 5 # Финальный таймер. После принятия решения о выключении сервера ещё ожидает 5 секунд

# Рекомендуется добавить дополнительные уведомления с системный лог
NOTIFYCMD /usr/sbin/upssched

NOTIFYFLAG ONLINE SYSLOG
NOTIFYFLAG ONBATT SYSLOG
NOTIFYFLAG LOWBATT SYSLOG
NOTIFYFLAG FSD SYSLOG
NOTIFYFLAG COMMOK SYSLOG
NOTIFYFLAG COMMBAD SYSLOG
NOTIFYFLAG SHUTDOWN SYSLOG/etc/nut/upsmon.conf

После сохранения конфигурации проверяем ее, перезапускаем сервис и проверяем статус.

upsmon -D
systemctl status nut-monitor

Если вы указали неверные данные подключения к ИБП или допустили другую ошибку, то upsmon -D выведет предупреждение об этом

Мониторинг на втором сервере

Сейчас на сервере настроен NUT, который напрямую работает с UPS через USB. Этот сервер получает все данные от источника питания и публикует их в сеть через сервис upsd. По сути, он становится центральной точкой, которая знает текущее состояние UPS и реагирует на изменения, например переход на батарею или низкий заряд.

Кроме этого, к нему могут подключаться другие серверы в сети. Они не имеют прямого доступа к UPS, но через NUT получают все те же данные с главного сервера и могут корректно реагировать на отключение питания, например завершать работу. Таким образом один сервер с UPS может управлять питанием сразу нескольких машин в сети.

Проверка и создание пользователя

На сервере к которому подключён UPS по USB проверьте что в файле /etc/nut/upsd.conf у вас указано LISTEN 0.0.0.0 3493, для того чтобы NUT был доступен внутри локальной сети.

Мы уже создали выше пользователя monuser, но у него “роль” primary, такой пользователь может управлять UPS и лучше для клиентов NUT создать другого пользователя с более низкими правами.

Откройте файл с пользователями и добавьте в конец ещё одного:

[readuser] # можете указать любой логин
  password = password # укажите пароль
  upsmon secondary # тут уже не primary, а secondary/etc/nut/upsd.users

Перезапускаем сервисы:

systemctl restart nut-server
systemctl restart nut-monitor

Теперь подключаемся ко второму серверу.

Настройка NUT клиента

На втором сервере устанавливаем NUT клиент и сразу проверяем подключение к основному серверу:

apt install nut-client
upscmd -l myups@192.168.10.2 # укажите название ИБП и адрес первого сервера

Читать данные о состоянии ИБП внутри сети можно без логина и пароля, если вы специально не запретили это в настройках.

Если связь есть, то аналогичным образом создаём резервные копии конфигурации и настраиваем nut.conf и upsmon.conf.

MODE=netclient # ключевой момент, теперь тут режим клиента/etc/nut/nut.conf
# myups - название UPS на сервере
# 192.168.1.10 - адрес сервера
# 1 - это вес источника, для одного ИБП всегда 1
# readuser - логин второго пользователя
# password - пароль
# secondary - "роль" не должна быть primary
MONITOR myups@192.168.1.10 1 readuser password secondary

# остальные команды как на сервере
MINSUPPLIES 1
SHUTDOWNCMD "/sbin/shutdown -h now"
RUN_AS_USER nut/etc/nut/upsmon.conf

Проверяем конфигурация, перезапускам сервис и смотрим статус сервиса:

systemctl restart nut-client
upsmon -D
systemctl restart nut-monitor
systemctl status nut-monitor

Проверка

Можете попробовать отключить ИБП от сети и после этого в системных логах на серверах проверить записи:

journalctl -u nut-monitor -f

В логах должны быть записи со статусом OB - питание от батареи.

Мониторинг ИБП

Так же как и второй сервер вы можете получать данные от NUT по сети и в зависимости от ситуации настроить уведомления и автоматизации.

Список статусов NUT необходимые для мониторинга

Комбинации тоже возможны, например:

Home Assistant

Установите стандартную интеграцию Network UPS Tools (NUT) и укажите настройки подключения: название ИБП и адрес сервера.

Интеграция мониторинга ИБП NUT в Home Assistant

Prometheus и Grafana

Существует множество экспортёров метрик NUT в Prometheus, рассмотрим один из них и развернём его в докере. Экспортёры обычно легковесные, можно развернуть без докера прямо на сервере, подробнее в документации на GitHub.

services:
  exporter-nut:
    container_name: exporter-nut
    image: ghcr.io/druggeri/nut_exporter:latest
    restart: unless-stopped
    ports:
      - "9995:9995"
    environment:
      - NUT_SERVER=192.168.10.2 # сервер с ИБП
      - NUT_PORT=3493 # порт, который указывали в настройках NUT
    command:
      - "--web.listen-address=:9995"docker-compose.yaml

После запуска контейнера docker compose up -d проверяем что метрики отдаются по адресу докер сервера: http://192.168.10.1:9995/ups_metrics

Обратите внимание что по адресу /metrics отдаёт свои метрики, а метрики NUT он отдаёт по /ups_metrics

Настраиваем Prometheus, добавим в секцию scrape_configs конфигурацию экспортёра.

scrape_configs:
  - job_name: nut
    metrics_path: /ups_metrics
    static_configs:
      - targets: ['192.168.10.139:9995'] # адрес и порт сервера с докер контейнером
        labels:
          ups: "primary"/etc/prometheus/prometheus.yml

Перезапускаем

systemctl restart prometheus

Через несколько секунд проверяем в веб-интерфейсе Prometheus в разделе Status / Target health что метрики пошли.

Метрики NUT в Prometheus

В Grafana импортируйте подходящий для вас дашборд или настройте свой.

Nut метрики в Grafana

Nut метрики в Grafana


Предыдущая запись
Прошивка Klipper Mod для 3Д принтера Flashforge Adventurer 5M
Следующая запись
Облачная виртуальная машина за 150р. в месяц