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

Grafana 5.2: дашборды и datasource в Git - мониторинг как код

Grafana 5.2 принесла provisioning через YAML: дашборды и datasource теперь хранятся в Git и деплоятся Ansible вместе с приложением. Разбираем что изменилось на практике.

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

Grafana 5.2 - provisioning дашбордов и datasource через YAML-файлы конфигурации

До версии 5.2 у Grafana была одна неприятная особенность: дашборды существовали только в её собственной SQLite или PostgreSQL базе. Хочешь перенести стенд - экспортируй JSON вручную, импортируй на новом месте, молись что ничего не перепутал. Пересоздал контейнер - дашборды исчезли, если не настроил persistent volume. Накатил Ansible-плейбук на новый сервер - всё чисто, Prometheus работает, а Grafana пустая. Добавляй datasource руками, импортируй дашборды руками.

Это было терпимо пока Grafana стояла на одном-двух серверах. Когда таких инсталляций стало больше - терпение закончилось.

Что изменилось в 5.2

Grafana 5.2 сделала provisioning частью штатного функционала. Теперь при старте Grafana читает YAML-файлы из указанных директорий и автоматически:

  • создаёт datasource - адрес, тип, авторизация, дефолтный флаг;
  • загружает дашборды из JSON-файлов - полностью, включая все панели и переменные;
  • отслеживает изменения в JSON-файлах и перезагружает дашборды без рестарта.

Всё это через два типа YAML-конфигов: один описывает datasource, второй указывает где искать файлы дашбордов. Выглядит просто, и это хорошо - иногда простота и есть фича.

Как выглядит на практике

Структура файлов у нас получилась такая:

grafana/
  provisioning/
    datasources/
      prometheus.yaml
    dashboards/
      default.yaml
  dashboards/
    infrastructure.json
    kubernetes.json
    postgres.json

Конфиг datasource для Prometheus:

apiVersion: 1

datasources:
  - name: Prometheus
    type: prometheus
    access: proxy
    url: http://prometheus:9090
    isDefault: true
    editable: false

Конфиг провайдера дашбордов:

apiVersion: 1

providers:
  - name: default
    orgId: 1
    folder: ''
    type: file
    disableDeletion: false
    updateIntervalSeconds: 30
    options:
      path: /var/lib/grafana/dashboards

updateIntervalSeconds: 30 - Grafana раз в 30 секунд проверяет директорию и подтягивает изменения в JSON. Это означает что правка дашборда через git push + Ansible реально отражается без рестарта сервиса.

В docker-compose это монтируется двумя volume:

grafana:
  image: grafana/grafana:5.2.2
  volumes:
    - ./grafana/provisioning:/etc/grafana/provisioning
    - ./grafana/dashboards:/var/lib/grafana/dashboards
    - grafana_data:/var/lib/grafana

Grafana_data - это теперь только пользователи, настройки интерфейса и плагины. Содержательная часть живёт в Git.

Плейбук и workflow

В Ansible роль для Grafana стала проще. Раньше там была магия с API: после установки дёргали /api/datasources, проверяли есть ли datasource, если нет - создавали POST-запросом, если есть - PUT. С provisioning этот код ушёл. Ansible просто раскладывает файлы в нужные места и перезапускает Grafana если что-то изменилось.

Workflow для дашбордов теперь такой: берёшь дашборд, редактируешь в UI, делаешь «Export» в JSON, кладёшь в репозиторий. Чуть громоздко, но зато история изменений в git, diff читаемый (JSON Grafana - не самый компактный, но хоть что-то), и главное - дашборд не исчезнет при любых манипуляциях с контейнером или сервером.

На managed-проектах это закрыло постоянную головную боль: при обновлении стека или пересоздании окружения мониторинг поднимается вместе с приложением, а не восстанавливается потом вручную.

Мелкие грабли

Пара вещей, на которые потратили время.

Поле uid в JSON. Если дашборд создан без явного uid - Grafana генерирует его при импорте. При следующем деплое она решит что это новый дашборд и создаст дубль. Нужно вручную прописать uid в JSON перед коммитом:

{
  "uid": "infra-overview",
  "title": "Infrastructure Overview",
  ...
}

editable: false в datasource. Если указать editable: false, то datasource нельзя изменить через UI. Звучит правильно с точки зрения «infrastructure as code», но на практике это мешает при отладке - иногда нужно временно поменять URL Prometheus. Мы оставили editable: true в dev-окружениях.

Удаление дашбордов. disableDeletion: false означает что если удалить JSON из директории - дашборд удалится при следующей проверке. Неочевидное поведение по умолчанию, стоит знать.

Связь с тем что уже было

Когда мы переходили на Prometheus 2.3, Grafana там выступала как просто интерфейс - datasource и дашборды настраивались вручную после деплоя. С provisioning этот шов исчезает: весь стек мониторинга - Prometheus с конфигом в Git, Grafana с дашбордами в Git - поднимается одним плейбуком.

Алертинг Grafana в provisioning не участвует - алерты хранятся только в базе. Это логично, потому что алерты в Grafana мы почти не используем - Alertmanager справляется лучше. Но для тех кто на них полагается - имейте в виду.

Итог

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

Контакт

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

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