Три дашборда на границе Grafana
Часть 3 из 3.
Жду 30 секунд (updateIntervalSeconds в provisioning конфиге).
Проверяю:
kubectl exec -n grafana pg-monitoring-2 -c postgres -- psql -U postgres -d grafana -c "SELECT id, uid, title FROM dashboard WHERE uid LIKE '%service-metrics%';"
id | uid | title
------+-----------------------------+--------------------------------------------
3838 | service-metrics-overview | Service Metrics Overview [VictoriaLogs]
Одна запись. Правильный title. Правильный UID.
Иду в UI - работает. Никаких дублей, никаких "Draft", никакого Loki.
Победа! 🎉
Если provisioning не срабатывает автоматически, можно вызвать reload через API (выше был пример курлом) или перезапустить pod Grafana (не мой вариант).
Подробнее про provisioning: https://grafana.com/docs/grafana/latest/administration/provisioning/
На всё ушло часа два.
Могло бы - минут пятнадцать, если бы сразу глянул в логи.
Выводы, а куда без них.
- Grafana provisioning не перезаписывает существующие записи в БД, если они созданы из другого источника. Он кидает ошибку в лог и оставляет старую версию.
- ошибка "A dashboard with the same uid already exists" - это про запись в PostgreSQL, не про файл. Файл может быть идеальным, но если в базе мусор - ничего не заработает.
- логи первым делом. Там обычно всё написано. Но не во всех версиях Grafana логи достаточно информативны.
- удаление из БД работает, но это неофициальный подход. Я не нашёл другого способа. Для provisioned dashboards безопасно - они автоматически пересоздаются из файлов. Главное - делать на primary ноде PostgreSQL и иметь бэкап.
- миграции дашбордов - это не "поменять пару строк". Особенно если UID менялся несколько раз. Особенно, если я баран.
Как избежать этой проблемы (предполагаю):
- не меняйте UID после первого деплоя. Если нужна миграция - создайте новый дашборд с новым UID, а старый удалите полностью (включая запись в БД).
- используйте стабильные UID с префиксами:
myteam-service-metrics-overview
myteam-app-logs-dashboard
- не используйте один UID для дашбордов в разных папках - это создаёт race condition.
- документируйте миграции в changelog или README.
- используйте
allowUiUpdates: false в provisioning конфиге - это предотвращает дрейф конфигурации.Пример конфигурации провижининга
apiVersion: 1
providers:
- name: 'sidecarProvider'
orgId: 1
type: file
disableDeletion: false
allowUiUpdates: false # запрет редактирования в UI
updateIntervalSeconds: 30 # интервал сканирования файлов
options:
foldersFromFilesStructure: true
path: /tmp/dashboards
Альтернативный подход, без прямого доступа к БД - когда его нет или страшно (предполагаю, что это правильный путь, но я не проверял):
- временно переименовать ConfigMap (например добавить суффикс
-old)- дождаться, пока Grafana удалит дашборды (если
disableDeletion: false)- вернуть ConfigMap с правильным именем и новым UID
- provisioning создаст дашборды заново
Этот способ медленнее, но безопаснее.
Для зануд:
Прямое изменение базы данных Grafana - неофициальная практика!
Это не является моим советом или рекомендацией!
Просто поделился своей историей.
- - -
- https://github.com/grafana/grafana/issues/12411
- https://github.com/grafana/grafana/issues/41085
- https://github.com/grafana/grafana/issues/73043