Grafana Grafana

Grafana auf Kubernetes mit Helm und Provisioning-Values deployen

Betreibe Grafana aus einem Helm-Chart, bei dem Datenquellen, Dashboards und Einstellungen alle aus Values-Dateien stammen.

15 min Fortgeschritten

Auf Kubernetes verwandelt das Grafana-Helm-Chart die Provisioning-Ordner in Konfiguration, die du in values.yaml schreibst. Das Chart rendert ConfigMaps und Secrets, mountet sie an den Pfaden, die Grafana erwartet, und startet neu oder lädt neu, wenn sie sich ändern. Das macht Grafana zu einem guten Kandidaten für GitOps, da die Values-Datei das Einzige ist, was du bearbeitest. Diese Anleitung baut eine Values-Datei, die eine Datenquelle, Dashboards, Alerting und Servereinstellungen provisioniert.

Das Hosting der Charts ändert sich: Einige Charts von Grafana Labs ziehen in ein von der Community gepflegtes Repository um. Prüfe vor der Installation die README des Charts auf die Repository-URL und die Chart-Version, die du nutzen sollst, und pinne diese Version. Die Values-Schlüssel unten folgen der dokumentierten Struktur des Charts, bestätige sie aber in der values.yaml der Version, die du installierst.

Installieren

helm repo add grafana https://grafana.github.io/helm-charts
helm repo update
helm install grafana grafana/grafana \
  --namespace monitoring --create-namespace \
  --version <chart-version> \
  -f values.yaml

Ist das Chart umgezogen, ersetze die Repository-URL durch die aus der README. Halte den Befehl, die --version und die Values-Datei in Git, damit die Installation wiederholbar ist.

Servereinstellungen: grafana.ini

Alles, was du in grafana.ini schreiben würdest, kommt unter den Schlüssel grafana.ini, nach Sections organisiert:

grafana.ini:
  server:
    root_url: https://grafana.example.com/
  users:
    allow_sign_up: false
  analytics:
    reporting_enabled: false
    check_for_updates: false
  log:
    mode: console

Werte, die nicht committet werden dürfen, können wie in der Konfigurationsanleitung auf Umgebungsvariablen oder Dateien verweisen (zum Beispiel password: $__file{/etc/secrets/db/password}).

Admin-Zugangsdaten und andere Secrets

Nutze ein bestehendes Kubernetes-Secret statt eines Passworts in den Values:

admin:
  existingSecret: grafana-admin
  userKey: admin-user
  passwordKey: admin-password

envFromSecret: grafana-secrets   # jeder Schlüssel wird zu einer Umgebungsvariable
apiVersion: v1
kind: Secret
metadata:
  name: grafana-secrets
  namespace: monitoring
stringData:
  POSTGRES_PASSWORD: change-me
  SLACK_WEBHOOK_URL: https://hooks.slack.com/services/XXX/YYY/ZZZ

Provisioning-Dateien können dann $POSTGRES_PASSWORD und ${SLACK_WEBHOOK_URL} verwenden. Verschlüssele das Secret mit SOPS oder synchronisiere es mit External Secrets, statt es als reines YAML zu committen (siehe die Anleitung zu Secrets).

Datenquellen

Der Schlüssel datasources wird in eine Provisioning-Datei gerendert:

datasources:
  datasources.yaml:
    apiVersion: 1
    datasources:
      - name: Prometheus
        uid: prometheus
        type: prometheus
        access: proxy
        url: http://prometheus-server.monitoring.svc.cluster.local
        isDefault: true
        editable: false

Dashboards: drei Wege

1. Inline aus Dateien im Chart-Ordner. Deklariere einen Provider und liste Dashboards nach Quelle auf:

dashboardProviders:
  dashboardproviders.yaml:
    apiVersion: 1
    providers:
      - name: default
        orgId: 1
        folder: ''
        type: file
        disableDeletion: false
        allowUiUpdates: false
        options:
          path: /var/lib/grafana/dashboards/default

dashboards:
  default:
    node-exporter:
      gnetId: 1860
      revision: 37
      datasource: Prometheus
    kubernetes-overview:
      json: |
        { "uid": "k8s-overview", "title": "Kubernetes Overview", "panels": [] }

Einträge können von grafana.com (gnetId und revision), einer URL oder Inline-JSON stammen. Der Schlüssel unter dashboards (hier default) muss zum Ordnernamen in options.path des Providers passen.

2. Aus ConfigMaps, die du selbst verwaltest. Halte Dashboard-JSON in eigenen ConfigMaps (zum Beispiel von Kustomize aus dem Repository erzeugt) und mounte sie:

dashboardsConfigMaps:
  default: grafana-dashboards

3. Mit dem Sidecar. Ein Sidecar-Container beobachtet den Cluster auf ConfigMaps (oder Secrets) mit einem Label und lädt sie als Dashboards, sodass jedes Anwendungsteam sein eigenes Dashboard neben seinen Manifesten ausliefern kann:

sidecar:
  dashboards:
    enabled: true
    label: grafana_dashboard
    labelValue: "1"
    searchNamespace: ALL
    folderAnnotation: grafana_folder
    provider:
      foldersFromFilesStructure: true
  datasources:
    enabled: true
    label: grafana_datasource
  alerts:
    enabled: true
    label: grafana_alert
apiVersion: v1
kind: ConfigMap
metadata:
  name: webapp-dashboard
  namespace: webapp
  labels:
    grafana_dashboard: "1"
  annotations:
    grafana_folder: Applications
data:
  webapp.json: |
    { "uid": "webapp-overview", "title": "Webapp Overview", "panels": [] }

Der Sidecar-Ansatz skaliert über Teams hinweg am besten: Niemand muss die Values von Grafana bearbeiten, um ein Dashboard hinzuzufügen.

Alerting

Alerting-Provisioning-Dateien können aus dem Schlüssel alerting kommen und die YAML-Formate aus der Alerting-Anleitung nutzen:

alerting:
  contactpoints.yaml:
    secret:
      apiVersion: 1
      contactPoints:
        - orgId: 1
          name: team-slack
          receivers:
            - uid: team-slack-1
              type: slack
              settings:
                url: ${SLACK_WEBHOOK_URL}
                recipient: '#alerts'
  policies.yaml:
    apiVersion: 1
    policies:
      - orgId: 1
        receiver: team-slack

Der Wrapper secret: legt diese Datei in ein Secret statt in eine ConfigMap. Prüfe die values.yaml des Charts auf die exakte Form in deiner Version. Alert-Regeln können aus demselben Schlüssel oder aus der Einstellung alerts des Sidecars kommen.

Persistenz und Replikas

persistence:
  enabled: true
  size: 5Gi
replicas: 1

SQLite auf einem Persistent Volume unterstützt ein Replikat. Für Hochverfügbarkeit richte Grafana über grafana.ini auf PostgreSQL und erhöhe replicas.

Mit Flux deployen

Wenn du Flux nutzt, wird das Chart zu einem HelmRelease, und die obigen Values gehören in spec.values:

apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
  name: grafana
  namespace: monitoring
spec:
  interval: 10m
  chart:
    spec:
      chart: grafana
      version: "<chart-version>"
      sourceRef:
        kind: HelmRepository
        name: grafana
        namespace: flux-system
  valuesFrom:
    - kind: ConfigMap
      name: grafana-values

Eine Änderung der Values in Git rollt die Änderung automatisch aus. Siehe die Helm-Anleitung der Flux-Reihe für HelmRepository, Remediation und Drift-Erkennung.

Prüfen

kubectl get pods -n monitoring
kubectl port-forward svc/grafana 3000:80 -n monitoring &
curl -s http://localhost:3000/api/health
kubectl logs deploy/grafana -n monitoring -c grafana | grep -i provisioning

Fehlt ein Dashboard oder eine Datenquelle, prüfe zuerst die Provisioning-Logzeilen, dann die Logs des Sidecars (-c grafana-sc-dashboard) auf Probleme mit Label oder Namespace.

Beliebte Anleitungen