Перейти к содержанию

🟡 Статус: Design draft · v0.1

Подход правильный, но конкретный код, конфиги или пороги требуют валидации в вашем окружении.

12. Эксплуатационные процедуры

Главы 5–6 описывают, как построить мониторинг. Эта глава — про то, как его эксплуатировать, чтобы он не деградировал за полгода.

Темы:

  • A1. Self-monitoring — мониторинг самого Zabbix (кто следит за следящими)
  • A2. Maintenance Windows — плановые окна, freeze calendar, автоматизация
  • A3. Мониторинг Veeam — RPO/RTO, тест восстановления
  • A4. Onboarding нового хоста — чеклист, верификация
  • A5. Управление усталостью от алертов — еженедельный разбор, noise ratio, тюнинг
  • A6. Major Incident Communication Plan — матрица оповещения, шаблоны писем
  • A7. Планирование ёмкости — forecast-триггеры, квартальный разбор, сезонность

Каждая из них — отдельная мини-инструкция. Не обязательно внедрять всё сразу: можно по одной за квартал.


Приложение A. Операционные процедуры


A1. Мониторинг инфраструктуры мониторинга (Self-monitoring)

Назначение

Zabbix — единственная точка видимости состояния инфраструктуры. Если он недоступен, команда слепа. Self-monitoring решает парадокс: кто следит за сторожем.

Архитектурный принцип

Self-monitoring строится на отдельном независимом контуре — минимальном скрипте или сервисе, который не зависит от самого Zabbix. Основной мониторинг не может мониторить сам себя надёжно.

[Watchdog-скрипт на отдельном хосте]
         |
         | каждые 2 минуты проверяет Zabbix API
  если API не отвечает → Telegram напрямую через Bot API

Watchdog живёт на хосте, физически отдельном от Zabbix Server — например, на одном из прокси или на отдельной VM. Зависимость от одного канала (Telegram Bot API) — риск: если канал недоступен, алерт не дойдёт. Рекомендуется иметь два независимых out-of-band канала (например, Telegram + email через SMTP на внешний relay, или Telegram + SMS). Bot token и chat ID — через переменные окружения или secrets manager, не хардкод в скрипте.

#!/bin/bash
# /opt/watchdog/check_zabbix.sh
# cron: */2 * * * *

ZABBIX_URL="https://zabbix.plant.local/api_jsonrpc.php"
BOT_TOKEN="123456:ABC..."
CHAT_ID="-100123456789"
STATE_FILE="/tmp/zabbix_watchdog.state"

response=$(curl -s --max-time 10 -X POST "$ZABBIX_URL" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"apiinfo.version","params":[],"id":1}')

if echo "$response" | grep -q '"result"'; then
  # OK — сбросить флаг если был
  rm -f "$STATE_FILE"
else
  # Проверяем: уже отправляли алерт?
  if [ ! -f "$STATE_FILE" ]; then
    touch "$STATE_FILE"
    curl -s -X POST "https://api.telegram.org/bot$BOT_TOKEN/sendMessage" \
      -d "chat_id=$CHAT_ID" \
      -d "text=🔴 ZABBIX НЕДОСТУПЕН — $(date '+%Y-%m-%d %H:%M') — требуется проверка сервера" \
      -d "parse_mode=HTML" > /dev/null
  fi
fi

Что мониторить внутри Zabbix про себя

Шаблон Plant: Zabbix Infrastructure — клон стандартного Zabbix шаблона с кастомными триггерами под завод:

Метрика Trigger Severity
Zabbix queue (items > 10 min) > 100 элементов High
Proxy connectivity Proxy не отвечает > 5 мин High
PostgreSQL replication lag > 60 секунд High
PgBouncer pool saturation Ожидающих соединений > 10 Average
Zabbix DB size growth rate > 5 GB/сутки Warning
Zabbix Server process utilization > 75% Average
Grafana availability HTTP 200 не получен 3 мин Average

Runbook: Zabbix Server недоступен

Получен алерт от Watchdog. Алертов из Zabbix нет.

  1. Проверить доступность хоста: ping zabbix.plant.local, ssh zabbix-srv
  2. Если хост недоступен — это инцидент уровня инфраструктуры, переходи к runbook «VM недоступна»
  3. Если хост доступен: systemctl status zabbix-server → если stopped: journalctl -u zabbix-server -n 50
  4. Частые причины: переполнен диск (df -h), исчерпан пул соединений PgBouncer (psql -c "show pools"), OOM killer (dmesg | grep -i kill), нет доступа к БД (systemctl status postgresql)
  5. Восстановление: systemctl restart zabbix-serverтолько после проверки что: (а) диск не заполнен, (б) PostgreSQL доступен и принимает соединения, (в) нет незавершённого backup или крупной миграции данных. Перезапуск без диагностики может повторить крэш через минуту. Если есть Zabbix Server HA — проверьте failover через secondary узел до перезапуска primary. Подождать 2 минуты, проверить очередь через API
  6. После восстановления: проверить что Proxy-ноды переподключились (в UI: Monitoring → Hosts, фильтр по availability)
  7. Открыть постмортем если даунтайм > 15 минут

Временный мониторинг в период восстановления: дежурный вручную проверяет ключевые сервисы (1С, Exchange, сеть) по чеклисту из Operations Handbook пока Zabbix восстанавливается.


A2. Maintenance Windows — управление плановым обслуживанием

Зачем это важно

Без maintenance windows каждое плановое обслуживание генерирует десятки ложных алертов. Дежурные перестают реагировать на «шум во время патчинга» — и пропускают реальные инциденты.

Типы окон

Разовое — конкретная дата и время, однократно. Для патчинга, апгрейда, переезда.

Повторяющееся — например, каждое воскресенье 02:00–04:00. Для регламентного обслуживания.

Экстренное — создаётся оперативно при незапланированных работах.

Процедура создания окна

Кто создаёт: инженер, ответственный за работы, или дежурный по согласованию с тимлидом.

Срок уведомления: не менее чем за 4 часа для планового. Экстренное — немедленно.

Что указать при создании: - Хосты или группа хостов - Период (с точностью до минут) - Тип сбора данных в окне обслуживания: with data collection (0) или without data collection (1). При without data collection Zabbix server/proxy всё равно собирает данные, но сервер их не сохраняет и не обрабатывает triggers — хост фактически «глухой». Для патчинга чаще безопаснее выбрать with data collection: данные продолжают собираться, triggers срабатывать могут, но problem notifications подавлены. Выбор зависит от задачи: without data collection — для плановых остановок когда нет смысла хранить данные; with data collection — для патчинга когда хотите видеть что происходит, но не получать шум. - Описание: номер задачи/тикета

Автоматизация через API

Интеграция с ServiceDesk: при открытии Change Request типа «плановые работы» SD автоматически вызывает Zabbix API и создаёт окно. При закрытии CR — удаляет окно.

import requests

def create_maintenance(token, host_ids, name, start_ts, end_ts):
    # В current Zabbix API hosts и groups передаются как массивы объектов
    # Проверяйте актуальную документацию: https://www.zabbix.com/documentation/current/en/manual/api/reference/maintenance/create
    payload = {
        "jsonrpc": "2.0",
        "method": "maintenance.create",
        "params": {
            "name": name,
            "active_since": start_ts,
            "active_till": end_ts,
            "hosts": [{"hostid": hid} for hid in host_ids],  # массив объектов, не hostids
            "timeperiods": [{
                "timeperiod_type": 0,  # one-time
                "start_date": start_ts,
                "period": end_ts - start_ts
            }],
            "maintenance_type": 0  # 0=with data collection, 1=without data collection
        },
        "auth": token,
        "id": 1
    }
    # Примечание: tag-based maintenance (фильтр по тегам хостов)
    # поддерживается только при maintenance_type=0 (with data collection)
    r = requests.post(ZABBIX_URL, json=payload)
    return r.json()

Календарь заморозки — что нельзя трогать никогда

Это не maintenance window, это запрет на проведение работ. Фиксируется в Operations Handbook и согласуется с CIO ежегодно:

Период Причина Что запрещено
25–31 число каждого месяца Закрытие месяца в 1С Все работы на серверах 1С, БД, сети
15 декабря — 15 января Годовой баланс Любые изменения в продакшн
День выпуска продукции (уточнить) Критичный производственный цикл Работы на OT-сегменте

Freeze calendar публикуется в Confluence/Bookstack, напоминание уходит в Telegram-канал команды за 3 дня до начала.


A3. Мониторинг резервного копирования (Veeam)

Принцип

Мониторинг бэкапов — отдельная дисциплина. Цель не «задание зелёное», а гарантия что данные можно восстановить в пределах RPO и RTO. Зелёный статус задания ≠ рабочий бэкап.

Что мониторить

Уровень задания (Job level): - Последний статус: Success / Warning / Failed - Время последнего успешного завершения → вычислить «возраст» бэкапа - Продолжительность задания (тренд — если растёт, хранилище или источник деградирует) - Объём переданных данных (резкое падение → проблема на источнике)

Уровень репозитория: - Свободное место (алерт при < 20%, критично < 10%) - Количество точек восстановления (если меньше политики retention — что-то удалилось)

Уровень RPO: Самая важная метрика — не статус задания, а факт: «последний успешный бэкап был не старше N часов». Это independent check, не зависящий от статуса Veeam.

Для 1С-ERP: RPO = 4 часа → алерт если last_success > now - 4h
Для Exchange: RPO = 1 час (если DAG) → алерт если > 2h
Для PostgreSQL: RPO = 30 минут (WAL-G) → алерт если > 1h
Для файловых шар: RPO = 24 часа → алерт если > 26h

Интеграция с Zabbix

Veeam не имеет встроенного Zabbix-агента, но есть несколько путей:

Вариант 1: PowerShell + Zabbix UserParameter (проще всего)

# veeam_job_status.ps1 — запускается Zabbix агентом на Veeam-сервере
# Требует: Zabbix агент запущен под учёткой с правами Veeam Backup Operator или выше
param([string]$JobName)
try {
    $job = Get-VBRJob -Name $JobName -ErrorAction Stop
    if (-not $job) { Write-Output -1; exit }
    $session = $job.FindLastSession()
    if (-not $session) { Write-Output -1; exit }
    # Используем EndTime только для Success/Warning; для Running используем StartTime
    if ($session.Result -eq "Running") {
        Write-Output 0  # job ещё идёт
    } else {
        $ageHours = (New-TimeSpan -Start $session.EndTime -End (Get-Date)).TotalHours
        Write-Output ([math]::Round($ageHours, 2))
    }
} catch {
    Write-Output -1  # ошибка: -1 сигнализирует Zabbix триггеру
}

Проверяйте что $session.EndTime не null для Running-задания. Скрипт выше явно это обрабатывает. Для надёжного мониторинга рассмотрите официальный Veeam template из community-templates — он покрывает больше edge cases.

# zabbix_agentd.conf UserParameter
UserParameter=veeam.job.age[*],powershell -File C:\Scripts\veeam_job_status.ps1 -JobName "$1"
UserParameter=veeam.repo.free[*],powershell -File C:\Scripts\veeam_repo_free.ps1 -RepoName "$1"

Вариант 2: Официальный Zabbix template для Veeam — есть в community-templates репозитории, проверить актуальность под вашу версию Veeam.

Вариант 3: Veeam → syslog → Zabbix log item — Veeam умеет слать события в syslog, Zabbix их парсит.

Триггеры

Условие Severity Действие
Возраст бэкапа 1С > 4ч High Telegram + тикет
Возраст бэкапа Exchange > 2ч High Telegram + тикет
Любой job Failed High Telegram + тикет
Репозиторий < 20% Average Email команде
Репозиторий < 10% High Telegram — срочно
Job продолжается > 2× среднего времени Warning Telegram

Тест восстановления как мониторинг

Ежеквартальный тест восстановления должен быть задокументирован и зафиксирован в ServiceDesk. Без теста SLA на восстановление — декларация, не гарантия. Результат теста: файл восстановлен за N минут, БД поднята за N минут — записывается в Operations Handbook как фактический RTO.


A4. Onboarding нового хоста

Зачем нужен чеклист

Без регламента через год в Zabbix будет: хосты без тегов, хосты с шаблоном «Template OS Linux» вместо кастомных, хосты без owner и без runbook. Вся tag schema деградирует.

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

Чеклист добавления хоста

Шаг 1. Заполнить карточку хоста (до добавления в Zabbix):

hostname:       srv-app-01
ip:             10.10.20.15
os:             Windows Server 2022
role:           1С App Server
service:        1c-erp
criticality:    P1
owner:          it-apps
location:       dc-main
env:            prod
in_veeam:       yes (job: "DC Main Servers")
in_ad:          yes
warranty_until: 2027-06

Шаг 2. Добавить хост в Zabbix: - Применить базовый шаблон ОС (Plant: Windows Base или Plant: Linux Base) - Применить сервисный шаблон (Plant: 1C App Server) - Заполнить все 7 обязательных тегов - Добавить в правильные Host Groups (для RBAC)

Шаг 3. Верификация (через 24 часа): - [ ] Данные поступают без ошибок (нет Unavailable в Status) - [ ] Триггеры настроены (проверить что baseline-метрики видны: CPU, Memory, Disk) - [ ] Тест алерта: использовать Test кнопку в media type настройках (Actions → Media types → Test) или создать dedicated test trigger с заведомо срабатывающим условием на тестовом хосте. Временное снижение порога на production-хосте опасно: реальный алерт может сгенерировать тикет в ITSM и уведомление дежурным. Восстановить порог часто забывают - [ ] Synthetic check настроен если применимо (для web-сервисов) - [ ] Runbook ссылка добавлена в описание хоста

Шаг 4. Обновить Master Inventory (inventory.xlsx или NetBox) — колонку in_zabbix и дату добавления.

Кто отвечает: инженер добавляет, тимлид верифицирует за 24 часа. Без верификации тимлида хост считается в статусе «черновик».


A5. Управление усталостью от алертов — регулярный разбор алертов

Проблема

Усталость от алертов — главная причина деградации мониторинга. Команда видит 200 алертов в день, привыкает их игнорировать, пропускает реальный P1. Это не техническая проблема — это операционная.

Метрики для измерения усталости

  • Noise ratio = кол-во алертов без последующего acknowledge / общее кол-во алертов за неделю. Норма: < 20%. Если > 40% — что-то сильно не так.
  • MTTA (Mean Time To Acknowledge) по severity. P1 > 15 мин — проблема. Average > 24ч без движения — игнорируются.
  • Top-10 noisy triggers — те же 10 триггеров, которые срабатывают снова и снова. Это кандидаты на тюнинг или удаление.

Запрос для получения топ шумных триггеров из Zabbix API:

# Топ-20 триггеров по количеству событий за 30 дней
events = zapi.event.get(
    time_from=int((datetime.now() - timedelta(days=30)).timestamp()),
    time_till=int(datetime.now().timestamp()),
    source=0,  # trigger events
    value=1,   # PROBLEM events
    sortfield=["clock"],
    countOutput=False,
    selectHosts=["host"],
    selectRelatedObject=["description"],
    limit=10000
)
# Группируем по triggerid, считаем → топ

Еженедельный разбор алертов — регламент

Формат: 15 минут, каждую пятницу/понедельник в конце дня, участвует вся дежурная смена + тимлид.

Повестка: 1. Noise ratio за неделю — лучше/хуже предыдущей 2. Топ-5 срабатываний — каждый разбирается: actionable? шум? порог неверный? 3. Решение по каждому: повысить порог / добавить confirmation period / понизить severity / удалить 4. Одна задача с ответственным и дедлайном

Протокол (1 строка в таблице):

Дата | Триггер | Кол-во срабатываний | Решение | Owner | Дедлайн
2025-W23 | High CPU on srv-1c-02 | 47 | Поднять порог 85%→90%, добавить 5min period | Application Owner | пятница

Правило: ни один trigger с > 20 срабатываниями за неделю не должен оставаться без решения дольше двух недель.

Тюнинг без страха

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

Инструменты тюнинга в Zabbix: - min(,5m) > 90 — все значения за 5 минут выше порога (confirmation period); last(,5m) возвращает последнее значение не старше 5 мин — это не confirmation period - min(,10m) > 90 — минимум за 10 минут, убирает спайки - avg(,15m) > 85 — среднее, для CPU - Hysteresis: trigger ON при > 90%, recovery при < 80% — убирает flapping


A6. Major Incident Communication Plan

Зачем это в Operations Handbook

Технический runbook описывает как починить. Communication plan описывает кому и что сообщать пока чинишь. Бизнес узнаёт о падении 1С от злого звонка директора — это провал, даже если починили за 20 минут.

Матрица оповещения по P1

Кто Канал Когда Что сообщать
Дежурный тимлид Telegram/Звонок T+0 (сразу) «Инцидент P1: [сервис] недоступен с [время], работаем»
CIO SMS/Звонок T+5 мин Одно предложение: что, с какого времени, что делаем
Пользователи сервиса Email (шаблон) T+10 мин Шаблон A (см. ниже)
Директор завода CIO сам звонит T+15 мин если нет прогресса
Все причастные Telegram-канал статуса T+30 мин, потом каждый час Обновление статуса

Шаблоны писем

Шаблон A — начало инцидента (пользователи):

Тема: [Информация] 1С-ERP временно недоступна

Уважаемые коллеги,

С [ЧЧ:ММ] сегодня система 1С-ERP временно недоступна.
Специалисты ИТ работают над устранением. Ориентировочное время восстановления 
уточняется, следующее обновление — через 30 минут.

Приносим извинения за неудобства.
Вопросы: helpdesk@plant.local или вн. 2200

С уважением,
Служба ИТ

Шаблон B — обновление статуса:

Тема: [Обновление 10:45] 1С-ERP — работы продолжаются

Ситуация: [кратко что происходит]
Причина: [если известна]
Следующее обновление: через [N] минут / после восстановления

Шаблон C — восстановление:

Тема: [Решено 11:20] 1С-ERP восстановлена

Система 1С-ERP доступна с 11:20.
Длительность инцидента: 80 минут.
Пожалуйста, проверьте корректность ваших данных за период недоступности.

Подробный отчёт будет направлен в течение 24 часов.

Телефонное дерево P1

Хранится в Operations Handbook и обновляется при смене кадров (минимум раз в квартал):

[Дежурный инженер]
  → не берёт трубку 3 мин → [Резервный дежурный]
  → оба не берут → [Тимлид ИТ]
  → тимлид не берёт → [CIO]

[CIO при P1 > 30 мин]
  → [Директор завода] — только если есть влияние на производство

Номера телефонов — в отдельном защищённом документе (не в публичном Confluence), доступ у дежурных и CIO.

Сообщение по итогам инцидента

Через 24 часа после восстановления P1 — краткое письмо пользователям: что произошло, что сделано для предотвращения повторения. Это не постмортем — это коммуникация. Даже если причина «железо сломалось» — письмо строит доверие.


A7. Планирование ёмкости

Философия

Планирование ёмкости — не предсказание будущего. Это обнаружение трендов и принятие решений до того как проблема стала инцидентом. Лучший момент для заказа дополнительного хранилища — за 3 месяца до того как оно закончится, не за 3 дня.

Что измерять и как

Zabbix хранит исторические данные и умеет строить forecast через функцию timeleft() в триггерах и forecast() в графиках.

Дисковое пространство — самая важная метрика:

# Триггер: диск закончится через < 30 дней при текущем темпе заполнения
timeleft(/hostname/vfs.fs.size[/,pfree],1w,0) < 30d

⚠️ timeleft(..., 0) — время до достижения threshold 0% (полное заполнение). Функция может вести себя непредсказуемо на дисках с непостоянным паттерном заполнения (например, диски с ротацией логов — заполняется быстро, потом очищается). Для таких дисков практичнее алертить по абсолютному порогу: vfs.fs.size[/,pfree] < 10 (< 10% свободно). Используйте timeleft для дисков с монотонным ростом (БД, архивы).

Ключевые ресурсы для capacity tracking:

Ресурс Метрика Горизонт Порог алерта
Дисковое пространство (все серверы) % заполнения + forecast 30/60/90 дней < 30 дней до заполнения
Zabbix PostgreSQL БД Размер БД, скорость роста Ежемесячно > 5 GB/сутки
RAM на гипервизорах Balloon + swap + overcommit Квартально Overcommit > 120%
CPU на гипервизорах CPU ready time, avg load Квартально CPU ready > 5%
Veeam репозиторий % использования Еженедельно < 20% свободно
Network interfaces Utilization, errors, discards Квартально > 70% утилизация

Квартальный разбор ёмкости

Раз в квартал тимлид делает 30-минутный разбор в Grafana:

  1. Открыть дашборд планирования ёмкости (строится на forecast() и timeleft() из Zabbix datasource)
  2. Выделить ресурсы которые закончатся в течение следующего квартала
  3. Оформить запрос на закупку/расширение с обоснованием тренда (скриншот графика + forecast)
  4. Записать в таблицу: ресурс, текущий % использования, прогноз через 90/180 дней, рекомендуемое действие

Этот отчёт — один из слайдов квартального разбора ИТ для CIO. Данные из мониторинга напрямую превращаются в аргумент для бюджета.

Сезонность

На заводе capacity имеет сезонный характер: конец квартала и особенно декабрь-январь (годовой баланс) дают пиковую нагрузку на 1С и MSSQL. Baseline нужно строить с учётом сезона — сравнивать декабрь с декабрём прошлого года, не с октябрём текущего.

В Grafana это решается через timeshift — overlay текущего периода на аналогичный период прошлого года.


A8. Backup и восстановление самого Zabbix

Zabbix мониторит инфраструктуру — но кто следит за бэкапом самого Zabbix? Часто ответ: никто.

Что бэкапить

Компонент Как RPO
PostgreSQL БД (вся история метрик, конфиг) WAL-G / pg_dump / Veeam agent По политике RPO для Zabbix как сервиса
Конфигурация шаблонов, хостов, групп configuration.export → git (регулярный auto-export) git-история
Zabbix Server конфиг (zabbix_server.conf) В git / backup системы При изменениях
Grafana дашборды JSON export → git или Grafana backup При изменениях

Restore drill (ежеквартально)

Без проверки бэкап = декларация. Минимальный restore drill:

  1. Поднять тестовый экземпляр Zabbix из бэкапа БД
  2. Убедиться что UI открывается, хосты видны, данные корректны
  3. Зафиксировать фактическое RTO: сколько заняло восстановление
  4. Записать результат в Operations Handbook (backup_drill_YYYY-QQ.md)

Если фактический RTO превышает целевой — это риск, который нужно устранить до следующего квартала.


Итого по Приложению A

Глава Статус Приоритет внедрения
A1. Self-monitoring Написана Немедленно (фаза 2)
A2. Maintenance Windows Написана Фаза 2
A3. Veeam Backup Monitoring Написана Фаза 2
A4. Onboarding чеклист Написана Фаза 2
A5. Управление усталостью от алертов Написана Фаза 3 (регулярный процесс)
A6. Incident Communication Написана Фаза 3
A7. Планирование ёмкости Написана Фаза 3
A8. Backup и restore Zabbix Написана Фаза 2 (сразу)

Связь с остальными главами

  • Глава 2 — Severity: усталость от алертов — следствие плохой severity-модели
  • Глава 8 — GitOps: maintenance windows автоматизируются через тот же CI/CD pipeline