Настройка NUT + Proxmox + Synology
У меня в Proxmox развернут DSM (XPEnology). Я недавно переехал и сейчас тут периодические проблемы с электричеством, которые у меня ранее не возникали. Приобрел 1 из доступных ИБП - CyberPower UT850EIG c IEC розетками.
После прочтения двух статей была найдена интересная реализация, которую я успешно применил на своем сервере.
В целом, как показала практика, любой UPS с USB можно подружить с Proxmox и прокинуть в DSM как ИБП Synology, несмотря на отсутствие поддержки ИБП в списке моделей для Synology.
Суть реализации в настройке NUT сервера и клиента прямо на машине с Proxmox для контроля ИБП и поведения при изменении статуса батарей. Дополнительно же установим LXC контейнер с NUT клиентом и веб-сервером Apache для мониторинга состояния ИБП без использования консоли. В конце добавим ИБП в Synology.
Настройка NUT сервера и клиента на сервере с Proxmox
Заходим в консоль машины, на которой установлен Proxmox (в моем случае версии 8.3.0) и смотрим список usb устройств командой:
lsusb
Нам нужно найти наш ИБП и узнать его bus и device:
Теперь посмотрим детальную информацию, указав bus и device, в моем случае:
lsusb -v -s 3:5
где 3 - шина (bus), 5 - устройство (device)
Как видно, система распознает ИБП и можно приступать к установке nut:
apt install nut -y
Проверяем, видит ли nut наш ИБП:
nut-scanner -U
Перед правкой конфигов, на всякий случай, лучше сделать резервные копии всех этих файлов:
cp /etc/nut/nut.conf /etc/nut/nut.example.conf cp /etc/nut/ups.conf /etc/nut/ups.example.conf cp /etc/nut/upsd.conf /etc/nut/upsd.example.conf cp /etc/nut/upsd.users /etc/nut/upsd.example.users cp /etc/nut/upsmon.conf /etc/nut/upsmon.example.conf cp /etc/nut/upssched.conf /etc/nut/upssched.example.conf cp /bin/upssched-cmd /bin/upssched-cmd.example
Теперь перейдем к правке. Первый на очереди nut.conf
:
nano /etc/nut/nut.conf
MODE=netserver
nano /etc/nut/ups.conf
# pollinterval и maxretry работают вместе для надежного мониторинга # Определяет частоту опроса состояния ИБП (в секундах) pollinterval = 15 # Количество попыток повторного подключения к ИБП при потере связи # Если после 3 попыток связь не восстановится, система считает ИБП недоступным maxretry = 3 # offdelay и ondelay образуют временную защиту для процессов выключения/включения # Задержка перед фактическим выключением питания после команды на shutdown (в секундах) # Это время дается системе на: # Корректное завершение работы всех служб # Сохранение данных # Выполнение процедур очистки offdelay = 300 # Задержка перед включением питания после восстановления основного электропитания (в секундах) # Это предотвращает: # Многократные циклы включения/выключения при нестабильном питании # Слишком быстрое включение до полной стабилизации напряжения ondelay = 30 [ups] driver = usbhid-ups port = auto desc = "CyberPower UT850EG" vendorid = 0764 productid = 0501 serial = ""
Обратите внимание, что все данные по своему ИБП я брал из вывода команд, указанных выше. В квадратных скобках имя ups оставляем как есть для Synology.
Необходимо настроить файл ups.conf на сервере NUT, чтобы ИБП назывался «ups». Он не может называться как-то иначе. В противном случае Synology откажется подключаться.
Сохраняем файл и можем протестировать драйвер:
upsdrvctl start
Если что-то неверно распознается, проверьте список совместимого оборудования чтобы узнать, какой драйвер использовать.
nano /etc/nut/upsd.conf
Дадим указание серверу отвечать на запросы из всех сетей. Удаляем все и добавляем:
LISTEN 0.0.0.0 3493 LISTEN :: 3493
nano /etc/nut/upsd.users
Настроим администратора и пользователя. Удаляем все и добавляем:
[upsadmin] # Administrative user password = ******** # Allow changing values of certain variables in the UPS. actions = SET # Allow setting the "Forced Shutdown" flag in the UPS. actions = FSD # Allow all instant commands instcmds = ALL upsmon master [upsuser] # Normal user password = ******** upsmon slave [monuser] # DSM user password = secret admin slave
Нужно создать пользователя на сервере NUT (в uspd.users) с именем «admin» и паролем «secret». Я безуспешно пытался подключить Synology к серверу NUT, используя менее очевидное имя пользователя и сложный пароль, но безрезультатно.
Замените звездочки на ваши пароли.
nano /etc/nut/upsmon.conf
RUN_AS_USER root MONITOR ups@localhost 1 upsadmin ******* master MINSUPPLIES 1 SHUTDOWNCMD "/sbin/shutdown -h now" NOTIFYCMD /usr/sbin/upssched POLLFREQ 4 POLLFREQALERT 2 HOSTSYNC 15 DEADTIME 24 MAXAGE 24 POWERDOWNFLAG /etc/killpower NOTIFYMSG ONLINE "UPS %s on line power" NOTIFYMSG ONBATT "UPS %s on battery" NOTIFYMSG LOWBATT "UPS %s battary is low" NOTIFYMSG FSD "UPS %s: forced shutdown in progress" NOTIFYMSG COMMOK "Communications with UPS %s established" NOTIFYMSG COMMBAD "Communications with UPS %s lost" NOTIFYMSG SHUTDOWN "Auto logout and shutdown proceeding" NOTIFYMSG REPLBATT "UPS %s battery needs to be replaced" NOTIFYMSG NOCOMM "UPS %s is unavailable" NOTIFYMSG NOPARENT "upsmon parent process died - shutdown impossible" 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 NOTIFYFLAG NOCOMM SYSLOG+WALL+EXEC NOTIFYFLAG NOPARENT SYSLOG+WALL RBWARNTIME 43200 NOCOMMWARNTIME 600 FINALDELAY 5
Не забудьте заменить звездочки на ваш пароль администратора во второй строчке.
nano /etc/nut/upssched.conf
CMDSCRIPT /bin/upssched-cmd PIPEFN /etc/nut/upssched.pipe LOCKFN /etc/nut/upssched.lock AT ONBATT * START-TIMER shutdown_proxmox 100 AT ONLINE * CANCEL-TIMER shutdown_proxmox online AT LOWBATT * EXECUTE shutdown_proxmox AT COMMBAD * START-TIMER commbad 30 AT COMMOK * CANCEL-TIMER commbad commok AT NOCOMM * EXECUTE commbad AT SHUTDOWN * EXECUTE shutdown_proxmox
START-TIMER shutdown_proxmox 120
— запускает таймер на 2 минуты для выключения Proxmox после перехода на батарею.CANCEL-TIMER shutdown_proxmox online
— отменяет таймер, если питание восстановилось до истечения времени.EXECUTE shutdown_proxmox
— немедленно выполняет выключение при критическом уровне заряда батареи или других событиях.
Как это будет работать?
- Переход на батарею:
- Когда ИБП переходит на батарею (
ONBATT
), запускается таймер на 2 минуты. - Если за это время питание не восстановится, через 2 минуты выполнится команда
shutdown_proxmox
. - Восстановление питания:
- Критический уровень батареи:
- Потеря связи с ИБП:
Нужно убедиться, что PIPEFN и LOCKFN указывают на существующую директорию. У меня ее не было, поэтому я ее создал.
mkdir /etc/nut/upssched/
nano /bin/upssched-cmd
#!/bin/bash case $1 in shutdown_proxmox) logger -t upssched-cmd "UPS on battery too long — shutting down Proxmox" /sbin/shutdown -h now ;; *) logger -t upssched-cmd "Unknown command from upssched: $1" ;; esac
При получении командыshutdown_proxmox
система логгирует сообщение и выполняет выключение командой/sbin/shutdown -h now
.
Сохраняем, затем предоставляем права:
chmod +x /bin/upssched-cmd
Осталось перезагрузить систему, или, если нет такой возможности, перезагрузить сервисы командами:
systemctl restart nut-server systemctl restart nut-client systemctl restart nut-monitor upsdrvctl stop upsdrvctl start
После перезагрузки выполняем команду:
upsc ups@localhost
и смотрим, показана ли информация о нашем ИБП:
Проверяем, какие значения мы можем записывать
upscmd -l ups@localhost
В моем ИБП не оказалось возможности аппаратно записать значения минимального времени работы (200 секунд) и заряда (50%), но оставлю эти команды тут:
upsrw -s battery.runtime.low=200 ups@localhost upsrw -s battery.charge.low=50 ups@localhost
После ввода каждой команды будет запрошен логин и пароль, используйте логин upsadmin и пароль, который вы указывали при редактировании /etc/nut/upsmon.conf и /etc/nut/upsd.users. После ввода команд система будет возвращать ОК, даже если изменения нельзя записать.
Перезагружаем сервисы/сервер.
Эти команды не настраивают автоматическое отключение хоста, а задаются критические значения для самого ИБП.
Так же, я заметил, что на моем ИБП нет возможности изменить параметр battery.charge.low. Рекомендую проверить изменения предыдущей командой, которая выводит ваши значения по ИБП.
Однако, можно программно записать значения в ups.conf
, добавив мониторинг нагрузки через override:
nano /etc/nut/ups.conf
override.battery.charge.low = 50 override.battery.runtime.low = 200
Тогда содержимое ups.conf
будет выглядеть так:
pollinterval = 15 maxretry = 3 offdelay = 300 ondelay = 30 [ups] driver = usbhid-ups port = auto desc = "CyberPower UT850EG" vendorid = 0764 productid = 0501 serial = "" override.battery.charge.low = 50 override.battery.runtime.low = 200
После внесения изменений проверяем той же командой:
upsc ups@localhost
И видим, что конфиг применился.
Как это вообще все работает?
Да я сам не сразу понял.
Порядок приоритетов работы системы:
1. Сначала проверяются override параметры:
2. Потом срабатывают таймеры из upssched.conf:
3. В конце учитываются временные задержки:
Рекомендации по согласованию значений:
- override.battery.runtime.low ≤ offdelay
- таймер в AT ONBATT ≤ override.battery.runtime.low
- override.battery.charge.low < override.battery.runtime.low
Создание и настройка LXC контейнера для мониторинга ИБП
В принципе, на стороне сервера уже все настроено и сервер будет отключаться в соответствии с настройками NUT, но для удобства можно настроить веб страничку с данными об ИБП. Я это сделал в отдельном LXC контейнере.
Характеристики: 1 ядро, 128мб ОЗУ, 2гб диск, ubuntu 24.04, автозапуск контейнера при загрузке.
Первым делом, после запуска контейнера, заходим в его консоль и выполняем обновление:
apt update && apt upgrade -y
apt install openssh-server -y
nano /etc/ssh/sshd_config
Нужно раскомментировать или добавить следующие строчки:
PasswordAuthentication yes PermitRootLogin yes
Сохраняем и перезапускаем openssh сервер:
systemctl restart ssh
Установим веб-сервер Apache, nut-cgi и nut клиент:
apt install apache2 nut-cgi nut-client -y
Сразу сделаем резервные копии всех редактируемых конфигов:
cp /etc/nut/nut.conf /etc/nut/nut.example.conf cp /etc/nut/hosts.conf /etc/nut/hosts.example.conf cp /etc/nut/upsset.conf /etc/nut/upsset.example.conf cp /etc/nut/upsmon.conf /etc/nut/upsmon.example.conf
Редактируем /etc/nut/nut.conf:
nano /etc/nut/nut.conf
MODE=netclient
Далее редактируем /etc/nut/hosts.conf:
nano /etc/nut/hosts.conf
MONITOR ups@xxx.xxx.xxx.xxx "CyberPower UT850IEG"
где xxx.xxx.xxx.xxx это ip адрес вашего сервера Proxmox
Редактируем/etc/nut/upsset.conf:
nano /etc/nut/upsset.conf
I_HAVE_SECURED_MY_CGI_DIRECTORY
Редактируем /etc/nut/upsmon.conf:
nano /etc/nut/upsmon.conf
RUN_AS_USER root MONITOR ups@xxx.xxx.xxx.xxx 1 upsuser ******* slave
где xxx.xxx.xxx.xxx это ip адрес вашего сервера Proxmox, а ******** это пароль юзера upsuser, настроенного на сервере с proxmox.
sudo a2enmod cgi
sudo systemctl restart apache2
Теперь можно перейти по адресу http://xxx.xxx.xxx.xxx/cgi-bin/nut/upsstats.cgi где xxx.xxx.xxx.xxx это ip вашего lxc контейнера и мониторить статус ИБП. В моем случае это выглядит так:
Добавление ИБП в Synology
Чтобы все работало, нужно настроить Synology с помощью IP-адреса сервера NUT.
1. Включить функцию UPS support.
2. Выбрать Тип ИБП
- Сервер ИБП Synology.
3. Настроить время - совет, ниже, чем на самом хосте.
Указать IP адрес вашего Proxmox.
Напоминаю, что также необходимо было настроить файл ups.conf на сервере NUT, чтобы ИБП назывался «ups». Он не может называться как-то иначе. В противном случае Synology откажется подключаться.
Вам также нужно было создать пользователя на сервере NUT (в uspd.users) с именем «admin» и паролем «secret». Я безуспешно пытался подключить Synology к серверу NUT, используя менее очевидное имя пользователя и сложный пароль, но безрезультатно.
Это не такая серьёзная проблема с точки зрения безопасности, как может показаться, поскольку пользователь «admin» имеет доступ к ИБП только для чтения. Я подтвердил это с помощью:
upscmd -l ups@localhost
Очевидно, что мы не хотим, чтобы любой злоумышленник в сети L3 мог отключить ИБП с помощью простых учётных данных.
upscmd -u admin -p secret ups@localhost shutdown.stayoff
Созданная выше учётная запись суперпользователя может выполнять все эти опасные команды, но встроенная учётная запись Synology не может.
Благодаря подписчику переработал конфиги и скрипт, а так же протестировал их работу.
Тестируем аварийное отключение
В самом DSM я выставил таймер на 40 секунд, а для Proxmox 120.
В первом тесте ИБП был без питания 26 секунд. Все системы продолжили работу.
Во втором тесте ИБП был без питания 86 секунд. DSM самостоятельно завершил работу и возобновил после подачи питания. Proxmox при этом считал 120 секунд и продолжил работу.
Третьим тестом будет полное отключение Proxmox спустя 120 секунд
По итогам тестов я выяснил, что аккумулятор в ИБП разряжается до критического состояния с заданными ему максимальными значениями, поэтому занизил их, так как для меня нет необходимости тащить систему на резервном питании, дожидаясь восстановления.
ИБП все же не продовый, а скорее для домашнего использования, чем и является мой хост.
Основной приоритет - безопасное завершение работы.
В 04:32:55 было отключение электричества
В 04:34:25 прошло 90 секунд и proxmox начал останавливать все процессы
В 04:38:41 все процессы были остановлены и система была отключена
Мои финальные параметры в конфигах с таймерами остались такими:
override.battery.runtime.low = 120 override.battery.charge.low = 30 AT ONBATT * START-TIMER shutdown_proxmox 90 offdelay = 300
А что получилось у вас? Делитесь в комментариях.