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.
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
-
Grafana als Code betreiben: Das große Ganze Was in Dateien leben kann, was eine API braucht und wie die Teile zusammenpassen. -
Den Grafana-Server mit grafana.ini und Umgebungsvariablen konfigurieren Wisse, wo Konfigurationsdateien liegen, wie Überschreibungen geordnet sind und wie du Einstellungen in Git hältst. -
Dashboards aus JSON-Dateien provisionieren Lade Dashboards von der Platte, bilde Ordner aus Verzeichnissen ab und erstelle sie, ohne Änderungen zu verlieren. -
Alert-Regeln, Contact Points und Notification Policies provisionieren Definiere die gesamte Alerting-Pipeline in YAML, damit sie wie Code geprüft und versioniert wird. -
Provisioning von der Kommandozeile neu laden, prüfen und Fehler beheben Finde heraus, was Grafana geladen hat, lade ohne Neustart neu und behebe die üblichen Provisioning-Fehler.