Grafana Community Helm Charts
repository·main·Indexed 42 days ago
https://github.com/grafana-community/helm-chartsKubernetes Helm charts for various Grafana Community projects, including the core Grafana and grafana-mcp charts. Provides documentation on installation via OCI and HTTP registries, configuration via grafana.ini, and dynamic provisioning of dashboards, datasources, notifiers, and alerting resources using sidecar containers.
What's inside Grafana Community Helm Charts
- Grafana Cloud Synthetic Monitoring does not officially support this Helm chart. If you are a Grafana Cloud customer and require support, you should use the recommended installation methods found in the official Grafana documentation.
Scale down live-stores safely
mainScaling down
liveStore.replicasreduces the number of Kafka partitions managed. To prevent data loss or service interruption, use the following opt-in settings which require the rollout-operator admission webhooks:noDownscale: true: Rejects any scale-down attempt of the live-stores.prepareDownscale.enabled: true: Coordinates a staggered scale-down. It moves a partition toINACTIVEto stop writes, then waits forminTimeBetweenZonesDownscalebefore allowing the next zone to scale down. This ensures the read path remains intact until the last zone is removed.
liveStore: zoneAwareReplication: prepareDownscale: enabled: true minTimeBetweenZonesDownscale: 12hFollow versioning and breaking change guidelines
mainAll charts must follow Semantic Versioning (SemVer) in the format
MAJOR.MINOR.PATCH.- Bumping Versions: The
versionfield inChart.yamlmust be incremented for every release. - Breaking Changes: If a change is backwards-incompatible, you must bump the MAJOR version. Additionally, you must add a
### X.0.0subsection under the## Upgradingheading in the chart's README to document the breaking change.
- Bumping Versions: The
Understand Loki StatefulSet immutability and updates
mainMost fields in a Kubernetes
StatefulSetare immutable. Changing certain configuration values in yourvalues.yamlwill not take effect via a standardhelm upgradeunless specific conditions are met.Immutable Fields (Requires manual intervention or recreation)
The following fields cannot be updated via standard upgrade and are not covered by the experimental recreate job:
*.persistence.storageClass*.persistence.claims[].storageClass*.persistence.accessModes*.persistence.selector*.persistence.volumeAttributesClassName*.persistence.annotations- Chart-generated selector labels
Fields covered by the Recreate Job
If you enable the experimental recreate job, you can update certain fields. The job deletes the StatefulSet with
--cascade=orphanto allow the new spec to take effect.Supported updates via Recreate Job:
*.persistence.size(and cachepersistence.storageSize)*.podManagementPolicyserviceName(affected bynameOverrideorfullnameOverride)- Volume-claim count, claim name, or claim size (if
defaults.statefulSetRecreateJob.patchPVCistrue)
Note: The recreate job does not work for Memcached cache StatefulSets.
How zone-aware replication works for the live-store
mainIn a standard configuration, the live-store is a single flat StatefulSet where each Kafka partition has exactly one live-store instance. If that pod fails, recent-trace queries for that partition fail.
Zone-aware replication solves this by rendering one StatefulSet per zone. Each zone runs a full set of live-stores and consumes Kafka partitions independently. This ensures that the loss of a single zone does not break recent-trace queries.
Key requirements and behaviors:
- Rollout Operator: The chart requires a
rollout_operatorto coordinate rollouts and manageZoneAwarePodDisruptionBudget. The chart will refuse to render without it. - Replicas:
liveStore.replicasmust equal the Kafka partition count. This value represents the size of one zone, not the total count across all zones. - Topology: Use
topologyKey(e.g.,topology.kubernetes.io/zone) to ensure anti-affinity. At least 2 zones are required. - Switching on: Enabling zone-awareness replaces the flat StatefulSet with per-zone ones. This causes all live-stores to restart and requires them to replay the Kafka lookback period to rebuild state. Plan this as a full live-store restart.
rollout_operator: enabled: true liveStore: enabled: true replicas: 3 # partitions per zone; must equal the Kafka partition count zoneAwareReplication: enabled: true topologyKey: topology.kubernetes.io/zone zones: - name: zone-a nodeSelector: topology.kubernetes.io/zone: eu-west-1a - name: zone-b nodeSelector: topology.kubernetes.io/zone: eu-west-1b- Rollout Operator: The chart requires a
Use the Dashboard Sidecar for dynamic dashboard loading
mainWhen
sidecar.dashboards.enabledis set totrue, a sidecar container is deployed to watch ConfigMaps or Secrets in the cluster. It filters resources based on the label defined insidecar.dashboards.label.Files within the matching ConfigMaps/Secrets are written to a folder accessible by Grafana. Changes to the ConfigMap/Secret trigger updates or deletions in Grafana.
Recommendation: Use one ConfigMap per dashboard to ensure proper mirroring.
Example ConfigMap
apiVersion: v1 kind: ConfigMap metadata: name: sample-grafana-dashboard labels: grafana_dashboard: "1" data: k8s-dashboard.json: |- # Dashboard JSON content hereUse recommended Kubernetes labels and selectors
mainWhen writing templates, follow these labeling standards:
- Standard Labels: Use the recommended
app.kubernetes.io/*labels (e.g.,app.kubernetes.io/name,app.kubernetes.io/instance). - Selector Immutability: Do not include
helm.sh/chartinspec.selector.matchLabels. Because Kubernetes selectors are immutable after creation, including the chart version in the selector will prevent successful upgrades.
- Standard Labels: Use the recommended
Manage node draining with ZoneAwarePodDisruptionBudget
mainWhen using zone-aware replication, standard PodDisruptionBudgets (PDB) are insufficient because they cannot express that an eviction should be coordinated across zones per partition.
The chart renders a
ZoneAwarePodDisruptionBudgetenforced by the rollout-operator. This budget ensures that a drain takes at mostmaxUnavailablelive-stores per partition across all zones, preventing the last owner of a partition from being evicted.If your live-stores use the default
readiness-target-lagof 0, you should setcrossZoneEvictionDelayto allow time for the live-store to finish replaying its partition before it is considered ready.liveStore: zoneAwareReplication: podDisruptionBudget: enabled: true maxUnavailable: 1 # If using default readiness-target-lag of 0: # liveStore.zoneAwareReplication.podDisruptionBudget.crossZoneEvictionDelay: 20mUse the Datasource Sidecar for dynamic datasource provisioning
mainWhen
sidecar.datasources.enabledis set totrue, an init container is deployed. It watches Secrets (recommended) or ConfigMaps for resources matching the label insidecar.datasources.label. The files are written to a folder and imported into Grafana on startup.Reloading Datasources: To reload datasources automatically when a Secret changes, set
sidecar.datasources.skipReload: falseand provide asidecar.datasources.reloadURL(e.g.,http://<svc-name>.<namespace>.svc.cluster.local/api/admin/provisioning/datasources/reload).Example Secret for Postgres Datasource
apiVersion: v1 kind: Secret metadata: name: grafana-datasources labels: grafana_datasource: 'true' stringData: pg-db.yaml: | apiVersion: 1 datasources: - name: My pg db datasource type: postgres url: my-postgresql-db:5432 user: db-readonly-user secureJsonData: password: 'SUperSEcretPa$$word' jsonData: database: my_datase sslmode: 'disable' editable: falseConfigure Tempo Distributed components
mainThe
tempo-distributedHelm chart installs a set of core components by default, while other specialized components are optional and must be explicitly enabled via their respectiveenabledflags.Always Installed:
distributor: Writes spans to Kafka in Tempo 3.0.querier: Handles query execution.query-frontend: Manages query requests.
Optional Components: To use these, you must set their
enabledkey totruein yourvalues.yaml:backend-scheduler(backendScheduler.enabled): Required for compaction and retention.backend-worker: Automatically enabled whenbackend-scheduleris active; executes compaction jobs.block-builder(blockBuilder.enabled): Consumes from Kafka and writes blocks to object storage.live-store(liveStore.enabled): Consumes from Kafka and serves recent-data queries.metrics-generator: Generates metrics from traces.memcached: Provides caching.memcached-exporter: Exports metrics for Memcached.gateway: Provides an entry point for requests.rollout-operator: Manages rollout processes.
# Example enabling optional components backendScheduler: enabled: true blockBuilder: enabled: true liveStore: enabled: true metricsGenerator: enabled: trueUpgrade Tempo Chart from versions < 0.7.0
mainUpgrading from versions older than 0.7.0 changes the default trace storage path from
/tmp/tempo/tracesto/var/tempo/traces.Warning: This change will cause Tempo to lose trace history. To retain history, manually copy the contents from the old folder to the new folder before upgrading.
Migrate or retain built-in MinIO during upgrade
mainThe built-in MinIO subchart has been removed in Tempo 3.0. Setting
minio.enabled: truewill now cause a render failure.Option 1: Migrate to external S3 storage
Deploy MinIO (or another S3-compatible store) separately and configure Tempo via
storage.trace.s3.Option 2: Keep existing built-in MinIO running (Manual Detachment)
If you used
minio.enabled: true, a standardhelm upgradewill delete the MinIO resources and your data. To prevent this, you must annotate the MinIO resources withhelm.sh/resource-policy: keepto detach them from the Helm release before upgrading.- Annotate resources:
# RELEASE and NAMESPACE are your existing tempo-distributed install. for kind in deployment service secret pvc serviceaccount; do kubectl -n "$NAMESPACE" annotate "$kind" \ -l app=minio,release="$RELEASE" \ helm.sh/resource-policy=keep --overwrite done- Verify annotations (especially on the PVC):
kubectl -n "$NAMESPACE" get deploy,svc,secret,pvc,sa -l app=minio,release="$RELEASE" \ -o jsonpath='{range .items[*]}{.kind}/{.metadata.name}: {.metadata.annotations.helm\.sh/resource-policy}{"\n"}{end}'- Update values: Remove the
minio:block and point Tempo to the surviving MinIO service using thestorage.trace.s3configuration.