ESXi и apcupsd

В маленьких инсталляциях VMware, которые располагаются не в ЦОД, а в своих серверных, где питание хостов реализовано через UPS, нужно контролировать работу этих самых UPS, чтобы в случае пропадания питания и разряда батареи виртуальные машины выключились корректно.

В данной статья рассматривается UPS от компании APC.

Для решения этой задачи есть несколько вариантов:

  • Использовать ПО производителя - PowerChute, установить агенты в ВМ;
  • Использовать виртуальную машину vMA;
  • Использовать apcupsd и свой скрипт остановки ВМ;

Я выбрал последний вариант, как самый простой и легковесный.

И так нам понадобится любая ВМ с Linux для установки apcupsd, у меня это машина с ZABBIX.

К этой машине нужно подключить UPS, сделать это как минимум двумя способами:

  • по локальной сети, если UPS оборудован Network Management Card, стоит она приличных денег, но вообще штука полезная, можно запускать тесты UPS по шедулеру, снимать метрики для мониторинга, проводить калибровку АКБ.
  • по USB, тут есть особенность проброски этого USB устройства в гостевую ВМ.

Т.к. менеджмент платы у мня не было, то был выбран вариант с USB, нужно подключить UPS в нужных хост ESXi, на него нужно смигрировать виртуальную машину, к которой будем пробрасывать устройство. При добавлении устройства обязательно ставим галочку "Enable vMotion", что позволит потом мигрировать эту машину на другой хост, при этом устройство останется подключенным, магия да? ;-)

В настройках это будет отображено так:

Установка apcupsd

Тут все просто:

# yum install apcupsd

Правим конфиг /etc/apcupsd/apcupsd.conf по своему усмотрению, у меня такой:


UPSCABLE usb
UPSTYPE usb
DEVICE
LOCKFILE /var/lock
SCRIPTDIR /etc/apcupsd
PWRFAILDIR /etc/apcupsd
NOLOGINDIR /etc
ONBATTERYDELAY 6
BATTERYLEVEL 5
MINUTES 7
TIMEOUT 0
ANNOY 300
ANNOYDELAY 60
NOLOGON disable
KILLDELAY 0
NETSERVER on
NISIP 0.0.0.0
NISPORT 3551
EVENTSFILE /var/log/apcupsd.events
EVENTSFILEMAX 10
UPSCLASS standalone
UPSMODE disable
STATTIME 300
STATFILE /var/log/apcupsd.status
LOGSTATS off
DATATIME 0


Тут есть два интересных параметра:

MINUTES 7 - Говорит о том, что когда UPS перейдет на работу от батарей и при текущей нагрузке он сообщает, сколько еще сможет протянуть и вот когда остается 7 минут, то начинаем выключение. Тут нужно учитывать, что когда машины будут выключаться или "засыпать" нагрузка увеличится и 7 минут могут легко превратиться в 4 например.

TIMEOUT 0 - альтернативный вариант настройки, если тут указать таймаут в секундах, то после этого времени он будет произведено выключение, если указано 0, то такое поведение отключено.

Запускаем сервис и добавляем в автозагрузку:

# service apcupsd start
# chkconfig apcupsd on

Вот так можно проверить, что все работает:

[root@srv-zabbix-01 /]#  cat /var/log/apcupsd.status
APC      : 001,027,0691
DATE     : 2018-08-23 13:41:31 +0300
HOSTNAME : srv-zabbix-01.psf.local
VERSION  : 3.14.14 (31 May 2016) redhat
UPSNAME  : srv-zabbix-01.psf.local
CABLE    : USB Cable
DRIVER   : USB UPS Driver
UPSMODE  : Stand Alone
STARTTIME: 2018-08-23 09:22:30 +0300
MODEL    : Smart-UPS C 1500
STATUS   : ONLINE
BCHARGE  : 100.0 Percent
TIMELEFT : 65.0 Minutes
MBATTCHG : 5 Percent
MINTIMEL : 7 Minutes
MAXTIME  : 0 Seconds
ALARMDEL : No alarm
BATTV    : 27.3 Volts
NUMXFERS : 0
TONBATT  : 0 Seconds
CUMONBATT: 0 Seconds
XOFFBATT : N/A
STATFLAG : 0x05000008
MANDATE  : 2017-06-15
SERIALNO : AS1724341480
NOMBATTV : 24.0 Volts
FIRMWARE : UPS 10.0 / ID=1005
END APC  : 2018-08-23 13:41:31 +0300

Генерация ключа для подключения к ESXi

Сгенерируйте ключ, если не делали это ранее:

# ssh-keygen

переходим в каталог

# cd .ssh/

и копируем ключ на ESXi хост, да ssh-copy-id тут не сработает, поэтому так:

#  cat id_rsa.pub | ssh root@srv-esx-01 'cat >>/etc/ssh/keys-root/authorized_keys'

Эту операцию проводим со всеми хостами. Теперь можем ходить на хосты ESXi по SSH без пароля.

Скрипт завершения работы

Сделамем скрипт для завершения работы VM

#!/bin/sh
vms=('srv-ts-01' 'srv-ts-02' 'srv-sql-01' 'srv-fs-01' 'srv-adds-02' 'srv-veeam-01' 'srv-vcsa-01' 'srv-adds-01' 'srv-web-01' 'srv-gw-01')
hosts=('srv-esx-01' 'srv-esx-02' 'srv-esx-03')

for vm in ${vms[@]}
do
    for host in ${hosts[@]}
    do
        id=`ssh root@$host -C "vim-cmd vmsvc/getallvms" | grep "$vm\s" | awk '{print $1}'`
        if [ "$id" != "" ]
            then
            ssh root@$host -C "vim-cmd vmsvc/power.suspend $id"
        fi
    done
done
poweroff

У меня это /opt/vm-shutdown.sh, его нужно сделать исполняемым:

chmod +x /opt/vm-shutdown.sh

В списке vms, перечисляются ВМ которые необходимо выключить, а в списке hosts соответственно хосты. В моем случае машины "уснут", но можно поменять команду на power.shutdown вместо power.suspend и тогда они просто завершат работу. Выключение ВМ будет выполняться в том порядке, в котором вы их пропишите в этом списке. Последняя команда в скрипте poweroff, выключит саму машину где установлен apcupsd.

При желании, так же можно добавить команды для выключения хостов ESXi, то-то вроде:

ssh root@srv-esx-01 -C "poweroff"

Конечно это нужно вставить вместо poweroff и сделать так для каждого хоста.

Теперь нужно в файле /etc/apcupsd/apccontrol

заменить переменную вот так:

SHUTDOWN=/opt/vm-shutdown.sh

После чего перезапустить сервис apcupsd.


Мониторинг UPS в ZABBIX

Для мониторингда ИБП можно использовать следующий шаблон:

https://share.zabbix.com/power-ups/apc/apcupsd

Инструкция там же.

Все, теперь при отключении питания мы будем проинформированны сервером ZABBIX и когда АБК в ИБП разрядится, ВМ коректно завершат работу или уснут.