TGViewer
Make. Build. Break. Reflect. Make. Build. Break. Reflect. @makebreakreflect · 1.37K subscribers
Post #284 828
#longread #grafana #kubernetes #troubleshooting #одинденьизжизни

Три дашборда на границе Grafana
Часть 2 из 3.

Смотрю логи Grafana:
kubectl logs -n grafana deployment/prod-region1-grafana -c grafana --since=1h | grep -iE "provision|dashboard"


И вот оно:
{"error":"A dashboard with the same uid already exists","file":"/tmp/dashboards/MyApp/service-metrics-overview.json"}


Grafana provisioning видит файл, пытается его применить, но не может - в базе уже есть дашборд с таким UID.
Кстати в некоторых версиях Grafana логи могут не содержать сам UID.
В таком случае придётся идти в API или базу данных напрямую.

У нас графана с авторизацией по SSO, у меня права, как у девелопера.
Мне лень писать заявки на админский доступ и ковырять UI интерфейс, думаю мне хватит и curl + localhost для анализа.
Ведь я знаю, что рут пароль лежит в секретах кубера.😁
Я сам себе админ 😀

Проверяю через Grafana API:
GRAFANA_PASS=$(kubectl get secret -n grafana creds-grafana-admin -o jsonpath='{.data.admin-password}' | base64 -d)

kubectl exec -n grafana deployment/prod-region1-grafana -c grafana -- curl -s -u "admin:${GRAFANA_PASS}" "http://localhost:3000/api/search?query=service%20metrics"


И вижу:
- service-metrics-overview
- service-metrics-overview-vl
- service-metrics-overview-vl-draft
Сука, да откуда вы берётесь.

Три версии одного дашборда.
А файл у меня один (гит, конфигмап, файл внутри пода).

Тут до меня дошло: каждый раз, когда я менял UID, provisioning создавал новую запись в базе.
А старые записи никуда не девались - они просто висели мёртвым грузом.
Теперь, когда я хочу вернуть оригинальный UID service-metrics-overview, он уже занят старой записью.

Grafana хранит дашборды в PostgreSQL. Provisioning работает так:
- видит файл с UID
- проверяет - есть ли в БД запись с таким UID?
- если есть и привязана к этому файлу - обновляет
- если есть, но привязана к другому источнику - ошибка

Это не баг, а задуманное поведение: provisioning не перезаписывает дашборды, созданные из других источников.

Лезу в базу:
# ищу primary ноду (рид реплика не даст писать)
kubectl exec -n grafana pg-monitoring-1 -c postgres -- psql -U postgres -d grafana -c "SELECT pg_is_in_recovery();"
# true = replica

kubectl exec -n grafana pg-monitoring-2 -c postgres -- psql -U postgres -d grafana -c "SELECT pg_is_in_recovery();"
# false = primary


Смотрю что там:
kubectl exec -n grafana pg-monitoring-2 -c postgres -- psql -U postgres -d grafana -c "SELECT id, uid, title, version FROM dashboard WHERE uid LIKE '%service-metrics%' ORDER BY uid;"


  id  |                uid                  |                      title                       | version 
------+-------------------------------------+--------------------------------------------------+---------
3781 | service-metrics-overview | Service Metrics Overview | 1
3830 | service-metrics-overview-vl | Service Metrics Overview [VictoriaLogs] | 1
3825 | service-metrics-overview-vl-draft | Service Metrics Overview [VictoriaLogs Draft] | 1


Три записи от разных этапов миграции.
Файл один.
Вот и причина.

Варианты:
1. Удалить через UI - не выйдет (я ж попробовал), "provisioned dashboard cannot be deleted"
2. Ждать - не рассосётся само
3. Рестарт пода/подов - не вариант, мне по шапке за это дадут, графана как бы на всех.
4. Принудительный reload provisioning через API:
kubectl exec -n grafana deployment/prod-region1-grafana -c grafana -- curl -s -X POST -u "admin:${GRAFANA_PASS}" "http://localhost:3000/api/admin/provisioning/dashboards/reload"

Не помогло - ошибка та же, записи в БД мешают.
5. Удалить записи из базы напрямую 🤡

Выбираю последний вариант. Сначала бэкап:
kubectl exec -n grafana pg-monitoring-2 -c postgres -- pg_dump -U postgres grafana > grafana_backup_$(date +%Y%m%d_%H%M%S).sql


Затем удаление:
kubectl exec -n grafana pg-monitoring-2 -c postgres -- psql -U postgres -d grafana -c "DELETE FROM dashboard WHERE uid IN ('service-metrics-overview', 'service-metrics-overview-vl', 'service-metrics-overview-vl-draft');"

DELETE 3
  • 🔥 5
More from @makebreakreflect
  1. Sep 23, 2026В удивительнейшее время живём. - https://typesafe.ai/blog/introducing-system-one-models-an…
  2. Sep 22, 2026#aws #elasticache #redis #kubernetes #troubleshooting #devops #sre #longread Ничего не пре…
  3. Sep 18, 2026Вся эта неделя была очень странной. Опус отупел до уровня 3 модели. Фейбл сжигает токены б…
  4. Sep 16, 2026Post #382
  5. Sep 15, 2026Apple наконец слила beta и release в один продукт и избавились от лишнего шага в релизном…
  6. Sep 14, 2026#мысли #devops #aws Куча людей перешли на искусственный интеллект, так и не освоив собстве…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →