Как я поднимал под пивко "Централизованный мониторинг": Prometheus + Grafana (OSS) для TEST и PROD. Поднял единый контур мониторинга на базе Prometheus + Grafana + Blackbox. Всё на одной VM, управление — Ansible (roles install/configure/manage), проекты подключаются одним YAML-файлом. Умер проект удал YAML-файл.

Стек

  • Prometheus (single-node, scrape через scrape_config_files: projects/*.yaml)
  • Grafana 13.1 (OSS), nginx (публикация /grafana и /prometheus), Blackbox, Node Exporter, cAdvisor
  • LDAP-авторизация (dc1.cmx.ru), basic auth на Prometheus

Архитектура

  • Одна организация Grafana, каждый проект = папка: Common (дашборды, view-only) + Custom (под пользователя)
  • Изоляция данных: на все таргеты вешается метка project=, при копировании дашборда в проект в каждый PromQL-запрос инжектится project=""
  • RBAC: права на папки через команды проекта, команды заполняются автоматически из AD-групп cn=_*
  • Подключение проекта: файл projects/.yml → make manage-monitoring → папки/борды/команды/scrape-конфиги создаются автоматически

Проблемы, на которые наступил (и как решал) 1. foldersFromFilesStructure в Grafana 13 создаёт ПЛОСКИЕ папки — вложенность не строится (Linux/Disk/Certs становятся сёстрами, а не детьми). → Папки создаю через Grafana API с parentUid. 2. Думал, что прав на папки в OSS нет — оказалось, в v13 folder permissions работают (и реально режут видимость: 403 и дашборд скрыт). Это стало основой RBAC. 3. Reload Prometheus не работал: --web.enable-lifecycle не был включён + ansible template пересоздаёт файл → меняется inode → inotify не видит изменения. → POST /-/reload через API после каждого изменения конфига. 4. Grafana → Prometheus 403. Дашборды не грузились. Причина: grafana ходила на prometheus:9090 через HTTP-прокси (Squid), т.к. имя не в NO_PROXY → прокси отдавал 403. → добавил prometheus,grafana,... в NO_PROXY. 5. nginx терял grafana после пересоздания контейнера: кэшировал старый IP, grafana получала новый → 502. → статические IP на сети integration_external. 6. Одинаковые дашборды в папках разных проектов конфликтовали — «same UID used more than once», provisioning отказывался писать. → переписываю UID на <проект>-<борд> при копировании. 7. Дашборды без uid (например blackbox.json) получали случайный UID при каждом импорте → дубли. → normalize-скрипт выставляет UID и убирает id/version (иначе deprecatedInternalID is already in use, 409). 8. folderUid в dashboard.yaml provisioning не срабатывал для новых дашбордов → перешёл на импорт через Grafana API (POST /api/dashboards/db + overwrite: true) — детерминированный create/update/delete. 9. Изоляция данных: борда ПРОЕКТА1 показывала хосты ПРОЕКТА2. → метка project + инъекция фильтра во все запросы (включая переменные dropdown). 10. LDAP не пускал: «User does not belong in any of the specified LDAP groups» — юзер не в группах подключённых проектов. → wildcard * → Viewer, доступ к папкам решают команды. 11. Grafana 13 хранит дашборды НЕ в таблице dashboard — SQL-очистка БД не удаляла борды. Чистка только через API (после снятия provisioning). 12. search folderUids не фильтрует — «удаление лишних борд» сносило все. → список всех дашбордов + фильтр по folderUid на стороне плейбука.

Вывод

  • Модель «папки + права на папки + команды» для OSS Grafana — рабочая, изоляция дашбордов и данных на уровне меток.
  • Слабые места: single-node Prometheus (7d retention), нет Alertmanager/логов, хрупкая инъекция project в PromQL (bare-запросы и Explore не закрыты).
  • Дальше: Alertmanager + уведомления, Loki, бэкапы, при росте — Mimir/Thanos для настоящей мультитенантности и HA.