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

Event-Driven Ansible в бою: Zabbix-алерт расширяет LVM без дежурного

Внедряем EDA у клиента: алерт о заполнении диска в Zabbix автоматически запускает плейбук расширения LVM. Разбираем, где споткнулись и что получилось.

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

Event-Driven Ansible достиг GA в составе Ansible Automation Platform 2.3, август 2023

Три недели назад мы писали про AAP 2.3 и первые эксперименты с Event-Driven Ansible - запустили связку EDA + Zabbix + AWX на одном клиенте в режиме «параллельно с дежурным». С тех пор в этой схеме появился первый боевой сценарий, который мы считаем полноценно закрытым: автоматическое расширение LVM при деградации дискового пространства.

Пост - честный разбор того, как это делалось, где спотыкались и в каком состоянии всё находится сейчас.

Почему именно диски

У клиента - несколько десятков Linux-серверов на управляемой инфраструктуре. Zabbix мониторит заполнение файловых систем стандартным шаблоном. Когда утилизация пересекает порог, прилетает алерт, который раньше уходил дежурному инженеру. Дежурный смотрел ситуацию, оценивал, запускал плейбук расширения LVM за счёт свободного места в volume group, проверял результат. Вся операция - от алерта до закрытия - занимала в среднем 40 минут в рабочее время и дольше ночью.

Сценарий идеален для автоматизации: детерминированный, безопасный при правильно написанном плейбуке, и при этом точечно убирает нагрузку с людей в неудобное время. Кроме того, у нас уже был проверенный плейбук расширения - оставалось только правильно его запустить.

Структура rulebook

Основная механика - та же, что описана в посте про AAP 2.3: Zabbix отправляет webhook, EDA его разбирает, при совпадении условия запускает job template в AWX Controller.

Rulebook для этого сценария:

sources:
  - ansible.eda.webhook:
      host: 0.0.0.0
      port: 5001

rules:
  - name: LVM expand on disk warning
    condition: >
      event.payload.trigger.status == "PROBLEM" and
      event.payload.trigger.name is match(".*disk.*space.*", ignorecase=true) and
      event.payload.event.severity in ["warning", "average"]
    throttle:
      once_within: 30 minutes
      group_by_attributes:
        - event.payload.host.host
    action:
      run_job_template:
        name: "lvm-expand-vg"
        organization: "Default"
        job_args:
          extra_vars:
            target_host: "{{ event.payload.host.host }}"
            mount_point: "{{ event.payload.trigger.description }}"

Несколько решений, которые здесь не случайны:

  • throttle: once_within: 30 minutes - Zabbix умеет присылать несколько уведомлений по одной проблеме при смене severity. Без дроссля EDA запускал бы плейбук каждый раз. 30 минут - достаточно, чтобы первый запуск завершился.
  • group_by_attributes: host - дроссль работает независимо на каждый хост. Если у двух серверов одновременно заполнился диск, оба получат свой плейбук, а не один на двоих.
  • Фильтр по severity - «critical» мы намеренно оставили дежурному. Если диск уже на 95% и выше - там может быть нестандартная ситуация, которую стоит посмотреть глазами.

Где споткнулись

Поле с mount point из Zabbix. Нам нужно было передавать в плейбук, какую именно файловую систему расширять. В описании триггера Zabbix это есть, но структура зависит от того, как написан шаблон webhook на стороне Zabbix. У клиента был кастомный шаблон с нестандартными именами полей. Час отладки через ansible-rulebook --print-events - полезная опция, которая показывает сырые события - помог это разобрать.

Плейбук должен быть идемпотентным и устойчивым к no free space. Это звучит очевидно, но в нашем старом плейбуке была задача, которая писала временный файл в /tmp целевого хоста. Если диск уже заполнен - задача падала до нужного шага. Пришлось переписать этот кусок.

Авторизация EDA в AWX Controller. eda-server хранит credentials для подключения к Controller. При первоначальной настройке мы случайно создали token с недостаточными правами - EDA мог читать job templates, но не запускать. Ошибка проявлялась не сразу, а только при первом срабатывании, и выглядела как невнятный 403 в логах активации.

Плейбук расширения LVM

Сам плейбук - отдельная тема, но ключевые шаги:

  • Проверить, что на указанном mount point файловая система ext4 или xfs (с другими не трогаем автоматически).
  • Найти logical volume, смонтированный в эту точку.
  • Проверить наличие свободного места в volume group - если его нет, уведомить и остановиться.
  • Расширить LV на фиксированный размер (у нас 20 Гб - параметр, который можно переопределить через extra_vars).
  • Выполнить resize2fs или xfs_growfs в зависимости от типа ФС.
  • Записать результат в кастомное поле Zabbix через API - чтобы в истории хоста была отметка о том, что расширение произошло автоматически.

Последний пункт добавили не сразу. Без него утром коллеги видели в AWX историю запуска, но в Zabbix никакого следа не было. Теперь в истории хоста есть запись с временной меткой и размером до/после.

Что получилось по итогу трёх недель

За это время схема отработала на нескольких реальных инцидентах. Время реакции - от момента срабатывания триггера Zabbix до начала расширения - около 15-20 секунд. Это несравнимо с прежним форматом, когда дежурный мог среагировать через 40 минут, а ночью и дольше.

Ложных срабатываний за три недели не было. Одна ситуация, когда плейбук остановился сам - отсутствие свободного места в VG - это корректное поведение, там действительно требовалось решение иного масштаба.

Сейчас схема работает без «параллельного дежурного» на эту категорию алертов. Следующий кандидат на автоматизацию - рестарт упавших сервисов с предварительной проверкой причины через journalctl. Там сложнее с условиями, но принцип тот же.

EDA в AAP 2.3 - инструмент рабочий, хотя и с шероховатостями в UI и документации. Для повторяющихся, хорошо понятных инцидентов это работает, и работает неплохо.

Контакт

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

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