Трендовые github проекты в нашем телеграм канале. Подпишись → Переезд с PagerDuty на self-hosted: что выбрать для дежурств
Сценарий знакомый многим командам: PagerDuty перестаёт быть доступным или по карману, а на нём держатся расписания дежурств и эскалации по десятку проектов. Требования к замене короткие: собирать алерты из разных источников, знать, кто сегодня дежурит, и поднимать инцидент выше по цепочке, если первый человек не отреагировал. Плюс self-hosted, чтобы не зависеть от внешнего провайдера.
Ниже — разбор пилота двух кандидатов, IncidentRelay 1.1 и OneUptime 11.4.1, развёрнутых в Kubernetes и проверенных на реальных сценариях дежурства.
Почему Telegram-бот не справляется
Первая мысль — слать алерты в Telegram. Для on-call этого мало по нескольким причинам:
- Нет расписания. Сегодня проект на одном инженере, завтра на другом. Бот отправит алерт всем, и разбираться придётся в общем чате.
- Нет эскалации. Типовая цепочка: поддержка → дежурный DevOps → тимлид, с таймаутом на каждом шаге. В Telegram её можно собрать только своим сервисом, то есть написать мини-PagerDuty самому.
- История инцидента теряется. Взял в работу, приложил ранбук, записал заметки по диагностике, закрыл. В чате это превращается в ленту, где через день непонятно, кто что смотрел.
- Канал нестабилен. Отвалился VPN — уведомление пришло через час или не пришло вовсе.
IncidentRelay 1.1: лёгкий, но сырой
IncidentRelay ближе всего к «тонкому пейджеру». Официальный Helm-чарт поднимается быстро, есть нативные интеграции с Alertmanager и Mattermost, Keycloak подключается с передачей ролей и прав прямо из IdP. Для Telegram можно указать прокси в настройках продукта.
Проблемы вылезли при прогоне сценариев дежурного:
- интерфейс местами подсказывает нужное действие со второй-третьей попытки, часть элементов отрисовывается криво;
- дашбордов со статистикой по инцидентам нет;
- мобильного приложения нет.
Последний пункт решающий. Днём можно жить с веб-интерфейсом, но ночному дежурному нужен надёжный push. Проект молодой, функции могут появиться, но на момент пилота его отложили.
OneUptime 11.4.1: платформа, из которой нужен один слой
OneUptime выглядит заметно взрослее. В нём есть собственные мониторы, агенты, статусные страницы, ранбуки, интеграции с LLM и GitLab. Для замены PagerDuty из этого нужны инциденты, расписания дежурств, эскалации, метрики и доставка уведомлений — всё это работает. Есть русский язык в UI и мобильное приложение с рабочими push-уведомлениями.
Метрики по инцидентам и времени решения есть, но смотреть их приходится внутри отдельного монитора проекта: общего дашборда по всем проектам не нашлось.
Цена установки
OneUptime требует Postgres и ClickHouse и по числу компонентов и ресурсам тяжелее IncidentRelay. Документация по установке оставляет пробелы, и два из них ломают запуск:
- Внешнему Postgres нужно расширение
uuid-ossp. - ClickHouse должен быть реплицируемым, иначе OneUptime не стартует.
Оба требования выясняются только по ошибкам в логах. Для ClickHouse в Kubernetes подходит Altinity operator; альтернатива — внешний managed ClickHouse с репликацией. Если вы ставите OneUptime на внешний Postgres, расширение стоит создать заранее:
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
Telegram из России
Здесь OneUptime хуже конкурента: прокси для Telegram в продукте не задаётся. Рабочий вариант — фильтровать исходящий трафик и заворачивать через внешний прокси только обращения к Telegram. Поскольку параллельно уходят push и почта, сбой одного канала не оставляет дежурного без алерта.
Приём алертов из Alertmanager
Нативной интеграции с Alertmanager у OneUptime нет. Есть два способа принимать внешние события.
Workflow: удобно собрать, сложно сопровождать
Workflow — визуальный конструктор: внешняя система шлёт событие в вебхук, дальше цепочка разбирает payload, добавляет теги и создаёт или обновляет инцидент. Внутрь можно положить Custom Code, поэтому кажется логичным собрать по workflow на каждый проект со своим форматом алертов.
На практике у workflow нет версионирования и API для управления. Цепочку можно дублировать внутри проекта OneUptime, но перенести в другой проект (изолированное окружение) нельзя. MCP-сервер OneUptime с workflow тоже не работает. Логика, которая живёт только в UI, плохо ревьюится, плохо переносится между окружениями и плохо восстанавливается.
Разводить источники тегами (проект1, проект2) тоже получается, но в общей таблице инцидентов источник так и остаётся тегом без привязки к ресурсу.
Incoming Request: монитор вместо вебхука
Рабочая схема — мониторы типа Incoming Request. У каждого свой URL и secret key; внешняя система шлёт на него HTTP GET или POST, OneUptime сам ничего не опрашивает. В документации этот тип описан как heartbeat-мониторинг, но для приёма алертов он подходит лучше workflow:
- алерты корректно переходят в resolved без ручного Update Incident;
- в общей таблице появляется колонка Affected Resource с конкретным монитором;
- аналитику по проектам удобно строить по монитору.
По сети это тот же вебхук, разница в модели данных: источник становится ресурсом OneUptime. Контракты под разные форматы алертов настраивать всё равно придётся, но единица настройки — монитор с отдельным URL — сопровождается проще.
Существующие инструменты при этом не обязательно выбрасывать. Healthchecks.io может и дальше следить за cron и скриптами и отдавать события в OneUptime по вебхуку.
Keycloak и роли
IncidentRelay забирает RBAC из Keycloak. В OneUptime веб-SSO настраивается, но роли из IdP не передаются. Остаются два режима: приглашать людей по email, привязанному к их учётке в Keycloak, или пускать любого пользователя этого Keycloak. Политику доступа в обоих случаях придётся проектировать на стороне OneUptime.
OIDC в OneUptime отнесён к Enterprise, но для self-hosted установки лицензия разрешает снять это ограничение самостоятельно. Минус в том, что OneUptime обновляется часто, и патч придётся повторять после каждого обновления.
Мобильное приложение на момент теста не смогло войти через корпоративный Keycloak: оно обращалось к неправильному эндпоинту, хотя тот же SSO-сценарий в вебе проходил. Приложение для iOS с тех пор начали обновлять, и ошибку, возможно, исправили. Встроенная авторизация в приложении работает, push после входа приходят.
Миграция расписаний
Автоматического экспорта из PagerDuty в этом случае не было: доступ к аккаунту заблокировали. Расписания и цепочки эскалации собирали в OneUptime вручную по внутренним договорённостям.
Теоретически перенос можно автоматизировать через MCP: у PagerDuty есть MCP-сервер, в OneUptime MCP встроен. LLM-агент мог бы выгрузить расписания и политики из одной системы и завести в другую. Этот путь не проверялся, так что рассчитывать на него без собственного теста не стоит.
Сводная таблица
| Критерий | IncidentRelay 1.1 | OneUptime 11.4.1 |
|---|---|---|
| Инциденты, дежурства, эскалации | Есть | Есть |
| Метрики по инцидентам | Нет | Внутри отдельного монитора |
| Alertmanager | Нативно | Через Incoming Request |
| Telegram | Прокси в настройках | Прокси не задаётся, нужен внешний |
| Mattermost | Нативно | Нативно нет; есть каналы WhatsApp, Telegram, Slack, Teams |
| Мобильное приложение | Нет | Есть, push работают |
| Keycloak | OIDC + RBAC из IdP | Веб-SSO без RBAC из IdP |
| Деплой в Kubernetes | Лёгкий Helm | Тяжёлый Helm + реплицируемый ClickHouse |
Сколько это стоит
Ресурсы под self-hosted OneUptime обходятся примерно в десять раз дешевле подписок команды на PagerDuty. В это сравнение не входит время инженера: пилот двух продуктов, переезд с workflow на Incoming Request, разбор ошибок ClickHouse и патч OIDC заняли не один день, а дальше регулярно добавятся обновления и бэкапы.
Практическое правило по итогам пилота: если дежурства ночные и без push жить нельзя, выбирайте OneUptime и сразу закладывайте реплицируемый ClickHouse, uuid-ossp в Postgres и приём алертов через Incoming Request. Если нужен лёгкий пейджер с нативным Alertmanager, Mattermost и ролями из Keycloak, а мобильное приложение не критично, IncidentRelay стоит держать в списке и перепроверить на следующих версиях.