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, никакого состояния в БД которое надо хранить отдельно. Настройка занимает час, а потом перестаёшь думать о «а сохранились ли дашборды».