ADG Оставить заявку
Блог Автоматизация 5 мин чтения

ИБП и автовыключение: сервер, который успевает закрыть файлы

После двух жёстких падений серверов настраиваем автоматическое корректное завершение работы при разряде ИБП. Разбираем apcupsd, NUT и что реально важно настроить.

Контекст момента

рост числа серверов делает мониторинг ИБП и автовыключение критичным

Второй раз - это уже не случайность, это система. Первый раз сервер упал жёстко полгода назад: свет дали и забрали снова минут через восемь, ИБП не успел зарядиться, следующее отключение он не удержал. Мы тогда сделали fsck, подняли базу, вынесли урок про состояние батарей и двинулись дальше. Второй раз случился в августе: батарея новая, ИБП нормальный, но он просто кончился - два часа без света, аккумулятор разрядился, сервер вырубился как по выключателю, и почтовая очередь оказалась в интересном состоянии.

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

Что происходит при жёстком отключении. Операционная система в любой момент держит кучу всего в памяти, что ещё не записано на диск: кеш файловой системы, журналы, открытые транзакции баз данных, почтовые очереди. При корректном завершении работы всё это сбрасывается по порядку: демоны останавливаются, транзакции закрываются, буферы пишутся. При жёстком отключении этого не происходит. При следующей загрузке файловая система идёт через fsck, база данных поднимается с точки последнего чекпоинта или вообще отказывается стартовать, почта восстанавливается как получится. Иногда всё нормально, иногда нет. Угадать нельзя.

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

Как устроена связка. ИБП подключается к серверу либо по последовательному порту (COM), либо по USB - зависит от модели. Сигнальный кабель - не тот, что несёт питание, а отдельный тонкий, который идёт в комплекте с ИБП. На сервере стоит демон, который этот порт опрашивает, читает статус батареи и напряжения, и при необходимости инициирует shutdown. На Linux это чаще всего apcupsd (для APC) или NUT - Network UPS Tools, который работает с большинством других производителей.

У нас стоит APC Back-UPS Pro, так что берём apcupsd. Ставится пакетом, конфиг один файл - /etc/apcupsd/apcupsd.conf. Ключевые параметры, которые надо выставить вручную, а не оставлять дефолт:

  • UPSTYPE и DEVICE - тип подключения и порт. Для COM-порта это обычно apcsmart и /dev/ttyS0, для USB - usb и пустое DEVICE (демон находит сам).
  • BATTERYLEVEL - при каком проценте заряда батареи начинать shutdown. Дефолт 5% - это почти ничего. Мы ставим 30-40%, чтобы у системы оставался запас на само завершение.
  • MINUTES - при каком расчётном времени автономной работы начинать shutdown. Здесь надо знать, сколько реально занимает остановка всех служб на конкретном сервере. Почтовый сервер с большой очередью может гасить несколько минут. Ставим 5-7 минут с запасом.
  • TIMEOUT - если оба предыдущих условия не сработали, через сколько секунд работы от батареи всё равно начать выключение. Это страховка.

После настройки - обязательно тест. Не «посмотрим при следующем отключении», а реальный тест: вытаскиваем вилку ИБП из розетки и смотрим, что происходит. Демон должен записать события в лог, и при достижении порогов - инициировать shutdown. Если shutdown не произошёл - что-то не так с конфигом или кабелем.

Отдельно про несколько серверов. У нас парк вырос, и один ИБП часто держит два-три сервера. Проблема: ИБП один, порт для демона тоже один - значит, только один сервер получает прямой сигнал. Остальные должны узнать о разрядке другим способом.

Для этого в apcupsd есть сетевой режим: мастер-сервер слушает на порту 3551, остальные серверы запускают apcupsd в режиме slave и опрашивают мастера по сети. Когда мастер начинает выключаться, он рассылает сигнал всем слейвам. Слейвы начинают своё завершение работы. Принципиально важно, чтобы слейвы стартовали shutdown чуть раньше мастера - иначе мастер уже выключился, а слейвы ещё ждут его команды. Это настраивается параметром NETTIME.

Альтернатива - NUT, который с самого начала проектировался для сети и работает чище именно в схеме «один ИБП, много серверов». Мы его пробовали на Linux-машинах и он понравился больше по архитектуре, но apcupsd проще в начальной настройке, если у вас APC и один сервер.

Что даёт корректное завершение. Это не героизм и не паранойя. Это просто разница между «сервер упал, подняли, работаем» и «сервер упал, три часа восстанавливаем базу, потеряли часть данных, клиент нервничает». Мы про это писали ещё в 2000-м, но тогда разговор был про буфер питания. Буфер питания без автовыключения - это ещё не защита данных, это просто отсрочка катастрофы. Защита данных начинается там, где сервер знает, что свет кончается, и успевает всё закрыть сам.

После августа мы прошлись по всем объектам на сопровождении и проверили, где настроено автовыключение, а где нет. Оказалось, что примерно в трети случаев ИБП стоит, кабель есть, но демон или не установлен, или конфиг не тронут после установки. Это работа на полчаса - но именно эти полчаса стоят между корректным выключением и жёстким падением.

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

Контакт

Нужна такая же инженерная работа?

Опишите задачу и контекст. Ответим в течение рабочего дня, при необходимости подпишем NDA.