Provisioning datasources и дашбордов в Grafana через ConfigMap

Published: 2026-03-16

Grafana поддерживает декларативный provisioning: datasources и дашборды описываются в YAML/JSON-файлах, монтируемых в под. В связке с Flux дашборды живут в git и применяются автоматически — никакого ручного импорта, никаких инцидентов вида «кто-то удалил дашборд».


Provisioning datasources

В kube-prom-stack datasources описываются прямо в Helm values:

yamlgrafana:
  additionalDataSources:
    - name: Prometheus-dev
      type: prometheus
      url: http://prometheus-operated.observability.svc.cluster.local:9090
      isDefault: false
      jsonData:
        timeInterval: "30s"
        exemplarTraceIdDestinations:
          - name: trace_id
            datasourceUid: tempo

    - name: VictoriaMetrics
      type: prometheus
      url: http://victoria-metrics.observability.svc.cluster.local:8428
      isDefault: false

    - name: Elasticsearch
      type: elasticsearch
      url: http://elasticsearch-master.observability.svc.cluster.local:9200
      jsonData:
        index: "vector-*"
        timeField: "@timestamp"
        logMessageField: message

    - name: Loki-VictoriaLogs
      type: loki
      url: http://victoria-logs.observability.svc.cluster.local:9428

Provisioning дашбордов через sidecar

yamlgrafana:
  sidecar:
    dashboards:
      enabled: true
      label: grafana_dashboard
      labelValue: "1"
      searchNamespace: ALL
      folderAnnotation: grafana_folder
      provider:
        foldersFromFilesStructure: true

Sidecar отслеживает ConfigMap с меткой grafana_dashboard: "1" во всех неймспейсах и подхватывает изменения на лету, без перезапуска пода.


Создание ConfigMap из JSON-файлов дашборда

yaml# kustomization.yaml
configMapGenerator:
  - name: grafana-dashboards-infra
    namespace: observability
    options:
      disableNameSuffixHash: true
    files:
      - dashboards/cluster-overview.json
      - dashboards/flux-reconciliation.json
      - dashboards/elasticsearch-cluster.json

Патч с меткой и аннотацией папки:

yamlapiVersion: v1
kind: ConfigMap
metadata:
  name: grafana-dashboards-infra
  namespace: observability
  labels:
    grafana_dashboard: "1"
  annotations:
    grafana_folder: "Infrastructure"

JSON дашборда в git

Перед коммитом:

  1. Удалите поле id (специфично для кластера)
  2. Замените жёстко заданные UID datasource на переменные:
json{
  "templating": {
    "list": [
      {
        "name": "datasource",
        "type": "datasource",
        "query": "prometheus"
      }
    ]
  },
  "panels": [
    {
      "datasource": {"type": "prometheus", "uid": "${datasource}"}
    }
  ]
}

Структура папок

dashboards/
  infrastructure/
    cluster-overview.json
    node-exporter.json
  application/
    apisix.json
    elasticsearch.json
  flux/
    flux-control-plane.json
    flux-reconciliation.json

Contact points как код

yamlgrafana:
  alerting:
    contactpoints.yaml:
      apiVersion: 1
      contactPoints:
        - orgId: 1
          name: Telegram
          receivers:
            - uid: telegram-receiver
              type: telegram
              settings:
                bottoken: "${TELEGRAM_BOT_TOKEN}"
                chatid: "${TELEGRAM_CHAT_ID}"

Диагностика

Дашборды не загружаются:

bashkubectl logs -n observability deploy/kube-prom-stack-grafana -c grafana-sc-dashboard

Ошибки подключения datasource: проверьте DNS-имя сервиса — оно должно совпадать с именем и неймспейсом сервиса Prometheus/ES. Доступность можно проверить через kubectl exec из пода Grafana.

Дублирование дашбордов после обновления: используйте disableNameSuffixHash: true для ConfigMap дашбордов. Без этого Kustomize добавляет hash-суффикс, и sidecar создаёт новые дашборды, не удаляя старые.