Gestiona Grafana con el Grafana Operator
Declara instancias, carpetas, dashboards, data sources y reglas de alertas como recursos personalizados de Kubernetes.
El Grafana Operator convierte cada recurso de Grafana en un objeto de Kubernetes. Un GrafanaDashboard es un manifiesto, un GrafanaDatasource es un manifiesto, y el operator los reconcilia contra una instancia de Grafana a través de su API. Eso encaja de forma natural con herramientas GitOps como Flux y Argo CD, y funciona para instancias de Grafana dentro o fuera del clúster, incluido Grafana Cloud. Todos los recursos usan apiVersion: grafana.integreatly.org/v1beta1.
Instala el operator
Instálalo con Helm desde su chart OCI (consulta la documentación de instalación del operator para la ubicación y versión actuales del chart, y fíjala):
helm upgrade -i grafana-operator \
oci://ghcr.io/grafana/helm-charts/grafana-operator \
--namespace grafana --create-namespace \
--version <operator-version>
La documentación del operator también describe una instalación con Kustomize. Con Flux, pon el mismo chart en un HelmRelease.
Describe la instancia
Una instancia puede ser administrada (el operator despliega Grafana) o externa (se conecta a una que ya existe). Una instancia administrada:
apiVersion: grafana.integreatly.org/v1beta1
kind: Grafana
metadata:
name: grafana
namespace: grafana
labels:
dashboards: "grafana"
spec:
config:
log:
mode: console
security:
admin_user: root
admin_password: secret # solo como ejemplo; ver más abajo
Una instancia externa, como un stack de Grafana Cloud, apunta a una URL y toma un token de un Secret:
apiVersion: grafana.integreatly.org/v1beta1
kind: Grafana
metadata:
name: my-stack
namespace: grafana
labels:
dashboards: my-stack
spec:
external:
url: https://my-stack.grafana.net/
apiKey:
name: grafana-cloud-credentials
key: GRAFANA_CLOUD_INSTANCE_TOKEN
El bloque spec.config acepta las mismas secciones y claves que grafana.ini. No pongas una contraseña real en un manifiesto. La documentación del operator muestra cómo leer las credenciales de admin de un Secret.
Las etiquetas de la instancia importan: cada otro recurso selecciona su instancia de destino con instanceSelector.matchLabels, usando esas etiquetas.
Carpetas
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaFolder
metadata:
name: applications
spec:
instanceSelector:
matchLabels:
dashboards: "grafana"
title: Applications
uid: applications # define un UID estable para que otros recursos puedan referenciarlo
Si se omite title, toma por defecto metadata.name. Define spec.uid siempre que otros recursos apunten a la carpeta con folderRef, porque sin él el reconciliador puede adoptar una carpeta existente con el mismo nombre.
Data sources
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDatasource
metadata:
name: prometheus
spec:
instanceSelector:
matchLabels:
dashboards: "grafana"
datasource:
name: prometheus
type: prometheus
access: proxy
url: http://prometheus-service:9090
isDefault: true
jsonData:
timeInterval: 5s
Las credenciales vienen de un Secret en el mismo namespace mediante valuesFrom, así que nunca aparecen en el manifiesto:
apiVersion: v1
kind: Secret
metadata:
name: credentials
type: Opaque
stringData:
PROMETHEUS_USERNAME: grafana
PROMETHEUS_PASSWORD: change-me
---
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDatasource
metadata:
name: prometheus-secured
spec:
instanceSelector:
matchLabels:
dashboards: "grafana"
valuesFrom:
- targetPath: basicAuthUser
valueFrom:
secretKeyRef:
name: credentials
key: PROMETHEUS_USERNAME
- targetPath: secureJsonData.basicAuthPassword
valueFrom:
secretKeyRef:
name: credentials
key: PROMETHEUS_PASSWORD
datasource:
name: prometheus-secured
type: prometheus
access: proxy
basicAuth: true
url: http://prometheus-service:9090
secureJsonData:
basicAuthPassword: ${PROMETHEUS_PASSWORD}
No pongas credenciales en la url. Cifra o sincroniza el Secret con SOPS o External Secrets, como con cualquier Secret de Kubernetes.
Dashboards
Un GrafanaDashboard puede tomar su JSON de varias fuentes, que es la mayor fortaleza del operator:
# JSON en línea
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDashboard
metadata:
name: simple
spec:
resyncPeriod: 30s
instanceSelector:
matchLabels:
dashboards: "grafana"
folderRef: applications
json: >
{ "uid": "simple", "title": "Simple Dashboard", "panels": [] }
# desde un ConfigMap
spec:
instanceSelector:
matchLabels:
dashboards: "grafana"
configMapRef:
name: dashboard-definition
key: json
# desde una URL, como grafana.com o un archivo raw de Git
spec:
instanceSelector:
matchLabels:
dashboards: "grafana"
url: "https://grafana.com/api/dashboards/1860/revisions/30/download"
# desde un artefacto OCI
spec:
instanceSelector:
matchLabels:
dashboards: "grafana"
oci:
reference: ghcr.io/team-a/dashboards:v1.4.7
path: board.json
pullSecretRef:
name: ghcr-pull
Otros campos que usarás:
folderRefapunta a unGrafanaFolderpor nombre, yfolderUIDal UID de una carpeta existente.gzipJsoncontiene el dashboard como gzip codificado en base64 (cat dashboard.json | gzip | base64 -w0), para dashboards demasiado grandes para un manifiesto.variablessobrescribe variables de plantilla, por ejemplo para definir unnamespaceo un data source por entorno.resyncPeriodycontentCacheDurationcontrolan con qué frecuencia se vuelve a aplicar el contenido y durante cuánto tiempo se almacenan en caché las URL obtenidas.
Reglas de alertas
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaAlertRuleGroup
metadata:
name: webapp-alerts
spec:
folderRef: applications
instanceSelector:
matchLabels:
dashboards: "grafana"
interval: 5m
rules:
- uid: webapp-down
title: Webapp targets down
condition: C
for: 5m
noDataState: NoData
execErrState: Error
data:
- refId: A
# el paso de consulta a Prometheus, como en la guía de alertas
- refId: C
# el paso de expresión de umbral
Cada grupo de reglas necesita una carpeta y al menos una regla. Los pasos de datos usan la misma estructura que los archivos de provisioning, así que puedes reutilizar el YAML de la guía de alertas. El operator también tiene recursos para contact points; consulta sus ejemplos para la lista actual.
Opéralo
kubectl get grafanas,grafanafolders,grafanadatasources,grafanadashboards -A
kubectl describe grafanadashboard simple -n grafana
describe muestra las condiciones de estado del recurso, que indican si la última sincronización con Grafana tuvo éxito y por qué no, si falló. Causas comunes: un instanceSelector que no coincide con ninguna instancia, un token incorrecto o un Secret en el namespace equivocado.
¿Operator o provisioning por archivos?
Usa el Operator cuando ya ejecutes GitOps en Kubernetes, quieras que cada equipo sea dueño de sus dashboards y alertas como objetos separados, o gestiones Grafana Cloud o varias instancias. Usa los valores de provisioning del chart de Helm cuando tengas un solo Grafana y un puñado de recursos, ya que eso no añade ningún controlador adicional. Ambos pueden coexistir, pero deja que una sola herramienta sea dueña de cada recurso.
Guías populares
-
Opera Grafana como código: la visión de conjunto Qué puede vivir en archivos, qué necesita una API y cómo encajan las piezas. -
Configura el servidor de Grafana con grafana.ini y variables de entorno Sabe dónde viven los archivos de configuración, cómo se ordenan las sobrescrituras y cómo mantener los ajustes en Git. -
Provisiona dashboards desde archivos JSON Carga dashboards desde disco, asigna carpetas a partir de directorios y crea dashboards sin perder cambios. -
Provisiona reglas de alertas, contact points y políticas de notificación Define todo el pipeline de alertas en YAML para que se revise y versione como código. -
Despliega Grafana en Kubernetes con Helm y valores de provisioning Ejecuta Grafana desde un chart de Helm donde los data sources, dashboards y ajustes provienen de archivos de valores. -
Recarga, verifica y soluciona problemas de provisioning desde la línea de comandos Averigua qué cargó Grafana, recarga sin reiniciar y arregla los errores de provisioning más habituales.