Как настроить центральный менеджмент сервер для ИБП?
Цель и необходимость
Как только у Вас появился сервер, то сразу появляется вопрос в его поддержке. Один из основных вопросов связан с бесперебойной поставкой электричества к серверу. С этим вопросом помогает UPS (далее ИПБ), но есть проблема со штатным выключением сервера, так как в случае продолжительного отключения электричества вместе с ИПБ выключается и сервер (не в штатном режиме). В этом случае существует вероятность потери данных, сбоях в работе ОС и программ. Для решения этого вопроса будем использовать NUT + автоматизации.
Network UPS Tools (NUT) - это набор программных компонентов, предназначенный для мониторинга питания, таких как бесперебойные источники питания, блоки распределения питания, солнечные контроллеры и блоки питания серверов.
Модели ИПБ
Поддерживаемые модели устройств в NUT можно увидеть тут. Нашел бюджетный вариант в списке и в магазине (ИБП DEXP MIX 850VA).
Proxmox
Отключаем от USB ИПБ и выполняем:
lsusb
Подключаем ИПБ по USB и потом снова выполняем:
lsusb
. Таким образом, видим новое устройство. В моем случае этоFry's Electronics
(неожиданно :)):
Bus 006 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 005 Device 002: ID 1d6b:0104 Linux Foundation Multifunction Composite Gadget
Bus 005 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 003: ID 0001:0000 Fry's Electronics
Bus 001 Device 002: ID 0a12:0001 Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode)
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Смотрим детальную информацию, указав
bus
иdevice
, и выполнивlsusb -v -s 1:3
:
Bus 001 Device 003: ID 0001:0000 Fry's Electronics
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 0
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x0001 Fry's Electronics
idProduct 0x0000
bcdDevice 1.00
iManufacturer 0
iProduct 1
iSerial 0
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 0x0029
bNumInterfaces 1
bConfigurationValue 1
iConfiguration 0
bmAttributes 0x80
(Bus Powered)
MaxPower 100mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 3 Human Interface Device
bInterfaceSubClass 1 Boot Interface Subclass
bInterfaceProtocol 0
iInterface 0
HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.11
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 Report
wDescriptorLength 624
Report Descriptors:
** UNAVAILABLE **
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0008 1x 8 bytes
bInterval 10
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x02 EP 2 OUT
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0008 1x 8 bytes
bInterval 10
Device Status: 0x0000
(Bus Powered)
Устанавливаем
nut
:apt install nut -y
.Проверяем видит ли
nut
наш ИПБ, выполняемnut-scanner -U
:
Scanning USB bus.
[nutdev1]
driver = "nutdrv_qx"
port = "auto"
vendorid = "0001"
productid = "0000"
bus = "001"
Делаем backup конфигов
nut
:
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 /etc/nut/upssched-cmd /etc/nut/upssched-cmd.example
Редактриуем
/etc/nut/nut.conf
, удаляем все и добавляем черезnano /etc/nut/nut.conf
:
MODE=netserver
Редактируем
ups.conf
, удаляем все и добавляем черезnano /etc/nut/ups.conf
:
pollinterval = 15
maxretry = 3
offdelay = 120
ondelay = 240
[dexp]
driver=blazer_usb
port=auto
desc="DEXP MIX 850VA"
vendorid=0001
productid=0000
default.battery.voltage.high=2.27
default.battery.voltage.low=1.72
runtimecal=240,100,720,50
chargetime=43200
idleload=1%
langid_fix=0x0409
и выполняем upsdrvctl stop && upsdrvctl start
:
Network UPS Tools - UPS driver controller 2.8.0
Network UPS Tools - UPS driver controller 2.8.0
Network UPS Tools - Megatec/Q1 protocol USB driver 0.14 (2.8.0)
Please note that this driver is deprecated and will not receive
new development. If it works for managing your devices - fine,
but if you are running it to try setting up a new device, please
consider the newer nutdrv_qx instead, which should handle all 'Qx'
protocol variants for NUT. (Please also report if your device works
with this driver, but nutdrv_qx would not actually support it with
any subdriver!)
Supported UPS detected with megatec protocol
Vendor information read in 1 tries
Проверяем работу /lib/nut/blazer_usb -DDD -a dexp
:
Network UPS Tools - Megatec/Q1 protocol USB driver 0.14 (2.8.0)
0.000000 [D3] do_global_args: var='pollinterval' val='15'
0.000014 [D3] do_global_args: var='maxretry' val='3'
0.000019 [D3] do_global_args: var='offdelay' val='120'
0.000024 [D3] do_global_args: var='ondelay' val='240'
0.000031 [D3] main_arg: var='desc' val='dexp'
0.000036 [D3] main_arg: var='port' val='auto'
0.000044 [D3] main_arg: var='driver' val='blazer_usb'
0.000053 [D3] main_arg: var='default.battery.voltage.high' val='2.27'
0.000060 [D3] main_arg: var='default.battery.voltage.low' val='1.72'
0.000067 [D3] main_arg: var='runtimecal' val='240,100,720,50'
0.000075 [D3] main_arg: var='langid_fix' val='0x0409'
0.000082 [D3] main_arg: var='vendorid' val='0001'
0.000090 [D3] main_arg: var='productid' val='0000'
0.000097 [D3] main_arg: var='chargetime' val='43200'
0.000105 [D3] main_arg: var='idleload' val='1%'
0.000115 [D1] debug level is '3'
0.000956 [D2] language ID workaround enabled (using '0x409')
0.004633 [D2] Checking device 1 of 7 (1D6B/0003)
0.004656 [D1] Failed to open device (1D6B/0003), skipping: Access denied (insufficient permissions)
0.004663 [D2] Checking device 2 of 7 (1D6B/0104)
0.004672 [D1] Failed to open device (1D6B/0104), skipping: Access denied (insufficient permissions)
0.004678 [D2] Checking device 3 of 7 (1D6B/0002)
0.004687 [D1] Failed to open device (1D6B/0002), skipping: Access denied (insufficient permissions)
0.004692 [D2] Checking device 4 of 7 (1D6B/0003)
0.004700 [D1] Failed to open device (1D6B/0003), skipping: Access denied (insufficient permissions)
0.004705 [D2] Checking device 5 of 7 (0001/0000)
0.006938 [D1] nut_libusb_open get iProduct failed, retrying...
0.010937 [D1] nut_libusb_open get iProduct failed, retrying...
0.014932 [D1] nut_libusb_open get iProduct failed, retrying...
0.014939 [D2] - VendorID: 0001
0.014944 [D2] - ProductID: 0000
0.014949 [D2] - Manufacturer: unknown
0.014955 [D2] - Product: unknown
0.014960 [D2] - Serial Number: unknown
0.014965 [D2] - Bus: 001
0.014970 [D2] - Device: unknown
0.014976 [D2] - Device release number: 0100
0.014981 [D2] Trying to match device
0.014986 [D3] match_function_regex: matching a device...
0.015021 [D2] Device matches
0.015026 [D2] Reading first configuration descriptor
0.015034 [D3] libusb_kernel_driver_active() returned 0
0.015051 [D2] Claimed interface 0 successfully
0.015055 [D3] nut_usb_set_altinterface: skipped libusb_set_interface_alt_setting(udev, 0, 0)
0.018941 Please note that this driver is deprecated and will not receive
new development. If it works for managing your devices - fine,
but if you are running it to try setting up a new device, please
consider the newer nutdrv_qx instead, which should handle all 'Qx'
protocol variants for NUT. (Please also report if your device works
with this driver, but nutdrv_qx would not actually support it with
any subdriver!)
0.018955 [D2] Trying megatec protocol...
0.018963 [D3] send: Q1
0.023956 [D1] received 96 (96)
0.023963 [D3] read: (228.0 000.0 228.0 020 50.1 13.5 29.0 00001000
0.023987 [D2] Status read in 1 tries
0.023993 Supported UPS detected with megatec protocol
0.023998 [D3] send: F
0.027950 [D1] received 46 (46)
0.027957 [D3] read: # . . 12.00 .
0.027967 [D2] Ratings read in 1 tries
0.027972 [D3] send: I
0.032940 [D1] received 80 (80)
0.032948 [D3] read: # V3.8
0.032956 Vendor information read in 1 tries
0.032969 [D2] battery runtime exponent : 1.585
0.032977 [D2] battery runtime nominal : 240.0
0.032981 [D2] battery runtime estimate : 240.0
0.032986 [D2] battery charge time : 43200
0.032992 [D2] minimum load used (idle) : 0.010
0.032999 [D3] send: Q1
0.037961 [D1] received 96 (96)
0.037969 [D3] read: (228.0 000.0 228.0 020 50.1 13.5 29.0 00001000
0.038021 [D2] dstate_init: sock /run/nut/blazer_usb-dexp open on fd 9
0.038033 [D3] send: Q1
0.042937 [D1] received 96 (96)
0.042943 [D3] read: (228.0 000.0 228.0 020 50.1 13.5 29.0 00001000
15.047969 [D3] send: Q1
15.051805 [D1] received 96 (96)
15.051815 [D3] read: (228.0 000.0 228.0 021 50.3 13.5 29.0 00001000
30.056076 [D3] send: Q1
30.059683 [D1] received 96 (96)
30.059692 [D3] read: (228.0 000.0 229.0 020 49.9 13.5 29.0 00001000
Редактируем
upsd.conf
черезnano /etc/nut/upsd.conf
и вставляем:
LISTEN 0.0.0.0 3493
LISTEN :: 3493
Теперь сервер может отвечать на запросы из всех сетей.
Редактируем
upsd.users
через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
********
- заменяем на наши пароли.
Редактируем
upsmon.conf
черезnano /etc/nut/upsmon.conf
. Удаляем все и вставляем:
RUN_AS_USER root
MONITOR apc@localhost 1 upsadmin ******* master
MINSUPPLIES 1
SHUTDOWNCMD "/sbin/shutdown -h"
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
*******
- заменяем на пароль upsadmin
.
Перезагружаем сервисы:
service nut-server restart
service nut-client restart
systemctl restart nut-monitor
upsdrvctl stop
upsdrvctl start
Тестируем соединение
upsc dexp@localhost
:
Init SSL without certificate database
battery.charge: 100
battery.runtime: 2645
battery.voltage: 13.60
battery.voltage.high: 2.27
battery.voltage.low: 1.72
battery.voltage.nominal: 12.0
device.mfr:
device.model:
device.type: ups
driver.name: blazer_usb
driver.parameter.chargetime: 43200
driver.parameter.idleload: 1%
driver.parameter.langid_fix: 0x0409
driver.parameter.pollinterval: 15
driver.parameter.port: auto
driver.parameter.productid: 0000
driver.parameter.runtimecal: 240,100,720,50
driver.parameter.synchronous: auto
driver.parameter.vendorid: 0001
driver.version: 2.8.0
driver.version.internal: 0.14
driver.version.usb: libusb-1.0.26 (API: 0x1000109)
input.current.nominal: 0.0
input.frequency: 49.9
input.frequency.nominal: 0
input.voltage: 229.0
input.voltage.fault: 0.0
input.voltage.nominal: 0
output.voltage: 228.0
ups.beeper.status: disabled
ups.delay.shutdown: 30
ups.delay.start: 180
ups.firmware: V3.8
ups.load: 22
ups.mfr:
ups.model:
ups.productid: 0000
ups.status: OL
ups.temperature: 29.0
ups.type: offline / line interactive
ups.vendorid: 0001
Значение ups.status
:
OL — система работает от сети;
OB — система работает от батареи;
LB — система работает от разряженной батареи.
Смотрим какие команды доступны upscmd -l dexp@localhost
:
Instant commands supported on UPS [dexp]:
beeper.toggle - Toggle the UPS beeper
load.off - Turn off the load immediately
load.on - Turn on the load immediately
shutdown.return - Turn off the load and return when power is back
shutdown.stayoff - Turn off the load and remain off
shutdown.stop - Stop a shutdown in progress
test.battery.start - Start a battery test
test.battery.start.deep - Start a deep battery test
test.battery.start.quick - Start a quick battery test
test.battery.stop - Stop the battery test
Значение:
beeper.* - управляют сигналом ИБП в случае потери напряжения в сети
load.off - выключает ПК немедленно;
load.off.delay - задержка в секундах до выключения ПК;
shutdown.stop — команда прерывания процесса отключения ПК.
Для примера выключим сигнал ИБП, когда пропадает питание в сети:
upscmd -u upsmonitor -p UPSPASS dexp@localhost beeper.disable
Чтобы включить, заменяем beeper.disable на beeper.enable.
Для отключения самого сервера Proxmox нам потребуется новый пользователь, который имеет ограниченный набор прав. Создадим его :)
Создаем роль homeassistant
с правами auditor
:
Создаем пользователя:
Чтобы добавить возможность управления питанием нам необходимо создать роль с правами Sys.PowerMgmt
:
Пользователя с необходимыми правами мы создали, но мы хотим заходить на сервер как машина, а не как пользователь. Для такого поведения создадим токен для пользователя:
Homeassistant
Для мониторинга используем Homeaasistant, в частности устанавливаем интеграцию Network UPS Tools (NUT).
Здесь интересен объект «Dexp Заряд аккумулятора» (sensor.dexp_battery_charge), так как показывает на сколько % заряжен аккумулятор. По моим тестам ИПБ выключается при уровне 27%, поэтому для себя выделил границу 40%, ниже которой стоит отключать сервер.
Для выключения Proxmox в файл configuration.yaml
добавляем следующий код:
shell_command:
shutdown_proxmox: "curl 'https://<IP>:8006/api2/extjs/nodes/proxmox/status' -H 'Authorization: PVEAPIToken=<user>!<token_id>=<token>' -H 'Content-Type: application/x-www-form-urlencoded' --data 'command=shutdown' --insecure"
где:
IP
- ip-адрес Proxmox.user
- пользователь, под которым будут выполняться команды, например,homeassistant@pve
.token_id
- id товена, например,homeassistant
.token
- значение нашего токена. Проверяем конфигурацию на наличие ошибок и исправляем их. Затем перезагружаем Homeassistant. Если всё верно сделали, то в разделеDeveloper mode
, в сервисах можно будет найти новый элемент:shell_command.shutdown_proxmox
.
Автоматизацию делаем следующим образом:
alias: server_turn_off
description: Выключение сервера, если заряд батареи опускается ниже x%
triggers:
- type: battery_level
device_id: afc1912c3576ace3ede796bc926d635c
entity_id: 2579f34021ac5593a876c6915131e7cb
domain: sensor
trigger: device
below: 40
conditions: []
actions:
- action: shell_command.shutdown_proxmox
metadata: {}
data: {}
mode: single
Если коротко, то в случае снижения заряда батареи ниже 40% отправляем команду в Proxmox для выключения.
Автовключение
Для автоматизации включения ПК при появлении питания в сети включаем в BIOS данную функцию. У меня эта функция находится тут:
Итог
В итоге в случае отключения электричества наш сервер в рабочем порядке корректно завершит свою работу и выключится + всегда возможно ключить автовключение. Работу ИПБ мы также можем проконтролировать с помощью dashboard в Homeassistant.
Ссылки: