From bde875cc8982d9f2f1f0cc152af5238b04b80516 Mon Sep 17 00:00:00 2001 From: AvivGuiser Date: Tue, 14 Jan 2025 19:22:19 +0200 Subject: [PATCH 1/6] add session affinity config Signed-off-by: AvivGuiser --- charts/grafana/Chart.yaml | 2 +- charts/grafana/README.md | 1155 ++++++++----------------- charts/grafana/templates/service.yaml | 3 + charts/grafana/values.yaml | 1 + 4 files changed, 377 insertions(+), 784 deletions(-) diff --git a/charts/grafana/Chart.yaml b/charts/grafana/Chart.yaml index 9deccc3ff6..c570d934f1 100644 --- a/charts/grafana/Chart.yaml +++ b/charts/grafana/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v2 name: grafana -version: 8.8.2 +version: 8.8.3 appVersion: 11.4.0 kubeVersion: "^1.8.0-0" description: The leading tool for querying and visualizing time series and metrics. diff --git a/charts/grafana/README.md b/charts/grafana/README.md index a78b123605..c26784b919 100644 --- a/charts/grafana/README.md +++ b/charts/grafana/README.md @@ -1,783 +1,372 @@ -# Grafana Helm Chart - -* Installs the web dashboarding system [Grafana](http://grafana.org/) - -## Get Repo Info - -```console -helm repo add grafana https://grafana.github.io/helm-charts -helm repo update -``` - -_See [helm repo](https://helm.sh/docs/helm/helm_repo/) for command documentation._ - -## Installing the Chart - -To install the chart with the release name `my-release`: - -```console -helm install my-release grafana/grafana -``` - -## Uninstalling the Chart - -To uninstall/delete the my-release deployment: - -```console -helm delete my-release -``` - -The command removes all the Kubernetes components associated with the chart and deletes the release. - -## Upgrading an existing Release to a new major version - -A major chart version change (like v1.2.3 -> v2.0.0) indicates that there is an -incompatible breaking change needing manual actions. - -### To 4.0.0 (And 3.12.1) - -This version requires Helm >= 2.12.0. - -### To 5.0.0 - -You have to add --force to your helm upgrade command as the labels of the chart have changed. - -### To 6.0.0 - -This version requires Helm >= 3.1.0. - -### To 7.0.0 - -For consistency with other Helm charts, the `global.image.registry` parameter was renamed -to `global.imageRegistry`. If you were not previously setting `global.image.registry`, no action -is required on upgrade. If you were previously setting `global.image.registry`, you will -need to instead set `global.imageRegistry`. - -## Configuration - -| Parameter | Description | Default | -|-------------------------------------------|-----------------------------------------------|---------------------------------------------------------| -| `replicas` | Number of nodes | `1` | -| `podDisruptionBudget.minAvailable` | Pod disruption minimum available | `nil` | -| `podDisruptionBudget.maxUnavailable` | Pod disruption maximum unavailable | `nil` | -| `podDisruptionBudget.apiVersion` | Pod disruption apiVersion | `nil` | -| `deploymentStrategy` | Deployment strategy | `{ "type": "RollingUpdate" }` | -| `livenessProbe` | Liveness Probe settings | `{ "httpGet": { "path": "/api/health", "port": 3000 } "initialDelaySeconds": 60, "timeoutSeconds": 30, "failureThreshold": 10 }` | -| `readinessProbe` | Readiness Probe settings | `{ "httpGet": { "path": "/api/health", "port": 3000 } }`| -| `securityContext` | Deployment securityContext | `{"runAsUser": 472, "runAsGroup": 472, "fsGroup": 472}` | -| `priorityClassName` | Name of Priority Class to assign pods | `nil` | -| `image.registry` | Image registry | `docker.io` | -| `image.repository` | Image repository | `grafana/grafana` | -| `image.tag` | Overrides the Grafana image tag whose default is the chart appVersion (`Must be >= 5.0.0`) | `` | -| `image.sha` | Image sha (optional) | `` | -| `image.pullPolicy` | Image pull policy | `IfNotPresent` | -| `image.pullSecrets` | Image pull secrets (can be templated) | `[]` | -| `service.enabled` | Enable grafana service | `true` | -| `service.ipFamilies` | Kubernetes service IP families | `[]` | -| `service.ipFamilyPolicy` | Kubernetes service IP family policy | `""` | -| `service.type` | Kubernetes service type | `ClusterIP` | -| `service.port` | Kubernetes port where service is exposed | `80` | -| `service.portName` | Name of the port on the service | `service` | -| `service.appProtocol` | Adds the appProtocol field to the service | `` | -| `service.targetPort` | Internal service is port | `3000` | -| `service.nodePort` | Kubernetes service nodePort | `nil` | -| `service.annotations` | Service annotations (can be templated) | `{}` | -| `service.labels` | Custom labels | `{}` | -| `service.clusterIP` | internal cluster service IP | `nil` | -| `service.loadBalancerIP` | IP address to assign to load balancer (if supported) | `nil` | -| `service.loadBalancerSourceRanges` | list of IP CIDRs allowed access to lb (if supported) | `[]` | -| `service.externalIPs` | service external IP addresses | `[]` | -| `service.externalTrafficPolicy` | change the default externalTrafficPolicy | `nil` | -| `headlessService` | Create a headless service | `false` | -| `extraExposePorts` | Additional service ports for sidecar containers| `[]` | -| `hostAliases` | adds rules to the pod's /etc/hosts | `[]` | -| `ingress.enabled` | Enables Ingress | `false` | -| `ingress.annotations` | Ingress annotations (values are templated) | `{}` | -| `ingress.labels` | Custom labels | `{}` | -| `ingress.path` | Ingress accepted path | `/` | -| `ingress.pathType` | Ingress type of path | `Prefix` | -| `ingress.hosts` | Ingress accepted hostnames | `["chart-example.local"]` | -| `ingress.extraPaths` | Ingress extra paths to prepend to every host configuration. Useful when configuring [custom actions with AWS ALB Ingress Controller](https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.6/guide/ingress/annotations/#actions). Requires `ingress.hosts` to have one or more host entries. | `[]` | -| `ingress.tls` | Ingress TLS configuration | `[]` | -| `ingress.ingressClassName` | Ingress Class Name. MAY be required for Kubernetes versions >= 1.18 | `""` | -| `resources` | CPU/Memory resource requests/limits | `{}` | -| `nodeSelector` | Node labels for pod assignment | `{}` | -| `tolerations` | Toleration labels for pod assignment | `[]` | -| `affinity` | Affinity settings for pod assignment | `{}` | -| `extraInitContainers` | Init containers to add to the grafana pod | `{}` | -| `extraContainers` | Sidecar containers to add to the grafana pod | `""` | -| `extraContainerVolumes` | Volumes that can be mounted in sidecar containers | `[]` | -| `extraLabels` | Custom labels for all manifests | `{}` | -| `schedulerName` | Name of the k8s scheduler (other than default) | `nil` | -| `persistence.enabled` | Use persistent volume to store data | `false` | -| `persistence.type` | Type of persistence (`pvc` or `statefulset`) | `pvc` | -| `persistence.size` | Size of persistent volume claim | `10Gi` | -| `persistence.existingClaim` | Use an existing PVC to persist data (can be templated) | `nil` | -| `persistence.storageClassName` | Type of persistent volume claim | `nil` | -| `persistence.accessModes` | Persistence access modes | `[ReadWriteOnce]` | -| `persistence.annotations` | PersistentVolumeClaim annotations | `{}` | -| `persistence.finalizers` | PersistentVolumeClaim finalizers | `[ "kubernetes.io/pvc-protection" ]` | -| `persistence.extraPvcLabels` | Extra labels to apply to a PVC. | `{}` | -| `persistence.subPath` | Mount a sub dir of the persistent volume (can be templated) | `nil` | -| `persistence.inMemory.enabled` | If persistence is not enabled, whether to mount the local storage in-memory to improve performance | `false` | -| `persistence.inMemory.sizeLimit` | SizeLimit for the in-memory local storage | `nil` | -| `persistence.disableWarning` | Hide NOTES warning, useful when persisting to a database | `false` | -| `initChownData.enabled` | If false, don't reset data ownership at startup | true | -| `initChownData.image.registry` | init-chown-data container image registry | `docker.io` | -| `initChownData.image.repository` | init-chown-data container image repository | `busybox` | -| `initChownData.image.tag` | init-chown-data container image tag | `1.31.1` | -| `initChownData.image.sha` | init-chown-data container image sha (optional)| `""` | -| `initChownData.image.pullPolicy` | init-chown-data container image pull policy | `IfNotPresent` | -| `initChownData.resources` | init-chown-data pod resource requests & limits | `{}` | -| `schedulerName` | Alternate scheduler name | `nil` | -| `env` | Extra environment variables passed to pods | `{}` | -| `envValueFrom` | Environment variables from alternate sources. See the API docs on [EnvVarSource](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#envvarsource-v1-core) for format details. Can be templated | `{}` | -| `envFromSecret` | Name of a Kubernetes secret (must be manually created in the same namespace) containing values to be added to the environment. Can be templated | `""` | -| `envFromSecrets` | List of Kubernetes secrets (must be manually created in the same namespace) containing values to be added to the environment. Can be templated | `[]` | -| `envFromConfigMaps` | List of Kubernetes ConfigMaps (must be manually created in the same namespace) containing values to be added to the environment. Can be templated | `[]` | -| `envRenderSecret` | Sensible environment variables passed to pods and stored as secret. (passed through [tpl](https://helm.sh/docs/howto/charts_tips_and_tricks/#using-the-tpl-function)) | `{}` | -| `enableServiceLinks` | Inject Kubernetes services as environment variables. | `true` | -| `extraSecretMounts` | Additional grafana server secret mounts | `[]` | -| `extraVolumeMounts` | Additional grafana server volume mounts | `[]` | -| `extraVolumes` | Additional Grafana server volumes | `[]` | -| `automountServiceAccountToken` | Mounted the service account token on the grafana pod. Mandatory, if sidecars are enabled | `true` | -| `createConfigmap` | Enable creating the grafana configmap | `true` | -| `extraConfigmapMounts` | Additional grafana server configMap volume mounts (values are templated) | `[]` | -| `extraEmptyDirMounts` | Additional grafana server emptyDir volume mounts | `[]` | -| `plugins` | Plugins to be loaded along with Grafana | `[]` | -| `datasources` | Configure grafana datasources (passed through tpl) | `{}` | -| `alerting` | Configure grafana alerting (passed through tpl) | `{}` | -| `notifiers` | Configure grafana notifiers | `{}` | -| `dashboardProviders` | Configure grafana dashboard providers | `{}` | -| `dashboards` | Dashboards to import | `{}` | -| `dashboardsConfigMaps` | ConfigMaps reference that contains dashboards | `{}` | -| `grafana.ini` | Grafana's primary configuration | `{}` | -| `global.imageRegistry` | Global image pull registry for all images. | `null` | -| `global.imagePullSecrets` | Global image pull secrets (can be templated). Allows either an array of {name: pullSecret} maps (k8s-style), or an array of strings (more common helm-style). | `[]` | -| `ldap.enabled` | Enable LDAP authentication | `false` | -| `ldap.existingSecret` | The name of an existing secret containing the `ldap.toml` file, this must have the key `ldap-toml`. | `""` | -| `ldap.config` | Grafana's LDAP configuration | `""` | -| `annotations` | Deployment annotations | `{}` | -| `labels` | Deployment labels | `{}` | -| `podAnnotations` | Pod annotations | `{}` | -| `podLabels` | Pod labels | `{}` | -| `podPortName` | Name of the grafana port on the pod | `grafana` | -| `lifecycleHooks` | Lifecycle hooks for podStart and preStop [Example](https://kubernetes.io/docs/tasks/configure-pod-container/attach-handler-lifecycle-event/#define-poststart-and-prestop-handlers) | `{}` | -| `sidecar.image.registry` | Sidecar image registry | `quay.io` | -| `sidecar.image.repository` | Sidecar image repository | `kiwigrid/k8s-sidecar` | -| `sidecar.image.tag` | Sidecar image tag | `1.28.0` | -| `sidecar.image.sha` | Sidecar image sha (optional) | `""` | -| `sidecar.imagePullPolicy` | Sidecar image pull policy | `IfNotPresent` | -| `sidecar.resources` | Sidecar resources | `{}` | -| `sidecar.securityContext` | Sidecar securityContext | `{}` | -| `sidecar.enableUniqueFilenames` | Sets the kiwigrid/k8s-sidecar UNIQUE_FILENAMES environment variable. If set to `true` the sidecar will create unique filenames where duplicate data keys exist between ConfigMaps and/or Secrets within the same or multiple Namespaces. | `false` | -| `sidecar.alerts.enabled` | Enables the cluster wide search for alerts and adds/updates/deletes them in grafana |`false` | -| `sidecar.alerts.label` | Label that config maps with alerts should have to be added | `grafana_alert` | -| `sidecar.alerts.labelValue` | Label value that config maps with alerts should have to be added | `""` | -| `sidecar.alerts.searchNamespace` | Namespaces list. If specified, the sidecar will search for alerts config-maps inside these namespaces. Otherwise the namespace in which the sidecar is running will be used. It's also possible to specify ALL to search in all namespaces. | `nil` | -| `sidecar.alerts.watchMethod` | Method to use to detect ConfigMap changes. With WATCH the sidecar will do a WATCH requests, with SLEEP it will list all ConfigMaps, then sleep for 60 seconds. | `WATCH` | -| `sidecar.alerts.resource` | Should the sidecar looks into secrets, configmaps or both. | `both` | -| `sidecar.alerts.reloadURL` | Full url of datasource configuration reload API endpoint, to invoke after a config-map change | `"http://localhost:3000/api/admin/provisioning/alerting/reload"` | -| `sidecar.alerts.skipReload` | Enabling this omits defining the REQ_URL and REQ_METHOD environment variables | `false` | -| `sidecar.alerts.initAlerts` | Set to true to deploy the alerts sidecar as an initContainer. This is needed if skipReload is true, to load any alerts defined at startup time. | `false` | -| `sidecar.alerts.extraMounts` | Additional alerts sidecar volume mounts. | `[]` | -| `sidecar.dashboards.enabled` | Enables the cluster wide search for dashboards and adds/updates/deletes them in grafana | `false` | -| `sidecar.dashboards.SCProvider` | Enables creation of sidecar provider | `true` | -| `sidecar.dashboards.provider.name` | Unique name of the grafana provider | `sidecarProvider` | -| `sidecar.dashboards.provider.orgid` | Id of the organisation, to which the dashboards should be added | `1` | -| `sidecar.dashboards.provider.folder` | Logical folder in which grafana groups dashboards | `""` | -| `sidecar.dashboards.provider.folderUid` | Allows you to specify the static UID for the logical folder above | `""` | -| `sidecar.dashboards.provider.disableDelete` | Activate to avoid the deletion of imported dashboards | `false` | -| `sidecar.dashboards.provider.allowUiUpdates` | Allow updating provisioned dashboards from the UI | `false` | -| `sidecar.dashboards.provider.type` | Provider type | `file` | -| `sidecar.dashboards.provider.foldersFromFilesStructure` | Allow Grafana to replicate dashboard structure from filesystem. | `false` | -| `sidecar.dashboards.watchMethod` | Method to use to detect ConfigMap changes. With WATCH the sidecar will do a WATCH requests, with SLEEP it will list all ConfigMaps, then sleep for 60 seconds. | `WATCH` | -| `sidecar.skipTlsVerify` | Set to true to skip tls verification for kube api calls | `nil` | -| `sidecar.dashboards.label` | Label that config maps with dashboards should have to be added | `grafana_dashboard` | -| `sidecar.dashboards.labelValue` | Label value that config maps with dashboards should have to be added | `""` | -| `sidecar.dashboards.folder` | Folder in the pod that should hold the collected dashboards (unless `sidecar.dashboards.defaultFolderName` is set). This path will be mounted. | `/tmp/dashboards` | -| `sidecar.dashboards.folderAnnotation` | The annotation the sidecar will look for in configmaps to override the destination folder for files | `nil` | -| `sidecar.dashboards.defaultFolderName` | The default folder name, it will create a subfolder under the `sidecar.dashboards.folder` and put dashboards in there instead | `nil` | -| `sidecar.dashboards.searchNamespace` | Namespaces list. If specified, the sidecar will search for dashboards config-maps inside these namespaces. Otherwise the namespace in which the sidecar is running will be used. It's also possible to specify ALL to search in all namespaces. | `nil` | -| `sidecar.dashboards.script` | Absolute path to shell script to execute after a configmap got reloaded. | `nil` | -| `sidecar.dashboards.reloadURL` | Full url of dashboards configuration reload API endpoint, to invoke after a config-map change | `"http://localhost:3000/api/admin/provisioning/dashboards/reload"` | -| `sidecar.dashboards.skipReload` | Enabling this omits defining the REQ_USERNAME, REQ_PASSWORD, REQ_URL and REQ_METHOD environment variables | `false` | -| `sidecar.dashboards.resource` | Should the sidecar looks into secrets, configmaps or both. | `both` | -| `sidecar.dashboards.extraMounts` | Additional dashboard sidecar volume mounts. | `[]` | -| `sidecar.datasources.enabled` | Enables the cluster wide search for datasources and adds/updates/deletes them in grafana |`false` | -| `sidecar.datasources.label` | Label that config maps with datasources should have to be added | `grafana_datasource` | -| `sidecar.datasources.labelValue` | Label value that config maps with datasources should have to be added | `""` | -| `sidecar.datasources.searchNamespace` | Namespaces list. If specified, the sidecar will search for datasources config-maps inside these namespaces. Otherwise the namespace in which the sidecar is running will be used. It's also possible to specify ALL to search in all namespaces. | `nil` | -| `sidecar.datasources.watchMethod` | Method to use to detect ConfigMap changes. With WATCH the sidecar will do a WATCH requests, with SLEEP it will list all ConfigMaps, then sleep for 60 seconds. | `WATCH` | -| `sidecar.datasources.resource` | Should the sidecar looks into secrets, configmaps or both. | `both` | -| `sidecar.datasources.reloadURL` | Full url of datasource configuration reload API endpoint, to invoke after a config-map change | `"http://localhost:3000/api/admin/provisioning/datasources/reload"` | -| `sidecar.datasources.skipReload` | Enabling this omits defining the REQ_URL and REQ_METHOD environment variables | `false` | -| `sidecar.datasources.initDatasources` | Set to true to deploy the datasource sidecar as an initContainer in addition to a container. This is needed if skipReload is true, to load any datasources defined at startup time. | `false` | -| `sidecar.notifiers.enabled` | Enables the cluster wide search for notifiers and adds/updates/deletes them in grafana | `false` | -| `sidecar.notifiers.label` | Label that config maps with notifiers should have to be added | `grafana_notifier` | -| `sidecar.notifiers.labelValue` | Label value that config maps with notifiers should have to be added | `""` | -| `sidecar.notifiers.searchNamespace` | Namespaces list. If specified, the sidecar will search for notifiers config-maps (or secrets) inside these namespaces. Otherwise the namespace in which the sidecar is running will be used. It's also possible to specify ALL to search in all namespaces. | `nil` | -| `sidecar.notifiers.watchMethod` | Method to use to detect ConfigMap changes. With WATCH the sidecar will do a WATCH requests, with SLEEP it will list all ConfigMaps, then sleep for 60 seconds. | `WATCH` | -| `sidecar.notifiers.resource` | Should the sidecar looks into secrets, configmaps or both. | `both` | -| `sidecar.notifiers.reloadURL` | Full url of notifier configuration reload API endpoint, to invoke after a config-map change | `"http://localhost:3000/api/admin/provisioning/notifications/reload"` | -| `sidecar.notifiers.skipReload` | Enabling this omits defining the REQ_URL and REQ_METHOD environment variables | `false` | -| `sidecar.notifiers.initNotifiers` | Set to true to deploy the notifier sidecar as an initContainer in addition to a container. This is needed if skipReload is true, to load any notifiers defined at startup time. | `false` | -| `smtp.existingSecret` | The name of an existing secret containing the SMTP credentials. | `""` | -| `smtp.userKey` | The key in the existing SMTP secret containing the username. | `"user"` | -| `smtp.passwordKey` | The key in the existing SMTP secret containing the password. | `"password"` | -| `admin.existingSecret` | The name of an existing secret containing the admin credentials (can be templated). | `""` | -| `admin.userKey` | The key in the existing admin secret containing the username. | `"admin-user"` | -| `admin.passwordKey` | The key in the existing admin secret containing the password. | `"admin-password"` | -| `serviceAccount.automountServiceAccountToken` | Automount the service account token on all pods where is service account is used | `false` | -| `serviceAccount.annotations` | ServiceAccount annotations | | -| `serviceAccount.create` | Create service account | `true` | -| `serviceAccount.labels` | ServiceAccount labels | `{}` | -| `serviceAccount.name` | Service account name to use, when empty will be set to created account if `serviceAccount.create` is set else to `default` | `` | -| `serviceAccount.nameTest` | Service account name to use for test, when empty will be set to created account if `serviceAccount.create` is set else to `default` | `nil` | -| `rbac.create` | Create and use RBAC resources | `true` | -| `rbac.namespaced` | Creates Role and Rolebinding instead of the default ClusterRole and ClusteRoleBindings for the grafana instance | `false` | -| `rbac.useExistingRole` | Set to a rolename to use existing role - skipping role creating - but still doing serviceaccount and rolebinding to the rolename set here. | `nil` | -| `rbac.pspEnabled` | Create PodSecurityPolicy (with `rbac.create`, grant roles permissions as well) | `false` | -| `rbac.pspUseAppArmor` | Enforce AppArmor in created PodSecurityPolicy (requires `rbac.pspEnabled`) | `false` | -| `rbac.extraRoleRules` | Additional rules to add to the Role | [] | -| `rbac.extraClusterRoleRules` | Additional rules to add to the ClusterRole | [] | -| `command` | Define command to be executed by grafana container at startup | `nil` | -| `args` | Define additional args if command is used | `nil` | -| `testFramework.enabled` | Whether to create test-related resources | `true` | -| `testFramework.image.registry` | `test-framework` image registry. | `docker.io` | -| `testFramework.image.repository` | `test-framework` image repository. | `bats/bats` | -| `testFramework.image.tag` | `test-framework` image tag. | `v1.4.1` | -| `testFramework.imagePullPolicy` | `test-framework` image pull policy. | `IfNotPresent` | -| `testFramework.securityContext` | `test-framework` securityContext | `{}` | -| `downloadDashboards.env` | Environment variables to be passed to the `download-dashboards` container | `{}` | -| `downloadDashboards.envFromSecret` | Name of a Kubernetes secret (must be manually created in the same namespace) containing values to be added to the environment. Can be templated | `""` | -| `downloadDashboards.resources` | Resources of `download-dashboards` container | `{}` | -| `downloadDashboardsImage.registry` | Curl docker image registry | `docker.io` | -| `downloadDashboardsImage.repository` | Curl docker image repository | `curlimages/curl` | -| `downloadDashboardsImage.tag` | Curl docker image tag | `7.73.0` | -| `downloadDashboardsImage.sha` | Curl docker image sha (optional) | `""` | -| `downloadDashboardsImage.pullPolicy` | Curl docker image pull policy | `IfNotPresent` | -| `namespaceOverride` | Override the deployment namespace | `""` (`Release.Namespace`) | -| `serviceMonitor.enabled` | Use servicemonitor from prometheus operator | `false` | -| `serviceMonitor.namespace` | Namespace this servicemonitor is installed in | | -| `serviceMonitor.interval` | How frequently Prometheus should scrape | `1m` | -| `serviceMonitor.path` | Path to scrape | `/metrics` | -| `serviceMonitor.scheme` | Scheme to use for metrics scraping | `http` | -| `serviceMonitor.tlsConfig` | TLS configuration block for the endpoint | `{}` | -| `serviceMonitor.labels` | Labels for the servicemonitor passed to Prometheus Operator | `{}` | -| `serviceMonitor.scrapeTimeout` | Timeout after which the scrape is ended | `30s` | -| `serviceMonitor.relabelings` | RelabelConfigs to apply to samples before scraping. | `[]` | -| `serviceMonitor.metricRelabelings` | MetricRelabelConfigs to apply to samples before ingestion. | `[]` | -| `revisionHistoryLimit` | Number of old ReplicaSets to retain | `10` | -| `imageRenderer.enabled` | Enable the image-renderer deployment & service | `false` | -| `imageRenderer.image.registry` | image-renderer Image registry | `docker.io` | -| `imageRenderer.image.repository` | image-renderer Image repository | `grafana/grafana-image-renderer` | -| `imageRenderer.image.tag` | image-renderer Image tag | `latest` | -| `imageRenderer.image.sha` | image-renderer Image sha (optional) | `""` | -| `imageRenderer.image.pullPolicy` | image-renderer ImagePullPolicy | `Always` | -| `imageRenderer.env` | extra env-vars for image-renderer | `{}` | -| `imageRenderer.envValueFrom` | Environment variables for image-renderer from alternate sources. See the API docs on [EnvVarSource](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#envvarsource-v1-core) for format details. Can be templated | `{}` | -| `imageRenderer.extraConfigmapMounts` | Additional image-renderer configMap volume mounts (values are templated) | `[]` | -| `imageRenderer.extraSecretMounts` | Additional image-renderer secret volume mounts | `[]` | -| `imageRenderer.extraVolumeMounts` | Additional image-renderer volume mounts | `[]` | -| `imageRenderer.extraVolumes` | Additional image-renderer volumes | `[]` | -| `imageRenderer.serviceAccountName` | image-renderer deployment serviceAccountName | `""` | -| `imageRenderer.securityContext` | image-renderer deployment securityContext | `{}` | -| `imageRenderer.podAnnotations` | image-renderer image-renderer pod annotation | `{}` | -| `imageRenderer.hostAliases` | image-renderer deployment Host Aliases | `[]` | -| `imageRenderer.priorityClassName` | image-renderer deployment priority class | `''` | -| `imageRenderer.service.enabled` | Enable the image-renderer service | `true` | -| `imageRenderer.service.portName` | image-renderer service port name | `http` | -| `imageRenderer.service.port` | image-renderer port used by deployment | `8081` | -| `imageRenderer.service.targetPort` | image-renderer service port used by service | `8081` | -| `imageRenderer.appProtocol` | Adds the appProtocol field to the service | `` | -| `imageRenderer.grafanaSubPath` | Grafana sub path to use for image renderer callback url | `''` | -| `imageRenderer.serverURL` | Remote image renderer url | `''` | -| `imageRenderer.renderingCallbackURL` | Callback url for the Grafana image renderer | `''` | -| `imageRenderer.podPortName` | name of the image-renderer port on the pod | `http` | -| `imageRenderer.revisionHistoryLimit` | number of image-renderer replica sets to keep | `10` | -| `imageRenderer.networkPolicy.limitIngress` | Enable a NetworkPolicy to limit inbound traffic from only the created grafana pods | `true` | -| `imageRenderer.networkPolicy.limitEgress` | Enable a NetworkPolicy to limit outbound traffic to only the created grafana pods | `false` | -| `imageRenderer.resources` | Set resource limits for image-renderer pods | `{}` | -| `imageRenderer.nodeSelector` | Node labels for pod assignment | `{}` | -| `imageRenderer.tolerations` | Toleration labels for pod assignment | `[]` | -| `imageRenderer.affinity` | Affinity settings for pod assignment | `{}` | -| `networkPolicy.enabled` | Enable creation of NetworkPolicy resources. | `false` | -| `networkPolicy.allowExternal` | Don't require client label for connections | `true` | -| `networkPolicy.explicitNamespacesSelector` | A Kubernetes LabelSelector to explicitly select namespaces from which traffic could be allowed | `{}` | -| `networkPolicy.ingress` | Enable the creation of an ingress network policy | `true` | -| `networkPolicy.egress.enabled` | Enable the creation of an egress network policy | `false` | -| `networkPolicy.egress.ports` | An array of ports to allow for the egress | `[]` | -| `enableKubeBackwardCompatibility` | Enable backward compatibility of kubernetes where pod's defintion version below 1.13 doesn't have the enableServiceLinks option | `false` | - -### Example ingress with path - -With grafana 6.3 and above - -```yaml -grafana.ini: - server: - domain: monitoring.example.com - root_url: "%(protocol)s://%(domain)s/grafana" - serve_from_sub_path: true -ingress: - enabled: true - hosts: - - "monitoring.example.com" - path: "/grafana" -``` - -### Example of extraVolumeMounts and extraVolumes - -Configure additional volumes with `extraVolumes` and volume mounts with `extraVolumeMounts`. - -Example for `extraVolumeMounts` and corresponding `extraVolumes`: - -```yaml -extraVolumeMounts: - - name: plugins - mountPath: /var/lib/grafana/plugins - subPath: configs/grafana/plugins - readOnly: false - - name: dashboards - mountPath: /var/lib/grafana/dashboards - hostPath: /usr/shared/grafana/dashboards - readOnly: false - -extraVolumes: - - name: plugins - existingClaim: existing-grafana-claim - - name: dashboards - hostPath: /usr/shared/grafana/dashboards -``` - -Volumes default to `emptyDir`. Set to `persistentVolumeClaim`, -`hostPath`, `csi`, or `configMap` for other types. For a -`persistentVolumeClaim`, specify an existing claim name with -`existingClaim`. - -## Import dashboards - -There are a few methods to import dashboards to Grafana. Below are some examples and explanations as to how to use each method: - -```yaml -dashboards: - default: - some-dashboard: - json: | - { - "annotations": - - ... - # Complete json file here - ... - - "title": "Some Dashboard", - "uid": "abcd1234", - "version": 1 - } - custom-dashboard: - # This is a path to a file inside the dashboards directory inside the chart directory - file: dashboards/custom-dashboard.json - prometheus-stats: - # Ref: https://grafana.com/dashboards/2 - gnetId: 2 - revision: 2 - datasource: Prometheus - loki-dashboard-quick-search: - gnetId: 12019 - revision: 2 - datasource: - - name: DS_PROMETHEUS - value: Prometheus - - name: DS_LOKI - value: Loki - local-dashboard: - url: https://raw.githubusercontent.com/user/repository/master/dashboards/dashboard.json -``` - -## BASE64 dashboards - -Dashboards could be stored on a server that does not return JSON directly and instead of it returns a Base64 encoded file (e.g. Gerrit) -A new parameter has been added to the url use case so if you specify a b64content value equals to true after the url entry a Base64 decoding is applied before save the file to disk. -If this entry is not set or is equals to false not decoding is applied to the file before saving it to disk. - -### Gerrit use case - -Gerrit API for download files has the following schema: where {project-name} and -{file-id} usually has '/' in their values and so they MUST be replaced by %2F so if project-name is user/repo, branch-id is master and file-id is equals to dir1/dir2/dashboard -the url value is - -## Sidecar for dashboards - -If the parameter `sidecar.dashboards.enabled` is set, a sidecar container is deployed in the grafana -pod. This container watches all configmaps (or secrets) in the cluster and filters out the ones with -a label as defined in `sidecar.dashboards.label`. The files defined in those configmaps are written -to a folder and accessed by grafana. Changes to the configmaps are monitored and the imported -dashboards are deleted/updated. - -A recommendation is to use one configmap per dashboard, as a reduction of multiple dashboards inside -one configmap is currently not properly mirrored in grafana. - -Example dashboard config: - -```yaml -apiVersion: v1 -kind: ConfigMap -metadata: - name: sample-grafana-dashboard - labels: - grafana_dashboard: "1" -data: - k8s-dashboard.json: |- - [...] -``` - -## Sidecar for datasources - -If the parameter `sidecar.datasources.enabled` is set, an init container is deployed in the grafana -pod. This container lists all secrets (or configmaps, though not recommended) in the cluster and -filters out the ones with a label as defined in `sidecar.datasources.label`. The files defined in -those secrets are written to a folder and accessed by grafana on startup. Using these yaml files, -the data sources in grafana can be imported. - -Should you aim for reloading datasources in Grafana each time the config is changed, set `sidecar.datasources.skipReload: false` and adjust `sidecar.datasources.reloadURL` to `http://..svc.cluster.local/api/admin/provisioning/datasources/reload`. - -Secrets are recommended over configmaps for this usecase because datasources usually contain private -data like usernames and passwords. Secrets are the more appropriate cluster resource to manage those. - -Example values to add a postgres datasource as a kubernetes secret: - -```yaml -apiVersion: v1 -kind: Secret -metadata: - name: grafana-datasources - labels: - grafana_datasource: 'true' # default value for: sidecar.datasources.label -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' # disable/require/verify-ca/verify-full - maxOpenConns: 0 # Grafana v5.4+ - maxIdleConns: 2 # Grafana v5.4+ - connMaxLifetime: 14400 # Grafana v5.4+ - postgresVersion: 1000 # 903=9.3, 904=9.4, 905=9.5, 906=9.6, 1000=10 - timescaledb: false - # allow users to edit datasources from the UI. - editable: false -``` - -Example values to add a datasource adapted from [Grafana](http://docs.grafana.org/administration/provisioning/#example-datasource-config-file): - -```yaml -datasources: - datasources.yaml: - apiVersion: 1 - datasources: - # name of the datasource. Required - - name: Graphite - # datasource type. Required - type: graphite - # access mode. proxy or direct (Server or Browser in the UI). Required - access: proxy - # org id. will default to orgId 1 if not specified - orgId: 1 - # url - url: http://localhost:8080 - # database password, if used - password: - # database user, if used - user: - # database name, if used - database: - # enable/disable basic auth - basicAuth: - # basic auth username - basicAuthUser: - # basic auth password - basicAuthPassword: - # enable/disable with credentials headers - withCredentials: - # mark as default datasource. Max one per org - isDefault: - # fields that will be converted to json and stored in json_data - jsonData: - graphiteVersion: "1.1" - tlsAuth: true - tlsAuthWithCACert: true - # json object of data that will be encrypted. - secureJsonData: - tlsCACert: "..." - tlsClientCert: "..." - tlsClientKey: "..." - version: 1 - # allow users to edit datasources from the UI. - editable: false -``` - -## Sidecar for notifiers - -If the parameter `sidecar.notifiers.enabled` is set, an init container is deployed in the grafana -pod. This container lists all secrets (or configmaps, though not recommended) in the cluster and -filters out the ones with a label as defined in `sidecar.notifiers.label`. The files defined in -those secrets are written to a folder and accessed by grafana on startup. Using these yaml files, -the notification channels in grafana can be imported. The secrets must be created before -`helm install` so that the notifiers init container can list the secrets. - -Secrets are recommended over configmaps for this usecase because alert notification channels usually contain -private data like SMTP usernames and passwords. Secrets are the more appropriate cluster resource to manage those. - -Example datasource config adapted from [Grafana](https://grafana.com/docs/grafana/latest/administration/provisioning/#alert-notification-channels): - -```yaml -notifiers: - - name: notification-channel-1 - type: slack - uid: notifier1 - # either - org_id: 2 - # or - org_name: Main Org. - is_default: true - send_reminder: true - frequency: 1h - disable_resolve_message: false - # See `Supported Settings` section for settings supporter for each - # alert notification type. - settings: - recipient: 'XXX' - token: 'xoxb' - uploadImage: true - url: https://slack.com - -delete_notifiers: - - name: notification-channel-1 - uid: notifier1 - org_id: 2 - - name: notification-channel-2 - # default org_id: 1 -``` - -## Sidecar for alerting resources - -If the parameter `sidecar.alerts.enabled` is set, a sidecar container is deployed in the grafana -pod. This container watches all configmaps (or secrets) in the cluster (namespace defined by `sidecar.alerts.searchNamespace`) and filters out the ones with -a label as defined in `sidecar.alerts.label` (default is `grafana_alert`). The files defined in those configmaps are written -to a folder and accessed by grafana. Changes to the configmaps are monitored and the imported alerting resources are updated, however, deletions are a little more complicated (see below). - -This sidecar can be used to provision alert rules, contact points, notification policies, notification templates and mute timings as shown in [Grafana Documentation](https://grafana.com/docs/grafana/next/alerting/set-up/provision-alerting-resources/file-provisioning/). - -To fetch the alert config which will be provisioned, use the alert provisioning API ([Grafana Documentation](https://grafana.com/docs/grafana/next/developers/http_api/alerting_provisioning/)). -You can use either JSON or YAML format. - -Example config for an alert rule: - -```yaml -apiVersion: v1 -kind: ConfigMap -metadata: - name: sample-grafana-alert - labels: - grafana_alert: "1" -data: - k8s-alert.yml: |- - apiVersion: 1 - groups: - - orgId: 1 - name: k8s-alert - [...] -``` - -To delete provisioned alert rules is a two step process, you need to delete the configmap which defined the alert rule -and then create a configuration which deletes the alert rule. - -Example deletion configuration: - -```yaml -apiVersion: v1 -kind: ConfigMap -metadata: - name: delete-sample-grafana-alert - namespace: monitoring - labels: - grafana_alert: "1" -data: - delete-k8s-alert.yml: |- - apiVersion: 1 - deleteRules: - - orgId: 1 - uid: 16624780-6564-45dc-825c-8bded4ad92d3 -``` - -## Statically provision alerting resources - -If you don't need to change alerting resources (alert rules, contact points, notification policies and notification templates) regularly you could use the `alerting` config option instead of the sidecar option above. -This will grab the alerting config and apply it statically at build time for the helm file. - -There are two methods to statically provision alerting configuration in Grafana. Below are some examples and explanations as to how to use each method: - -```yaml -alerting: - team1-alert-rules.yaml: - file: alerting/team1/rules.yaml - team2-alert-rules.yaml: - file: alerting/team2/rules.yaml - team3-alert-rules.yaml: - file: alerting/team3/rules.yaml - notification-policies.yaml: - file: alerting/shared/notification-policies.yaml - notification-templates.yaml: - file: alerting/shared/notification-templates.yaml - contactpoints.yaml: - apiVersion: 1 - contactPoints: - - orgId: 1 - name: Slack channel - receivers: - - uid: default-receiver - type: slack - settings: - # Webhook URL to be filled in - url: "" - # We need to escape double curly braces for the tpl function. - text: '{{ `{{ template "default.message" . }}` }}' - title: '{{ `{{ template "default.title" . }}` }}' -``` - -The two possibilities for static alerting resource provisioning are: - -* Inlining the file contents as shown for contact points in the above example. -* Importing a file using a relative path starting from the chart root directory as shown for the alert rules in the above example. - -### Important notes on file provisioning - -* The format of the files is defined in the [Grafana documentation](https://grafana.com/docs/grafana/next/alerting/set-up/provision-alerting-resources/file-provisioning/) on file provisioning. -* The chart supports importing YAML and JSON files. -* The filename must be unique, otherwise one volume mount will overwrite the other. -* In case of inlining, double curly braces that arise from the Grafana configuration format and are not intended as templates for the chart must be escaped. -* The number of total files under `alerting:` is not limited. Each file will end up as a volume mount in the corresponding provisioning folder of the deployed Grafana instance. -* The file size for each import is limited by what the function `.Files.Get` can handle, which suffices for most cases. - -## How to serve Grafana with a path prefix (/grafana) - -In order to serve Grafana with a prefix (e.g., ), add the following to your values.yaml. - -```yaml -ingress: - enabled: true - annotations: - kubernetes.io/ingress.class: "nginx" - nginx.ingress.kubernetes.io/rewrite-target: /$1 - nginx.ingress.kubernetes.io/use-regex: "true" - - path: /grafana/?(.*) - hosts: - - k8s.example.dev - -grafana.ini: - server: - root_url: http://localhost:3000/grafana # this host can be localhost -``` - -## How to securely reference secrets in grafana.ini - -This example uses Grafana [file providers](https://grafana.com/docs/grafana/latest/administration/configuration/#file-provider) for secret values and the `extraSecretMounts` configuration flag (Additional grafana server secret mounts) to mount the secrets. - -In grafana.ini: - -```yaml -grafana.ini: - [auth.generic_oauth] - enabled = true - client_id = $__file{/etc/secrets/auth_generic_oauth/client_id} - client_secret = $__file{/etc/secrets/auth_generic_oauth/client_secret} -``` - -Existing secret, or created along with helm: - -```yaml ---- -apiVersion: v1 -kind: Secret -metadata: - name: auth-generic-oauth-secret -type: Opaque -stringData: - client_id: - client_secret: -``` - -Include in the `extraSecretMounts` configuration flag: - -```yaml -extraSecretMounts: - - name: auth-generic-oauth-secret-mount - secretName: auth-generic-oauth-secret - defaultMode: 0440 - mountPath: /etc/secrets/auth_generic_oauth - readOnly: true -``` - -### extraSecretMounts using a Container Storage Interface (CSI) provider - -This example uses a CSI driver e.g. retrieving secrets using [Azure Key Vault Provider](https://github.com/Azure/secrets-store-csi-driver-provider-azure) - -```yaml -extraSecretMounts: - - name: secrets-store-inline - mountPath: /run/secrets - readOnly: true - csi: - driver: secrets-store.csi.k8s.io - readOnly: true - volumeAttributes: - secretProviderClass: "my-provider" - nodePublishSecretRef: - name: akv-creds -``` - -## Image Renderer Plug-In - -This chart supports enabling [remote image rendering](https://github.com/grafana/grafana-image-renderer/blob/master/README.md#run-in-docker) - -```yaml -imageRenderer: - enabled: true -``` - -### Image Renderer NetworkPolicy - -By default the image-renderer pods will have a network policy which only allows ingress traffic from the created grafana instance - -### High Availability for unified alerting - -If you want to run Grafana in a high availability cluster you need to enable -the headless service by setting `headlessService: true` in your `values.yaml` -file. - -As next step you have to setup the `grafana.ini` in your `values.yaml` in a way -that it will make use of the headless service to obtain all the IPs of the -cluster. You should replace ``{{ Name }}`` with the name of your helm deployment. - -```yaml -grafana.ini: - ... - unified_alerting: - enabled: true - ha_peers: {{ Name }}-headless:9094 - ha_listen_address: ${POD_IP}:9094 - ha_advertise_address: ${POD_IP}:9094 - - alerting: - enabled: false -``` +# grafana + +![Version: 8.8.3](https://img.shields.io/badge/Version-8.8.3-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 11.4.0](https://img.shields.io/badge/AppVersion-11.4.0-informational?style=flat-square) + +The leading tool for querying and visualizing time series and metrics. + +**Homepage:** + +## Maintainers + +| Name | Email | Url | +| ---- | ------ | --- | +| zanhsieh | | | +| rtluckie | | | +| maorfr | | | +| Xtigyro | | | +| torstenwalter | | | +| jkroepke | | | + +## Source Code + +* +* + +## Requirements + +Kubernetes: `^1.8.0-0` + +## Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| "grafana.ini".analytics.check_for_updates | bool | `true` | | +| "grafana.ini".grafana_net.url | string | `"https://grafana.net"` | | +| "grafana.ini".log.mode | string | `"console"` | | +| "grafana.ini".paths.data | string | `"/var/lib/grafana/"` | | +| "grafana.ini".paths.logs | string | `"/var/log/grafana"` | | +| "grafana.ini".paths.plugins | string | `"/var/lib/grafana/plugins"` | | +| "grafana.ini".paths.provisioning | string | `"/etc/grafana/provisioning"` | | +| "grafana.ini".server.domain | string | `"{{ if (and .Values.ingress.enabled .Values.ingress.hosts) }}{{ tpl (.Values.ingress.hosts | first) . }}{{ else }}''{{ end }}"` | | +| admin.existingSecret | string | `""` | | +| admin.passwordKey | string | `"admin-password"` | | +| admin.userKey | string | `"admin-user"` | | +| adminUser | string | `"admin"` | | +| affinity | object | `{}` | | +| alerting | object | `{}` | | +| assertNoLeakedSecrets | bool | `true` | | +| automountServiceAccountToken | bool | `true` | | +| autoscaling.behavior | object | `{}` | | +| autoscaling.enabled | bool | `false` | | +| autoscaling.maxReplicas | int | `5` | | +| autoscaling.minReplicas | int | `1` | | +| autoscaling.targetCPU | string | `"60"` | | +| autoscaling.targetMemory | string | `""` | | +| containerSecurityContext.allowPrivilegeEscalation | bool | `false` | | +| containerSecurityContext.capabilities.drop[0] | string | `"ALL"` | | +| containerSecurityContext.seccompProfile.type | string | `"RuntimeDefault"` | | +| createConfigmap | bool | `true` | | +| dashboardProviders | object | `{}` | | +| dashboards | object | `{}` | | +| dashboardsConfigMaps | object | `{}` | | +| datasources | object | `{}` | | +| deploymentStrategy.type | string | `"RollingUpdate"` | | +| dnsConfig | object | `{}` | | +| dnsPolicy | string | `nil` | | +| downloadDashboards.env | object | `{}` | | +| downloadDashboards.envFromSecret | string | `""` | | +| downloadDashboards.envValueFrom | object | `{}` | | +| downloadDashboards.resources | object | `{}` | | +| downloadDashboards.securityContext.allowPrivilegeEscalation | bool | `false` | | +| downloadDashboards.securityContext.capabilities.drop[0] | string | `"ALL"` | | +| downloadDashboards.securityContext.seccompProfile.type | string | `"RuntimeDefault"` | | +| downloadDashboardsImage.pullPolicy | string | `"IfNotPresent"` | | +| downloadDashboardsImage.registry | string | `"docker.io"` | The Docker registry | +| downloadDashboardsImage.repository | string | `"curlimages/curl"` | | +| downloadDashboardsImage.sha | string | `""` | | +| downloadDashboardsImage.tag | string | `"7.85.0"` | | +| enableKubeBackwardCompatibility | bool | `false` | | +| enableServiceLinks | bool | `true` | | +| env | object | `{}` | | +| envFromConfigMaps | list | `[]` | | +| envFromSecret | string | `""` | | +| envFromSecrets | list | `[]` | | +| envRenderSecret | object | `{}` | | +| envValueFrom | object | `{}` | | +| extraConfigmapMounts | list | `[]` | | +| extraContainerVolumes | list | `[]` | | +| extraContainers | string | `""` | | +| extraEmptyDirMounts | list | `[]` | | +| extraExposePorts | list | `[]` | | +| extraInitContainers | list | `[]` | | +| extraLabels | object | `{}` | | +| extraObjects | list | `[]` | | +| extraSecretMounts | list | `[]` | | +| extraVolumeMounts | list | `[]` | | +| extraVolumes | list | `[]` | | +| global.imagePullSecrets | list | `[]` | | +| global.imageRegistry | string | `nil` | Overrides the Docker registry globally for all images | +| gossipPortName | string | `"gossip"` | | +| headlessService | bool | `false` | | +| hostAliases | list | `[]` | | +| image.pullPolicy | string | `"IfNotPresent"` | | +| image.pullSecrets | list | `[]` | | +| image.registry | string | `"docker.io"` | The Docker registry | +| image.repository | string | `"grafana/grafana"` | Docker image repository | +| image.sha | string | `""` | | +| image.tag | string | `""` | | +| imageRenderer.affinity | object | `{}` | | +| imageRenderer.automountServiceAccountToken | bool | `false` | | +| imageRenderer.autoscaling.behavior | object | `{}` | | +| imageRenderer.autoscaling.enabled | bool | `false` | | +| imageRenderer.autoscaling.maxReplicas | int | `5` | | +| imageRenderer.autoscaling.minReplicas | int | `1` | | +| imageRenderer.autoscaling.targetCPU | string | `"60"` | | +| imageRenderer.autoscaling.targetMemory | string | `""` | | +| imageRenderer.containerSecurityContext.allowPrivilegeEscalation | bool | `false` | | +| imageRenderer.containerSecurityContext.capabilities.drop[0] | string | `"ALL"` | | +| imageRenderer.containerSecurityContext.readOnlyRootFilesystem | bool | `true` | | +| imageRenderer.containerSecurityContext.seccompProfile.type | string | `"RuntimeDefault"` | | +| imageRenderer.deploymentStrategy | object | `{}` | | +| imageRenderer.enabled | bool | `false` | | +| imageRenderer.env.HTTP_HOST | string | `"0.0.0.0"` | | +| imageRenderer.env.XDG_CACHE_HOME | string | `"/tmp/.chromium"` | | +| imageRenderer.env.XDG_CONFIG_HOME | string | `"/tmp/.chromium"` | | +| imageRenderer.envValueFrom | object | `{}` | | +| imageRenderer.extraConfigmapMounts | list | `[]` | | +| imageRenderer.extraSecretMounts | list | `[]` | | +| imageRenderer.extraVolumeMounts | list | `[]` | | +| imageRenderer.extraVolumes | list | `[]` | | +| imageRenderer.grafanaProtocol | string | `"http"` | | +| imageRenderer.grafanaSubPath | string | `""` | | +| imageRenderer.hostAliases | list | `[]` | | +| imageRenderer.image.pullPolicy | string | `"Always"` | | +| imageRenderer.image.registry | string | `"docker.io"` | The Docker registry | +| imageRenderer.image.repository | string | `"grafana/grafana-image-renderer"` | | +| imageRenderer.image.sha | string | `""` | | +| imageRenderer.image.tag | string | `"latest"` | | +| imageRenderer.networkPolicy.extraIngressSelectors | list | `[]` | | +| imageRenderer.networkPolicy.limitEgress | bool | `false` | | +| imageRenderer.networkPolicy.limitIngress | bool | `true` | | +| imageRenderer.nodeSelector | object | `{}` | | +| imageRenderer.podAnnotations | object | `{}` | | +| imageRenderer.podPortName | string | `"http"` | | +| imageRenderer.priorityClassName | string | `""` | | +| imageRenderer.renderingCallbackURL | string | `""` | | +| imageRenderer.replicas | int | `1` | | +| imageRenderer.resources | object | `{}` | | +| imageRenderer.revisionHistoryLimit | int | `10` | | +| imageRenderer.securityContext | object | `{}` | | +| imageRenderer.serverURL | string | `""` | | +| imageRenderer.service.appProtocol | string | `""` | | +| imageRenderer.service.enabled | bool | `true` | | +| imageRenderer.service.port | int | `8081` | | +| imageRenderer.service.portName | string | `"http"` | | +| imageRenderer.service.targetPort | int | `8081` | | +| imageRenderer.serviceAccountName | string | `""` | | +| imageRenderer.serviceMonitor.enabled | bool | `false` | | +| imageRenderer.serviceMonitor.interval | string | `"1m"` | | +| imageRenderer.serviceMonitor.labels | object | `{}` | | +| imageRenderer.serviceMonitor.path | string | `"/metrics"` | | +| imageRenderer.serviceMonitor.relabelings | list | `[]` | | +| imageRenderer.serviceMonitor.scheme | string | `"http"` | | +| imageRenderer.serviceMonitor.scrapeTimeout | string | `"30s"` | | +| imageRenderer.serviceMonitor.targetLabels | list | `[]` | | +| imageRenderer.serviceMonitor.tlsConfig | object | `{}` | | +| imageRenderer.tolerations | list | `[]` | | +| ingress.annotations | object | `{}` | | +| ingress.enabled | bool | `false` | | +| ingress.extraPaths | list | `[]` | | +| ingress.hosts[0] | string | `"chart-example.local"` | | +| ingress.labels | object | `{}` | | +| ingress.path | string | `"/"` | | +| ingress.pathType | string | `"Prefix"` | | +| ingress.tls | list | `[]` | | +| initChownData.enabled | bool | `true` | | +| initChownData.image.pullPolicy | string | `"IfNotPresent"` | | +| initChownData.image.registry | string | `"docker.io"` | The Docker registry | +| initChownData.image.repository | string | `"library/busybox"` | | +| initChownData.image.sha | string | `""` | | +| initChownData.image.tag | string | `"1.31.1"` | | +| initChownData.resources | object | `{}` | | +| initChownData.securityContext.capabilities.add[0] | string | `"CHOWN"` | | +| initChownData.securityContext.runAsNonRoot | bool | `false` | | +| initChownData.securityContext.runAsUser | int | `0` | | +| initChownData.securityContext.seccompProfile.type | string | `"RuntimeDefault"` | | +| ldap.config | string | `""` | | +| ldap.enabled | bool | `false` | | +| ldap.existingSecret | string | `""` | | +| lifecycleHooks | object | `{}` | | +| livenessProbe.failureThreshold | int | `10` | | +| livenessProbe.httpGet.path | string | `"/api/health"` | | +| livenessProbe.httpGet.port | int | `3000` | | +| livenessProbe.initialDelaySeconds | int | `60` | | +| livenessProbe.timeoutSeconds | int | `30` | | +| namespaceOverride | string | `""` | | +| networkPolicy.allowExternal | bool | `true` | | +| networkPolicy.egress.blockDNSResolution | bool | `false` | | +| networkPolicy.egress.enabled | bool | `false` | | +| networkPolicy.egress.ports | list | `[]` | | +| networkPolicy.egress.to | list | `[]` | | +| networkPolicy.enabled | bool | `false` | | +| networkPolicy.explicitNamespacesSelector | object | `{}` | | +| networkPolicy.ingress | bool | `true` | | +| nodeSelector | object | `{}` | | +| notifiers | object | `{}` | | +| persistence.accessModes[0] | string | `"ReadWriteOnce"` | | +| persistence.disableWarning | bool | `false` | | +| persistence.enabled | bool | `false` | | +| persistence.extraPvcLabels | object | `{}` | | +| persistence.finalizers[0] | string | `"kubernetes.io/pvc-protection"` | | +| persistence.inMemory.enabled | bool | `false` | | +| persistence.lookupVolumeName | bool | `true` | | +| persistence.size | string | `"10Gi"` | | +| persistence.type | string | `"pvc"` | | +| plugins | list | `[]` | | +| podDisruptionBudget | object | `{}` | | +| podPortName | string | `"grafana"` | | +| rbac.create | bool | `true` | | +| rbac.extraClusterRoleRules | list | `[]` | | +| rbac.extraRoleRules | list | `[]` | | +| rbac.namespaced | bool | `false` | | +| rbac.pspEnabled | bool | `false` | | +| rbac.pspUseAppArmor | bool | `false` | | +| readinessProbe.httpGet.path | string | `"/api/health"` | | +| readinessProbe.httpGet.port | int | `3000` | | +| replicas | int | `1` | | +| resources | object | `{}` | | +| revisionHistoryLimit | int | `10` | | +| route | object | `{"main":{"additionalRules":[],"annotations":{},"apiVersion":"gateway.networking.k8s.io/v1","enabled":false,"filters":[],"hostnames":[],"kind":"HTTPRoute","labels":{},"matches":[{"path":{"type":"PathPrefix","value":"/"}}],"parentRefs":[]}}` | BETA: Configure the gateway routes for the chart here. More routes can be added by adding a dictionary key like the 'main' route. Be aware that this is an early beta of this feature, kube-prometheus-stack does not guarantee this works and is subject to change. Being BETA this can/will change in the future without notice, do not use unless you want to take that risk [[ref]](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io%2fv1alpha2) | +| route.main.apiVersion | string | `"gateway.networking.k8s.io/v1"` | Set the route apiVersion, e.g. gateway.networking.k8s.io/v1 or gateway.networking.k8s.io/v1alpha2 | +| route.main.enabled | bool | `false` | Enables or disables the route | +| route.main.kind | string | `"HTTPRoute"` | Set the route kind Valid options are GRPCRoute, HTTPRoute, TCPRoute, TLSRoute, UDPRoute | +| securityContext.fsGroup | int | `472` | | +| securityContext.runAsGroup | int | `472` | | +| securityContext.runAsNonRoot | bool | `true` | | +| securityContext.runAsUser | int | `472` | | +| service.annotations | object | `{}` | | +| service.appProtocol | string | `""` | | +| service.enabled | bool | `true` | | +| service.ipFamilies | list | `[]` | | +| service.ipFamilyPolicy | string | `""` | | +| service.labels | object | `{}` | | +| service.loadBalancerClass | string | `""` | | +| service.loadBalancerIP | string | `""` | | +| service.loadBalancerSourceRanges | list | `[]` | | +| service.port | int | `80` | | +| service.portName | string | `"service"` | | +| service.sessionAffinity | string | `"ClientIP"` | | +| service.targetPort | int | `3000` | | +| service.type | string | `"ClusterIP"` | | +| serviceAccount.automountServiceAccountToken | bool | `false` | | +| serviceAccount.create | bool | `true` | | +| serviceAccount.labels | object | `{}` | | +| serviceAccount.name | string | `nil` | | +| serviceAccount.nameTest | string | `nil` | | +| serviceMonitor.basicAuth | object | `{}` | | +| serviceMonitor.enabled | bool | `false` | | +| serviceMonitor.interval | string | `"30s"` | | +| serviceMonitor.labels | object | `{}` | | +| serviceMonitor.metricRelabelings | list | `[]` | | +| serviceMonitor.path | string | `"/metrics"` | | +| serviceMonitor.relabelings | list | `[]` | | +| serviceMonitor.scheme | string | `"http"` | | +| serviceMonitor.scrapeTimeout | string | `"30s"` | | +| serviceMonitor.targetLabels | list | `[]` | | +| serviceMonitor.tlsConfig | object | `{}` | | +| sidecar.alerts.enabled | bool | `false` | | +| sidecar.alerts.env | object | `{}` | | +| sidecar.alerts.extraMounts | list | `[]` | | +| sidecar.alerts.initAlerts | bool | `false` | | +| sidecar.alerts.label | string | `"grafana_alert"` | | +| sidecar.alerts.labelValue | string | `""` | | +| sidecar.alerts.reloadURL | string | `"http://localhost:3000/api/admin/provisioning/alerting/reload"` | | +| sidecar.alerts.resource | string | `"both"` | | +| sidecar.alerts.script | string | `nil` | | +| sidecar.alerts.searchNamespace | string | `nil` | | +| sidecar.alerts.sizeLimit | object | `{}` | | +| sidecar.alerts.skipReload | bool | `false` | | +| sidecar.alerts.watchMethod | string | `"WATCH"` | | +| sidecar.dashboards.SCProvider | bool | `true` | | +| sidecar.dashboards.defaultFolderName | string | `nil` | | +| sidecar.dashboards.enabled | bool | `false` | | +| sidecar.dashboards.env | object | `{}` | | +| sidecar.dashboards.envValueFrom | object | `{}` | | +| sidecar.dashboards.extraMounts | list | `[]` | | +| sidecar.dashboards.folder | string | `"/tmp/dashboards"` | | +| sidecar.dashboards.folderAnnotation | string | `nil` | | +| sidecar.dashboards.label | string | `"grafana_dashboard"` | | +| sidecar.dashboards.labelValue | string | `""` | | +| sidecar.dashboards.provider.allowUiUpdates | bool | `false` | | +| sidecar.dashboards.provider.disableDelete | bool | `false` | | +| sidecar.dashboards.provider.folder | string | `""` | | +| sidecar.dashboards.provider.folderUid | string | `""` | | +| sidecar.dashboards.provider.foldersFromFilesStructure | bool | `false` | | +| sidecar.dashboards.provider.name | string | `"sidecarProvider"` | | +| sidecar.dashboards.provider.orgid | int | `1` | | +| sidecar.dashboards.provider.type | string | `"file"` | | +| sidecar.dashboards.reloadURL | string | `"http://localhost:3000/api/admin/provisioning/dashboards/reload"` | | +| sidecar.dashboards.resource | string | `"both"` | | +| sidecar.dashboards.script | string | `nil` | | +| sidecar.dashboards.searchNamespace | string | `nil` | | +| sidecar.dashboards.sizeLimit | object | `{}` | | +| sidecar.dashboards.skipReload | bool | `false` | | +| sidecar.dashboards.watchMethod | string | `"WATCH"` | | +| sidecar.datasources.enabled | bool | `false` | | +| sidecar.datasources.env | object | `{}` | | +| sidecar.datasources.envValueFrom | object | `{}` | | +| sidecar.datasources.extraMounts | list | `[]` | | +| sidecar.datasources.initDatasources | bool | `false` | | +| sidecar.datasources.label | string | `"grafana_datasource"` | | +| sidecar.datasources.labelValue | string | `""` | | +| sidecar.datasources.reloadURL | string | `"http://localhost:3000/api/admin/provisioning/datasources/reload"` | | +| sidecar.datasources.resource | string | `"both"` | | +| sidecar.datasources.script | string | `nil` | | +| sidecar.datasources.searchNamespace | string | `nil` | | +| sidecar.datasources.sizeLimit | object | `{}` | | +| sidecar.datasources.skipReload | bool | `false` | | +| sidecar.datasources.watchMethod | string | `"WATCH"` | | +| sidecar.enableUniqueFilenames | bool | `false` | | +| sidecar.image.registry | string | `"quay.io"` | The Docker registry | +| sidecar.image.repository | string | `"kiwigrid/k8s-sidecar"` | | +| sidecar.image.sha | string | `""` | | +| sidecar.image.tag | string | `"1.28.0"` | | +| sidecar.imagePullPolicy | string | `"IfNotPresent"` | | +| sidecar.livenessProbe | object | `{}` | | +| sidecar.notifiers.enabled | bool | `false` | | +| sidecar.notifiers.env | object | `{}` | | +| sidecar.notifiers.extraMounts | list | `[]` | | +| sidecar.notifiers.initNotifiers | bool | `false` | | +| sidecar.notifiers.label | string | `"grafana_notifier"` | | +| sidecar.notifiers.labelValue | string | `""` | | +| sidecar.notifiers.reloadURL | string | `"http://localhost:3000/api/admin/provisioning/notifications/reload"` | | +| sidecar.notifiers.resource | string | `"both"` | | +| sidecar.notifiers.script | string | `nil` | | +| sidecar.notifiers.searchNamespace | string | `nil` | | +| sidecar.notifiers.sizeLimit | object | `{}` | | +| sidecar.notifiers.skipReload | bool | `false` | | +| sidecar.notifiers.watchMethod | string | `"WATCH"` | | +| sidecar.plugins.enabled | bool | `false` | | +| sidecar.plugins.env | object | `{}` | | +| sidecar.plugins.extraMounts | list | `[]` | | +| sidecar.plugins.initPlugins | bool | `false` | | +| sidecar.plugins.label | string | `"grafana_plugin"` | | +| sidecar.plugins.labelValue | string | `""` | | +| sidecar.plugins.reloadURL | string | `"http://localhost:3000/api/admin/provisioning/plugins/reload"` | | +| sidecar.plugins.resource | string | `"both"` | | +| sidecar.plugins.script | string | `nil` | | +| sidecar.plugins.searchNamespace | string | `nil` | | +| sidecar.plugins.sizeLimit | object | `{}` | | +| sidecar.plugins.skipReload | bool | `false` | | +| sidecar.plugins.watchMethod | string | `"WATCH"` | | +| sidecar.readinessProbe | object | `{}` | | +| sidecar.resources | object | `{}` | | +| sidecar.securityContext.allowPrivilegeEscalation | bool | `false` | | +| sidecar.securityContext.capabilities.drop[0] | string | `"ALL"` | | +| sidecar.securityContext.seccompProfile.type | string | `"RuntimeDefault"` | | +| smtp.existingSecret | string | `""` | | +| smtp.passwordKey | string | `"password"` | | +| smtp.userKey | string | `"user"` | | +| testFramework.enabled | bool | `true` | | +| testFramework.image.registry | string | `"docker.io"` | The Docker registry | +| testFramework.image.repository | string | `"bats/bats"` | | +| testFramework.image.tag | string | `"v1.4.1"` | | +| testFramework.imagePullPolicy | string | `"IfNotPresent"` | | +| testFramework.resources | object | `{}` | | +| testFramework.securityContext | object | `{}` | | +| tolerations | list | `[]` | | +| topologySpreadConstraints | list | `[]` | | +| useStatefulSet | bool | `false` | | + +---------------------------------------------- +Autogenerated from chart metadata using [helm-docs v1.8.1](https://github.com/norwoodj/helm-docs/releases/v1.8.1) diff --git a/charts/grafana/templates/service.yaml b/charts/grafana/templates/service.yaml index 022328c114..3d3b399024 100644 --- a/charts/grafana/templates/service.yaml +++ b/charts/grafana/templates/service.yaml @@ -48,6 +48,9 @@ spec: {{- with .Values.service.externalTrafficPolicy }} externalTrafficPolicy: {{ . }} {{- end }} + {{- if .Values.service.sessionAffinity }} + sessionAffinity: {{ .Values.service.sessionAffinity }} + {{- end }} ports: - name: {{ .Values.service.portName }} port: {{ .Values.service.port }} diff --git a/charts/grafana/values.yaml b/charts/grafana/values.yaml index 5095c37441..ebe5c698e1 100644 --- a/charts/grafana/values.yaml +++ b/charts/grafana/values.yaml @@ -245,6 +245,7 @@ service: portName: service # Adds the appProtocol field to the service. This allows to work with istio protocol selection. Ex: "http" or "tcp" appProtocol: "" + sessionAffinity: ClientIP serviceMonitor: ## If true, a ServiceMonitor CR is created for a prometheus operator From c5e49f273da16450c2e33c2d56611190b4a27584 Mon Sep 17 00:00:00 2001 From: AvivGuiser Date: Tue, 14 Jan 2025 20:01:28 +0200 Subject: [PATCH 2/6] Revert "add session affinity config" This reverts commit bde875cc8982d9f2f1f0cc152af5238b04b80516. Signed-off-by: AvivGuiser --- charts/grafana/Chart.yaml | 2 +- charts/grafana/README.md | 1155 +++++++++++++++++-------- charts/grafana/templates/service.yaml | 3 - charts/grafana/values.yaml | 1 - 4 files changed, 784 insertions(+), 377 deletions(-) diff --git a/charts/grafana/Chart.yaml b/charts/grafana/Chart.yaml index c570d934f1..9deccc3ff6 100644 --- a/charts/grafana/Chart.yaml +++ b/charts/grafana/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v2 name: grafana -version: 8.8.3 +version: 8.8.2 appVersion: 11.4.0 kubeVersion: "^1.8.0-0" description: The leading tool for querying and visualizing time series and metrics. diff --git a/charts/grafana/README.md b/charts/grafana/README.md index c26784b919..a78b123605 100644 --- a/charts/grafana/README.md +++ b/charts/grafana/README.md @@ -1,372 +1,783 @@ -# grafana - -![Version: 8.8.3](https://img.shields.io/badge/Version-8.8.3-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 11.4.0](https://img.shields.io/badge/AppVersion-11.4.0-informational?style=flat-square) - -The leading tool for querying and visualizing time series and metrics. - -**Homepage:** - -## Maintainers - -| Name | Email | Url | -| ---- | ------ | --- | -| zanhsieh | | | -| rtluckie | | | -| maorfr | | | -| Xtigyro | | | -| torstenwalter | | | -| jkroepke | | | - -## Source Code - -* -* - -## Requirements - -Kubernetes: `^1.8.0-0` - -## Values - -| Key | Type | Default | Description | -|-----|------|---------|-------------| -| "grafana.ini".analytics.check_for_updates | bool | `true` | | -| "grafana.ini".grafana_net.url | string | `"https://grafana.net"` | | -| "grafana.ini".log.mode | string | `"console"` | | -| "grafana.ini".paths.data | string | `"/var/lib/grafana/"` | | -| "grafana.ini".paths.logs | string | `"/var/log/grafana"` | | -| "grafana.ini".paths.plugins | string | `"/var/lib/grafana/plugins"` | | -| "grafana.ini".paths.provisioning | string | `"/etc/grafana/provisioning"` | | -| "grafana.ini".server.domain | string | `"{{ if (and .Values.ingress.enabled .Values.ingress.hosts) }}{{ tpl (.Values.ingress.hosts | first) . }}{{ else }}''{{ end }}"` | | -| admin.existingSecret | string | `""` | | -| admin.passwordKey | string | `"admin-password"` | | -| admin.userKey | string | `"admin-user"` | | -| adminUser | string | `"admin"` | | -| affinity | object | `{}` | | -| alerting | object | `{}` | | -| assertNoLeakedSecrets | bool | `true` | | -| automountServiceAccountToken | bool | `true` | | -| autoscaling.behavior | object | `{}` | | -| autoscaling.enabled | bool | `false` | | -| autoscaling.maxReplicas | int | `5` | | -| autoscaling.minReplicas | int | `1` | | -| autoscaling.targetCPU | string | `"60"` | | -| autoscaling.targetMemory | string | `""` | | -| containerSecurityContext.allowPrivilegeEscalation | bool | `false` | | -| containerSecurityContext.capabilities.drop[0] | string | `"ALL"` | | -| containerSecurityContext.seccompProfile.type | string | `"RuntimeDefault"` | | -| createConfigmap | bool | `true` | | -| dashboardProviders | object | `{}` | | -| dashboards | object | `{}` | | -| dashboardsConfigMaps | object | `{}` | | -| datasources | object | `{}` | | -| deploymentStrategy.type | string | `"RollingUpdate"` | | -| dnsConfig | object | `{}` | | -| dnsPolicy | string | `nil` | | -| downloadDashboards.env | object | `{}` | | -| downloadDashboards.envFromSecret | string | `""` | | -| downloadDashboards.envValueFrom | object | `{}` | | -| downloadDashboards.resources | object | `{}` | | -| downloadDashboards.securityContext.allowPrivilegeEscalation | bool | `false` | | -| downloadDashboards.securityContext.capabilities.drop[0] | string | `"ALL"` | | -| downloadDashboards.securityContext.seccompProfile.type | string | `"RuntimeDefault"` | | -| downloadDashboardsImage.pullPolicy | string | `"IfNotPresent"` | | -| downloadDashboardsImage.registry | string | `"docker.io"` | The Docker registry | -| downloadDashboardsImage.repository | string | `"curlimages/curl"` | | -| downloadDashboardsImage.sha | string | `""` | | -| downloadDashboardsImage.tag | string | `"7.85.0"` | | -| enableKubeBackwardCompatibility | bool | `false` | | -| enableServiceLinks | bool | `true` | | -| env | object | `{}` | | -| envFromConfigMaps | list | `[]` | | -| envFromSecret | string | `""` | | -| envFromSecrets | list | `[]` | | -| envRenderSecret | object | `{}` | | -| envValueFrom | object | `{}` | | -| extraConfigmapMounts | list | `[]` | | -| extraContainerVolumes | list | `[]` | | -| extraContainers | string | `""` | | -| extraEmptyDirMounts | list | `[]` | | -| extraExposePorts | list | `[]` | | -| extraInitContainers | list | `[]` | | -| extraLabels | object | `{}` | | -| extraObjects | list | `[]` | | -| extraSecretMounts | list | `[]` | | -| extraVolumeMounts | list | `[]` | | -| extraVolumes | list | `[]` | | -| global.imagePullSecrets | list | `[]` | | -| global.imageRegistry | string | `nil` | Overrides the Docker registry globally for all images | -| gossipPortName | string | `"gossip"` | | -| headlessService | bool | `false` | | -| hostAliases | list | `[]` | | -| image.pullPolicy | string | `"IfNotPresent"` | | -| image.pullSecrets | list | `[]` | | -| image.registry | string | `"docker.io"` | The Docker registry | -| image.repository | string | `"grafana/grafana"` | Docker image repository | -| image.sha | string | `""` | | -| image.tag | string | `""` | | -| imageRenderer.affinity | object | `{}` | | -| imageRenderer.automountServiceAccountToken | bool | `false` | | -| imageRenderer.autoscaling.behavior | object | `{}` | | -| imageRenderer.autoscaling.enabled | bool | `false` | | -| imageRenderer.autoscaling.maxReplicas | int | `5` | | -| imageRenderer.autoscaling.minReplicas | int | `1` | | -| imageRenderer.autoscaling.targetCPU | string | `"60"` | | -| imageRenderer.autoscaling.targetMemory | string | `""` | | -| imageRenderer.containerSecurityContext.allowPrivilegeEscalation | bool | `false` | | -| imageRenderer.containerSecurityContext.capabilities.drop[0] | string | `"ALL"` | | -| imageRenderer.containerSecurityContext.readOnlyRootFilesystem | bool | `true` | | -| imageRenderer.containerSecurityContext.seccompProfile.type | string | `"RuntimeDefault"` | | -| imageRenderer.deploymentStrategy | object | `{}` | | -| imageRenderer.enabled | bool | `false` | | -| imageRenderer.env.HTTP_HOST | string | `"0.0.0.0"` | | -| imageRenderer.env.XDG_CACHE_HOME | string | `"/tmp/.chromium"` | | -| imageRenderer.env.XDG_CONFIG_HOME | string | `"/tmp/.chromium"` | | -| imageRenderer.envValueFrom | object | `{}` | | -| imageRenderer.extraConfigmapMounts | list | `[]` | | -| imageRenderer.extraSecretMounts | list | `[]` | | -| imageRenderer.extraVolumeMounts | list | `[]` | | -| imageRenderer.extraVolumes | list | `[]` | | -| imageRenderer.grafanaProtocol | string | `"http"` | | -| imageRenderer.grafanaSubPath | string | `""` | | -| imageRenderer.hostAliases | list | `[]` | | -| imageRenderer.image.pullPolicy | string | `"Always"` | | -| imageRenderer.image.registry | string | `"docker.io"` | The Docker registry | -| imageRenderer.image.repository | string | `"grafana/grafana-image-renderer"` | | -| imageRenderer.image.sha | string | `""` | | -| imageRenderer.image.tag | string | `"latest"` | | -| imageRenderer.networkPolicy.extraIngressSelectors | list | `[]` | | -| imageRenderer.networkPolicy.limitEgress | bool | `false` | | -| imageRenderer.networkPolicy.limitIngress | bool | `true` | | -| imageRenderer.nodeSelector | object | `{}` | | -| imageRenderer.podAnnotations | object | `{}` | | -| imageRenderer.podPortName | string | `"http"` | | -| imageRenderer.priorityClassName | string | `""` | | -| imageRenderer.renderingCallbackURL | string | `""` | | -| imageRenderer.replicas | int | `1` | | -| imageRenderer.resources | object | `{}` | | -| imageRenderer.revisionHistoryLimit | int | `10` | | -| imageRenderer.securityContext | object | `{}` | | -| imageRenderer.serverURL | string | `""` | | -| imageRenderer.service.appProtocol | string | `""` | | -| imageRenderer.service.enabled | bool | `true` | | -| imageRenderer.service.port | int | `8081` | | -| imageRenderer.service.portName | string | `"http"` | | -| imageRenderer.service.targetPort | int | `8081` | | -| imageRenderer.serviceAccountName | string | `""` | | -| imageRenderer.serviceMonitor.enabled | bool | `false` | | -| imageRenderer.serviceMonitor.interval | string | `"1m"` | | -| imageRenderer.serviceMonitor.labels | object | `{}` | | -| imageRenderer.serviceMonitor.path | string | `"/metrics"` | | -| imageRenderer.serviceMonitor.relabelings | list | `[]` | | -| imageRenderer.serviceMonitor.scheme | string | `"http"` | | -| imageRenderer.serviceMonitor.scrapeTimeout | string | `"30s"` | | -| imageRenderer.serviceMonitor.targetLabels | list | `[]` | | -| imageRenderer.serviceMonitor.tlsConfig | object | `{}` | | -| imageRenderer.tolerations | list | `[]` | | -| ingress.annotations | object | `{}` | | -| ingress.enabled | bool | `false` | | -| ingress.extraPaths | list | `[]` | | -| ingress.hosts[0] | string | `"chart-example.local"` | | -| ingress.labels | object | `{}` | | -| ingress.path | string | `"/"` | | -| ingress.pathType | string | `"Prefix"` | | -| ingress.tls | list | `[]` | | -| initChownData.enabled | bool | `true` | | -| initChownData.image.pullPolicy | string | `"IfNotPresent"` | | -| initChownData.image.registry | string | `"docker.io"` | The Docker registry | -| initChownData.image.repository | string | `"library/busybox"` | | -| initChownData.image.sha | string | `""` | | -| initChownData.image.tag | string | `"1.31.1"` | | -| initChownData.resources | object | `{}` | | -| initChownData.securityContext.capabilities.add[0] | string | `"CHOWN"` | | -| initChownData.securityContext.runAsNonRoot | bool | `false` | | -| initChownData.securityContext.runAsUser | int | `0` | | -| initChownData.securityContext.seccompProfile.type | string | `"RuntimeDefault"` | | -| ldap.config | string | `""` | | -| ldap.enabled | bool | `false` | | -| ldap.existingSecret | string | `""` | | -| lifecycleHooks | object | `{}` | | -| livenessProbe.failureThreshold | int | `10` | | -| livenessProbe.httpGet.path | string | `"/api/health"` | | -| livenessProbe.httpGet.port | int | `3000` | | -| livenessProbe.initialDelaySeconds | int | `60` | | -| livenessProbe.timeoutSeconds | int | `30` | | -| namespaceOverride | string | `""` | | -| networkPolicy.allowExternal | bool | `true` | | -| networkPolicy.egress.blockDNSResolution | bool | `false` | | -| networkPolicy.egress.enabled | bool | `false` | | -| networkPolicy.egress.ports | list | `[]` | | -| networkPolicy.egress.to | list | `[]` | | -| networkPolicy.enabled | bool | `false` | | -| networkPolicy.explicitNamespacesSelector | object | `{}` | | -| networkPolicy.ingress | bool | `true` | | -| nodeSelector | object | `{}` | | -| notifiers | object | `{}` | | -| persistence.accessModes[0] | string | `"ReadWriteOnce"` | | -| persistence.disableWarning | bool | `false` | | -| persistence.enabled | bool | `false` | | -| persistence.extraPvcLabels | object | `{}` | | -| persistence.finalizers[0] | string | `"kubernetes.io/pvc-protection"` | | -| persistence.inMemory.enabled | bool | `false` | | -| persistence.lookupVolumeName | bool | `true` | | -| persistence.size | string | `"10Gi"` | | -| persistence.type | string | `"pvc"` | | -| plugins | list | `[]` | | -| podDisruptionBudget | object | `{}` | | -| podPortName | string | `"grafana"` | | -| rbac.create | bool | `true` | | -| rbac.extraClusterRoleRules | list | `[]` | | -| rbac.extraRoleRules | list | `[]` | | -| rbac.namespaced | bool | `false` | | -| rbac.pspEnabled | bool | `false` | | -| rbac.pspUseAppArmor | bool | `false` | | -| readinessProbe.httpGet.path | string | `"/api/health"` | | -| readinessProbe.httpGet.port | int | `3000` | | -| replicas | int | `1` | | -| resources | object | `{}` | | -| revisionHistoryLimit | int | `10` | | -| route | object | `{"main":{"additionalRules":[],"annotations":{},"apiVersion":"gateway.networking.k8s.io/v1","enabled":false,"filters":[],"hostnames":[],"kind":"HTTPRoute","labels":{},"matches":[{"path":{"type":"PathPrefix","value":"/"}}],"parentRefs":[]}}` | BETA: Configure the gateway routes for the chart here. More routes can be added by adding a dictionary key like the 'main' route. Be aware that this is an early beta of this feature, kube-prometheus-stack does not guarantee this works and is subject to change. Being BETA this can/will change in the future without notice, do not use unless you want to take that risk [[ref]](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io%2fv1alpha2) | -| route.main.apiVersion | string | `"gateway.networking.k8s.io/v1"` | Set the route apiVersion, e.g. gateway.networking.k8s.io/v1 or gateway.networking.k8s.io/v1alpha2 | -| route.main.enabled | bool | `false` | Enables or disables the route | -| route.main.kind | string | `"HTTPRoute"` | Set the route kind Valid options are GRPCRoute, HTTPRoute, TCPRoute, TLSRoute, UDPRoute | -| securityContext.fsGroup | int | `472` | | -| securityContext.runAsGroup | int | `472` | | -| securityContext.runAsNonRoot | bool | `true` | | -| securityContext.runAsUser | int | `472` | | -| service.annotations | object | `{}` | | -| service.appProtocol | string | `""` | | -| service.enabled | bool | `true` | | -| service.ipFamilies | list | `[]` | | -| service.ipFamilyPolicy | string | `""` | | -| service.labels | object | `{}` | | -| service.loadBalancerClass | string | `""` | | -| service.loadBalancerIP | string | `""` | | -| service.loadBalancerSourceRanges | list | `[]` | | -| service.port | int | `80` | | -| service.portName | string | `"service"` | | -| service.sessionAffinity | string | `"ClientIP"` | | -| service.targetPort | int | `3000` | | -| service.type | string | `"ClusterIP"` | | -| serviceAccount.automountServiceAccountToken | bool | `false` | | -| serviceAccount.create | bool | `true` | | -| serviceAccount.labels | object | `{}` | | -| serviceAccount.name | string | `nil` | | -| serviceAccount.nameTest | string | `nil` | | -| serviceMonitor.basicAuth | object | `{}` | | -| serviceMonitor.enabled | bool | `false` | | -| serviceMonitor.interval | string | `"30s"` | | -| serviceMonitor.labels | object | `{}` | | -| serviceMonitor.metricRelabelings | list | `[]` | | -| serviceMonitor.path | string | `"/metrics"` | | -| serviceMonitor.relabelings | list | `[]` | | -| serviceMonitor.scheme | string | `"http"` | | -| serviceMonitor.scrapeTimeout | string | `"30s"` | | -| serviceMonitor.targetLabels | list | `[]` | | -| serviceMonitor.tlsConfig | object | `{}` | | -| sidecar.alerts.enabled | bool | `false` | | -| sidecar.alerts.env | object | `{}` | | -| sidecar.alerts.extraMounts | list | `[]` | | -| sidecar.alerts.initAlerts | bool | `false` | | -| sidecar.alerts.label | string | `"grafana_alert"` | | -| sidecar.alerts.labelValue | string | `""` | | -| sidecar.alerts.reloadURL | string | `"http://localhost:3000/api/admin/provisioning/alerting/reload"` | | -| sidecar.alerts.resource | string | `"both"` | | -| sidecar.alerts.script | string | `nil` | | -| sidecar.alerts.searchNamespace | string | `nil` | | -| sidecar.alerts.sizeLimit | object | `{}` | | -| sidecar.alerts.skipReload | bool | `false` | | -| sidecar.alerts.watchMethod | string | `"WATCH"` | | -| sidecar.dashboards.SCProvider | bool | `true` | | -| sidecar.dashboards.defaultFolderName | string | `nil` | | -| sidecar.dashboards.enabled | bool | `false` | | -| sidecar.dashboards.env | object | `{}` | | -| sidecar.dashboards.envValueFrom | object | `{}` | | -| sidecar.dashboards.extraMounts | list | `[]` | | -| sidecar.dashboards.folder | string | `"/tmp/dashboards"` | | -| sidecar.dashboards.folderAnnotation | string | `nil` | | -| sidecar.dashboards.label | string | `"grafana_dashboard"` | | -| sidecar.dashboards.labelValue | string | `""` | | -| sidecar.dashboards.provider.allowUiUpdates | bool | `false` | | -| sidecar.dashboards.provider.disableDelete | bool | `false` | | -| sidecar.dashboards.provider.folder | string | `""` | | -| sidecar.dashboards.provider.folderUid | string | `""` | | -| sidecar.dashboards.provider.foldersFromFilesStructure | bool | `false` | | -| sidecar.dashboards.provider.name | string | `"sidecarProvider"` | | -| sidecar.dashboards.provider.orgid | int | `1` | | -| sidecar.dashboards.provider.type | string | `"file"` | | -| sidecar.dashboards.reloadURL | string | `"http://localhost:3000/api/admin/provisioning/dashboards/reload"` | | -| sidecar.dashboards.resource | string | `"both"` | | -| sidecar.dashboards.script | string | `nil` | | -| sidecar.dashboards.searchNamespace | string | `nil` | | -| sidecar.dashboards.sizeLimit | object | `{}` | | -| sidecar.dashboards.skipReload | bool | `false` | | -| sidecar.dashboards.watchMethod | string | `"WATCH"` | | -| sidecar.datasources.enabled | bool | `false` | | -| sidecar.datasources.env | object | `{}` | | -| sidecar.datasources.envValueFrom | object | `{}` | | -| sidecar.datasources.extraMounts | list | `[]` | | -| sidecar.datasources.initDatasources | bool | `false` | | -| sidecar.datasources.label | string | `"grafana_datasource"` | | -| sidecar.datasources.labelValue | string | `""` | | -| sidecar.datasources.reloadURL | string | `"http://localhost:3000/api/admin/provisioning/datasources/reload"` | | -| sidecar.datasources.resource | string | `"both"` | | -| sidecar.datasources.script | string | `nil` | | -| sidecar.datasources.searchNamespace | string | `nil` | | -| sidecar.datasources.sizeLimit | object | `{}` | | -| sidecar.datasources.skipReload | bool | `false` | | -| sidecar.datasources.watchMethod | string | `"WATCH"` | | -| sidecar.enableUniqueFilenames | bool | `false` | | -| sidecar.image.registry | string | `"quay.io"` | The Docker registry | -| sidecar.image.repository | string | `"kiwigrid/k8s-sidecar"` | | -| sidecar.image.sha | string | `""` | | -| sidecar.image.tag | string | `"1.28.0"` | | -| sidecar.imagePullPolicy | string | `"IfNotPresent"` | | -| sidecar.livenessProbe | object | `{}` | | -| sidecar.notifiers.enabled | bool | `false` | | -| sidecar.notifiers.env | object | `{}` | | -| sidecar.notifiers.extraMounts | list | `[]` | | -| sidecar.notifiers.initNotifiers | bool | `false` | | -| sidecar.notifiers.label | string | `"grafana_notifier"` | | -| sidecar.notifiers.labelValue | string | `""` | | -| sidecar.notifiers.reloadURL | string | `"http://localhost:3000/api/admin/provisioning/notifications/reload"` | | -| sidecar.notifiers.resource | string | `"both"` | | -| sidecar.notifiers.script | string | `nil` | | -| sidecar.notifiers.searchNamespace | string | `nil` | | -| sidecar.notifiers.sizeLimit | object | `{}` | | -| sidecar.notifiers.skipReload | bool | `false` | | -| sidecar.notifiers.watchMethod | string | `"WATCH"` | | -| sidecar.plugins.enabled | bool | `false` | | -| sidecar.plugins.env | object | `{}` | | -| sidecar.plugins.extraMounts | list | `[]` | | -| sidecar.plugins.initPlugins | bool | `false` | | -| sidecar.plugins.label | string | `"grafana_plugin"` | | -| sidecar.plugins.labelValue | string | `""` | | -| sidecar.plugins.reloadURL | string | `"http://localhost:3000/api/admin/provisioning/plugins/reload"` | | -| sidecar.plugins.resource | string | `"both"` | | -| sidecar.plugins.script | string | `nil` | | -| sidecar.plugins.searchNamespace | string | `nil` | | -| sidecar.plugins.sizeLimit | object | `{}` | | -| sidecar.plugins.skipReload | bool | `false` | | -| sidecar.plugins.watchMethod | string | `"WATCH"` | | -| sidecar.readinessProbe | object | `{}` | | -| sidecar.resources | object | `{}` | | -| sidecar.securityContext.allowPrivilegeEscalation | bool | `false` | | -| sidecar.securityContext.capabilities.drop[0] | string | `"ALL"` | | -| sidecar.securityContext.seccompProfile.type | string | `"RuntimeDefault"` | | -| smtp.existingSecret | string | `""` | | -| smtp.passwordKey | string | `"password"` | | -| smtp.userKey | string | `"user"` | | -| testFramework.enabled | bool | `true` | | -| testFramework.image.registry | string | `"docker.io"` | The Docker registry | -| testFramework.image.repository | string | `"bats/bats"` | | -| testFramework.image.tag | string | `"v1.4.1"` | | -| testFramework.imagePullPolicy | string | `"IfNotPresent"` | | -| testFramework.resources | object | `{}` | | -| testFramework.securityContext | object | `{}` | | -| tolerations | list | `[]` | | -| topologySpreadConstraints | list | `[]` | | -| useStatefulSet | bool | `false` | | - ----------------------------------------------- -Autogenerated from chart metadata using [helm-docs v1.8.1](https://github.com/norwoodj/helm-docs/releases/v1.8.1) +# Grafana Helm Chart + +* Installs the web dashboarding system [Grafana](http://grafana.org/) + +## Get Repo Info + +```console +helm repo add grafana https://grafana.github.io/helm-charts +helm repo update +``` + +_See [helm repo](https://helm.sh/docs/helm/helm_repo/) for command documentation._ + +## Installing the Chart + +To install the chart with the release name `my-release`: + +```console +helm install my-release grafana/grafana +``` + +## Uninstalling the Chart + +To uninstall/delete the my-release deployment: + +```console +helm delete my-release +``` + +The command removes all the Kubernetes components associated with the chart and deletes the release. + +## Upgrading an existing Release to a new major version + +A major chart version change (like v1.2.3 -> v2.0.0) indicates that there is an +incompatible breaking change needing manual actions. + +### To 4.0.0 (And 3.12.1) + +This version requires Helm >= 2.12.0. + +### To 5.0.0 + +You have to add --force to your helm upgrade command as the labels of the chart have changed. + +### To 6.0.0 + +This version requires Helm >= 3.1.0. + +### To 7.0.0 + +For consistency with other Helm charts, the `global.image.registry` parameter was renamed +to `global.imageRegistry`. If you were not previously setting `global.image.registry`, no action +is required on upgrade. If you were previously setting `global.image.registry`, you will +need to instead set `global.imageRegistry`. + +## Configuration + +| Parameter | Description | Default | +|-------------------------------------------|-----------------------------------------------|---------------------------------------------------------| +| `replicas` | Number of nodes | `1` | +| `podDisruptionBudget.minAvailable` | Pod disruption minimum available | `nil` | +| `podDisruptionBudget.maxUnavailable` | Pod disruption maximum unavailable | `nil` | +| `podDisruptionBudget.apiVersion` | Pod disruption apiVersion | `nil` | +| `deploymentStrategy` | Deployment strategy | `{ "type": "RollingUpdate" }` | +| `livenessProbe` | Liveness Probe settings | `{ "httpGet": { "path": "/api/health", "port": 3000 } "initialDelaySeconds": 60, "timeoutSeconds": 30, "failureThreshold": 10 }` | +| `readinessProbe` | Readiness Probe settings | `{ "httpGet": { "path": "/api/health", "port": 3000 } }`| +| `securityContext` | Deployment securityContext | `{"runAsUser": 472, "runAsGroup": 472, "fsGroup": 472}` | +| `priorityClassName` | Name of Priority Class to assign pods | `nil` | +| `image.registry` | Image registry | `docker.io` | +| `image.repository` | Image repository | `grafana/grafana` | +| `image.tag` | Overrides the Grafana image tag whose default is the chart appVersion (`Must be >= 5.0.0`) | `` | +| `image.sha` | Image sha (optional) | `` | +| `image.pullPolicy` | Image pull policy | `IfNotPresent` | +| `image.pullSecrets` | Image pull secrets (can be templated) | `[]` | +| `service.enabled` | Enable grafana service | `true` | +| `service.ipFamilies` | Kubernetes service IP families | `[]` | +| `service.ipFamilyPolicy` | Kubernetes service IP family policy | `""` | +| `service.type` | Kubernetes service type | `ClusterIP` | +| `service.port` | Kubernetes port where service is exposed | `80` | +| `service.portName` | Name of the port on the service | `service` | +| `service.appProtocol` | Adds the appProtocol field to the service | `` | +| `service.targetPort` | Internal service is port | `3000` | +| `service.nodePort` | Kubernetes service nodePort | `nil` | +| `service.annotations` | Service annotations (can be templated) | `{}` | +| `service.labels` | Custom labels | `{}` | +| `service.clusterIP` | internal cluster service IP | `nil` | +| `service.loadBalancerIP` | IP address to assign to load balancer (if supported) | `nil` | +| `service.loadBalancerSourceRanges` | list of IP CIDRs allowed access to lb (if supported) | `[]` | +| `service.externalIPs` | service external IP addresses | `[]` | +| `service.externalTrafficPolicy` | change the default externalTrafficPolicy | `nil` | +| `headlessService` | Create a headless service | `false` | +| `extraExposePorts` | Additional service ports for sidecar containers| `[]` | +| `hostAliases` | adds rules to the pod's /etc/hosts | `[]` | +| `ingress.enabled` | Enables Ingress | `false` | +| `ingress.annotations` | Ingress annotations (values are templated) | `{}` | +| `ingress.labels` | Custom labels | `{}` | +| `ingress.path` | Ingress accepted path | `/` | +| `ingress.pathType` | Ingress type of path | `Prefix` | +| `ingress.hosts` | Ingress accepted hostnames | `["chart-example.local"]` | +| `ingress.extraPaths` | Ingress extra paths to prepend to every host configuration. Useful when configuring [custom actions with AWS ALB Ingress Controller](https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.6/guide/ingress/annotations/#actions). Requires `ingress.hosts` to have one or more host entries. | `[]` | +| `ingress.tls` | Ingress TLS configuration | `[]` | +| `ingress.ingressClassName` | Ingress Class Name. MAY be required for Kubernetes versions >= 1.18 | `""` | +| `resources` | CPU/Memory resource requests/limits | `{}` | +| `nodeSelector` | Node labels for pod assignment | `{}` | +| `tolerations` | Toleration labels for pod assignment | `[]` | +| `affinity` | Affinity settings for pod assignment | `{}` | +| `extraInitContainers` | Init containers to add to the grafana pod | `{}` | +| `extraContainers` | Sidecar containers to add to the grafana pod | `""` | +| `extraContainerVolumes` | Volumes that can be mounted in sidecar containers | `[]` | +| `extraLabels` | Custom labels for all manifests | `{}` | +| `schedulerName` | Name of the k8s scheduler (other than default) | `nil` | +| `persistence.enabled` | Use persistent volume to store data | `false` | +| `persistence.type` | Type of persistence (`pvc` or `statefulset`) | `pvc` | +| `persistence.size` | Size of persistent volume claim | `10Gi` | +| `persistence.existingClaim` | Use an existing PVC to persist data (can be templated) | `nil` | +| `persistence.storageClassName` | Type of persistent volume claim | `nil` | +| `persistence.accessModes` | Persistence access modes | `[ReadWriteOnce]` | +| `persistence.annotations` | PersistentVolumeClaim annotations | `{}` | +| `persistence.finalizers` | PersistentVolumeClaim finalizers | `[ "kubernetes.io/pvc-protection" ]` | +| `persistence.extraPvcLabels` | Extra labels to apply to a PVC. | `{}` | +| `persistence.subPath` | Mount a sub dir of the persistent volume (can be templated) | `nil` | +| `persistence.inMemory.enabled` | If persistence is not enabled, whether to mount the local storage in-memory to improve performance | `false` | +| `persistence.inMemory.sizeLimit` | SizeLimit for the in-memory local storage | `nil` | +| `persistence.disableWarning` | Hide NOTES warning, useful when persisting to a database | `false` | +| `initChownData.enabled` | If false, don't reset data ownership at startup | true | +| `initChownData.image.registry` | init-chown-data container image registry | `docker.io` | +| `initChownData.image.repository` | init-chown-data container image repository | `busybox` | +| `initChownData.image.tag` | init-chown-data container image tag | `1.31.1` | +| `initChownData.image.sha` | init-chown-data container image sha (optional)| `""` | +| `initChownData.image.pullPolicy` | init-chown-data container image pull policy | `IfNotPresent` | +| `initChownData.resources` | init-chown-data pod resource requests & limits | `{}` | +| `schedulerName` | Alternate scheduler name | `nil` | +| `env` | Extra environment variables passed to pods | `{}` | +| `envValueFrom` | Environment variables from alternate sources. See the API docs on [EnvVarSource](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#envvarsource-v1-core) for format details. Can be templated | `{}` | +| `envFromSecret` | Name of a Kubernetes secret (must be manually created in the same namespace) containing values to be added to the environment. Can be templated | `""` | +| `envFromSecrets` | List of Kubernetes secrets (must be manually created in the same namespace) containing values to be added to the environment. Can be templated | `[]` | +| `envFromConfigMaps` | List of Kubernetes ConfigMaps (must be manually created in the same namespace) containing values to be added to the environment. Can be templated | `[]` | +| `envRenderSecret` | Sensible environment variables passed to pods and stored as secret. (passed through [tpl](https://helm.sh/docs/howto/charts_tips_and_tricks/#using-the-tpl-function)) | `{}` | +| `enableServiceLinks` | Inject Kubernetes services as environment variables. | `true` | +| `extraSecretMounts` | Additional grafana server secret mounts | `[]` | +| `extraVolumeMounts` | Additional grafana server volume mounts | `[]` | +| `extraVolumes` | Additional Grafana server volumes | `[]` | +| `automountServiceAccountToken` | Mounted the service account token on the grafana pod. Mandatory, if sidecars are enabled | `true` | +| `createConfigmap` | Enable creating the grafana configmap | `true` | +| `extraConfigmapMounts` | Additional grafana server configMap volume mounts (values are templated) | `[]` | +| `extraEmptyDirMounts` | Additional grafana server emptyDir volume mounts | `[]` | +| `plugins` | Plugins to be loaded along with Grafana | `[]` | +| `datasources` | Configure grafana datasources (passed through tpl) | `{}` | +| `alerting` | Configure grafana alerting (passed through tpl) | `{}` | +| `notifiers` | Configure grafana notifiers | `{}` | +| `dashboardProviders` | Configure grafana dashboard providers | `{}` | +| `dashboards` | Dashboards to import | `{}` | +| `dashboardsConfigMaps` | ConfigMaps reference that contains dashboards | `{}` | +| `grafana.ini` | Grafana's primary configuration | `{}` | +| `global.imageRegistry` | Global image pull registry for all images. | `null` | +| `global.imagePullSecrets` | Global image pull secrets (can be templated). Allows either an array of {name: pullSecret} maps (k8s-style), or an array of strings (more common helm-style). | `[]` | +| `ldap.enabled` | Enable LDAP authentication | `false` | +| `ldap.existingSecret` | The name of an existing secret containing the `ldap.toml` file, this must have the key `ldap-toml`. | `""` | +| `ldap.config` | Grafana's LDAP configuration | `""` | +| `annotations` | Deployment annotations | `{}` | +| `labels` | Deployment labels | `{}` | +| `podAnnotations` | Pod annotations | `{}` | +| `podLabels` | Pod labels | `{}` | +| `podPortName` | Name of the grafana port on the pod | `grafana` | +| `lifecycleHooks` | Lifecycle hooks for podStart and preStop [Example](https://kubernetes.io/docs/tasks/configure-pod-container/attach-handler-lifecycle-event/#define-poststart-and-prestop-handlers) | `{}` | +| `sidecar.image.registry` | Sidecar image registry | `quay.io` | +| `sidecar.image.repository` | Sidecar image repository | `kiwigrid/k8s-sidecar` | +| `sidecar.image.tag` | Sidecar image tag | `1.28.0` | +| `sidecar.image.sha` | Sidecar image sha (optional) | `""` | +| `sidecar.imagePullPolicy` | Sidecar image pull policy | `IfNotPresent` | +| `sidecar.resources` | Sidecar resources | `{}` | +| `sidecar.securityContext` | Sidecar securityContext | `{}` | +| `sidecar.enableUniqueFilenames` | Sets the kiwigrid/k8s-sidecar UNIQUE_FILENAMES environment variable. If set to `true` the sidecar will create unique filenames where duplicate data keys exist between ConfigMaps and/or Secrets within the same or multiple Namespaces. | `false` | +| `sidecar.alerts.enabled` | Enables the cluster wide search for alerts and adds/updates/deletes them in grafana |`false` | +| `sidecar.alerts.label` | Label that config maps with alerts should have to be added | `grafana_alert` | +| `sidecar.alerts.labelValue` | Label value that config maps with alerts should have to be added | `""` | +| `sidecar.alerts.searchNamespace` | Namespaces list. If specified, the sidecar will search for alerts config-maps inside these namespaces. Otherwise the namespace in which the sidecar is running will be used. It's also possible to specify ALL to search in all namespaces. | `nil` | +| `sidecar.alerts.watchMethod` | Method to use to detect ConfigMap changes. With WATCH the sidecar will do a WATCH requests, with SLEEP it will list all ConfigMaps, then sleep for 60 seconds. | `WATCH` | +| `sidecar.alerts.resource` | Should the sidecar looks into secrets, configmaps or both. | `both` | +| `sidecar.alerts.reloadURL` | Full url of datasource configuration reload API endpoint, to invoke after a config-map change | `"http://localhost:3000/api/admin/provisioning/alerting/reload"` | +| `sidecar.alerts.skipReload` | Enabling this omits defining the REQ_URL and REQ_METHOD environment variables | `false` | +| `sidecar.alerts.initAlerts` | Set to true to deploy the alerts sidecar as an initContainer. This is needed if skipReload is true, to load any alerts defined at startup time. | `false` | +| `sidecar.alerts.extraMounts` | Additional alerts sidecar volume mounts. | `[]` | +| `sidecar.dashboards.enabled` | Enables the cluster wide search for dashboards and adds/updates/deletes them in grafana | `false` | +| `sidecar.dashboards.SCProvider` | Enables creation of sidecar provider | `true` | +| `sidecar.dashboards.provider.name` | Unique name of the grafana provider | `sidecarProvider` | +| `sidecar.dashboards.provider.orgid` | Id of the organisation, to which the dashboards should be added | `1` | +| `sidecar.dashboards.provider.folder` | Logical folder in which grafana groups dashboards | `""` | +| `sidecar.dashboards.provider.folderUid` | Allows you to specify the static UID for the logical folder above | `""` | +| `sidecar.dashboards.provider.disableDelete` | Activate to avoid the deletion of imported dashboards | `false` | +| `sidecar.dashboards.provider.allowUiUpdates` | Allow updating provisioned dashboards from the UI | `false` | +| `sidecar.dashboards.provider.type` | Provider type | `file` | +| `sidecar.dashboards.provider.foldersFromFilesStructure` | Allow Grafana to replicate dashboard structure from filesystem. | `false` | +| `sidecar.dashboards.watchMethod` | Method to use to detect ConfigMap changes. With WATCH the sidecar will do a WATCH requests, with SLEEP it will list all ConfigMaps, then sleep for 60 seconds. | `WATCH` | +| `sidecar.skipTlsVerify` | Set to true to skip tls verification for kube api calls | `nil` | +| `sidecar.dashboards.label` | Label that config maps with dashboards should have to be added | `grafana_dashboard` | +| `sidecar.dashboards.labelValue` | Label value that config maps with dashboards should have to be added | `""` | +| `sidecar.dashboards.folder` | Folder in the pod that should hold the collected dashboards (unless `sidecar.dashboards.defaultFolderName` is set). This path will be mounted. | `/tmp/dashboards` | +| `sidecar.dashboards.folderAnnotation` | The annotation the sidecar will look for in configmaps to override the destination folder for files | `nil` | +| `sidecar.dashboards.defaultFolderName` | The default folder name, it will create a subfolder under the `sidecar.dashboards.folder` and put dashboards in there instead | `nil` | +| `sidecar.dashboards.searchNamespace` | Namespaces list. If specified, the sidecar will search for dashboards config-maps inside these namespaces. Otherwise the namespace in which the sidecar is running will be used. It's also possible to specify ALL to search in all namespaces. | `nil` | +| `sidecar.dashboards.script` | Absolute path to shell script to execute after a configmap got reloaded. | `nil` | +| `sidecar.dashboards.reloadURL` | Full url of dashboards configuration reload API endpoint, to invoke after a config-map change | `"http://localhost:3000/api/admin/provisioning/dashboards/reload"` | +| `sidecar.dashboards.skipReload` | Enabling this omits defining the REQ_USERNAME, REQ_PASSWORD, REQ_URL and REQ_METHOD environment variables | `false` | +| `sidecar.dashboards.resource` | Should the sidecar looks into secrets, configmaps or both. | `both` | +| `sidecar.dashboards.extraMounts` | Additional dashboard sidecar volume mounts. | `[]` | +| `sidecar.datasources.enabled` | Enables the cluster wide search for datasources and adds/updates/deletes them in grafana |`false` | +| `sidecar.datasources.label` | Label that config maps with datasources should have to be added | `grafana_datasource` | +| `sidecar.datasources.labelValue` | Label value that config maps with datasources should have to be added | `""` | +| `sidecar.datasources.searchNamespace` | Namespaces list. If specified, the sidecar will search for datasources config-maps inside these namespaces. Otherwise the namespace in which the sidecar is running will be used. It's also possible to specify ALL to search in all namespaces. | `nil` | +| `sidecar.datasources.watchMethod` | Method to use to detect ConfigMap changes. With WATCH the sidecar will do a WATCH requests, with SLEEP it will list all ConfigMaps, then sleep for 60 seconds. | `WATCH` | +| `sidecar.datasources.resource` | Should the sidecar looks into secrets, configmaps or both. | `both` | +| `sidecar.datasources.reloadURL` | Full url of datasource configuration reload API endpoint, to invoke after a config-map change | `"http://localhost:3000/api/admin/provisioning/datasources/reload"` | +| `sidecar.datasources.skipReload` | Enabling this omits defining the REQ_URL and REQ_METHOD environment variables | `false` | +| `sidecar.datasources.initDatasources` | Set to true to deploy the datasource sidecar as an initContainer in addition to a container. This is needed if skipReload is true, to load any datasources defined at startup time. | `false` | +| `sidecar.notifiers.enabled` | Enables the cluster wide search for notifiers and adds/updates/deletes them in grafana | `false` | +| `sidecar.notifiers.label` | Label that config maps with notifiers should have to be added | `grafana_notifier` | +| `sidecar.notifiers.labelValue` | Label value that config maps with notifiers should have to be added | `""` | +| `sidecar.notifiers.searchNamespace` | Namespaces list. If specified, the sidecar will search for notifiers config-maps (or secrets) inside these namespaces. Otherwise the namespace in which the sidecar is running will be used. It's also possible to specify ALL to search in all namespaces. | `nil` | +| `sidecar.notifiers.watchMethod` | Method to use to detect ConfigMap changes. With WATCH the sidecar will do a WATCH requests, with SLEEP it will list all ConfigMaps, then sleep for 60 seconds. | `WATCH` | +| `sidecar.notifiers.resource` | Should the sidecar looks into secrets, configmaps or both. | `both` | +| `sidecar.notifiers.reloadURL` | Full url of notifier configuration reload API endpoint, to invoke after a config-map change | `"http://localhost:3000/api/admin/provisioning/notifications/reload"` | +| `sidecar.notifiers.skipReload` | Enabling this omits defining the REQ_URL and REQ_METHOD environment variables | `false` | +| `sidecar.notifiers.initNotifiers` | Set to true to deploy the notifier sidecar as an initContainer in addition to a container. This is needed if skipReload is true, to load any notifiers defined at startup time. | `false` | +| `smtp.existingSecret` | The name of an existing secret containing the SMTP credentials. | `""` | +| `smtp.userKey` | The key in the existing SMTP secret containing the username. | `"user"` | +| `smtp.passwordKey` | The key in the existing SMTP secret containing the password. | `"password"` | +| `admin.existingSecret` | The name of an existing secret containing the admin credentials (can be templated). | `""` | +| `admin.userKey` | The key in the existing admin secret containing the username. | `"admin-user"` | +| `admin.passwordKey` | The key in the existing admin secret containing the password. | `"admin-password"` | +| `serviceAccount.automountServiceAccountToken` | Automount the service account token on all pods where is service account is used | `false` | +| `serviceAccount.annotations` | ServiceAccount annotations | | +| `serviceAccount.create` | Create service account | `true` | +| `serviceAccount.labels` | ServiceAccount labels | `{}` | +| `serviceAccount.name` | Service account name to use, when empty will be set to created account if `serviceAccount.create` is set else to `default` | `` | +| `serviceAccount.nameTest` | Service account name to use for test, when empty will be set to created account if `serviceAccount.create` is set else to `default` | `nil` | +| `rbac.create` | Create and use RBAC resources | `true` | +| `rbac.namespaced` | Creates Role and Rolebinding instead of the default ClusterRole and ClusteRoleBindings for the grafana instance | `false` | +| `rbac.useExistingRole` | Set to a rolename to use existing role - skipping role creating - but still doing serviceaccount and rolebinding to the rolename set here. | `nil` | +| `rbac.pspEnabled` | Create PodSecurityPolicy (with `rbac.create`, grant roles permissions as well) | `false` | +| `rbac.pspUseAppArmor` | Enforce AppArmor in created PodSecurityPolicy (requires `rbac.pspEnabled`) | `false` | +| `rbac.extraRoleRules` | Additional rules to add to the Role | [] | +| `rbac.extraClusterRoleRules` | Additional rules to add to the ClusterRole | [] | +| `command` | Define command to be executed by grafana container at startup | `nil` | +| `args` | Define additional args if command is used | `nil` | +| `testFramework.enabled` | Whether to create test-related resources | `true` | +| `testFramework.image.registry` | `test-framework` image registry. | `docker.io` | +| `testFramework.image.repository` | `test-framework` image repository. | `bats/bats` | +| `testFramework.image.tag` | `test-framework` image tag. | `v1.4.1` | +| `testFramework.imagePullPolicy` | `test-framework` image pull policy. | `IfNotPresent` | +| `testFramework.securityContext` | `test-framework` securityContext | `{}` | +| `downloadDashboards.env` | Environment variables to be passed to the `download-dashboards` container | `{}` | +| `downloadDashboards.envFromSecret` | Name of a Kubernetes secret (must be manually created in the same namespace) containing values to be added to the environment. Can be templated | `""` | +| `downloadDashboards.resources` | Resources of `download-dashboards` container | `{}` | +| `downloadDashboardsImage.registry` | Curl docker image registry | `docker.io` | +| `downloadDashboardsImage.repository` | Curl docker image repository | `curlimages/curl` | +| `downloadDashboardsImage.tag` | Curl docker image tag | `7.73.0` | +| `downloadDashboardsImage.sha` | Curl docker image sha (optional) | `""` | +| `downloadDashboardsImage.pullPolicy` | Curl docker image pull policy | `IfNotPresent` | +| `namespaceOverride` | Override the deployment namespace | `""` (`Release.Namespace`) | +| `serviceMonitor.enabled` | Use servicemonitor from prometheus operator | `false` | +| `serviceMonitor.namespace` | Namespace this servicemonitor is installed in | | +| `serviceMonitor.interval` | How frequently Prometheus should scrape | `1m` | +| `serviceMonitor.path` | Path to scrape | `/metrics` | +| `serviceMonitor.scheme` | Scheme to use for metrics scraping | `http` | +| `serviceMonitor.tlsConfig` | TLS configuration block for the endpoint | `{}` | +| `serviceMonitor.labels` | Labels for the servicemonitor passed to Prometheus Operator | `{}` | +| `serviceMonitor.scrapeTimeout` | Timeout after which the scrape is ended | `30s` | +| `serviceMonitor.relabelings` | RelabelConfigs to apply to samples before scraping. | `[]` | +| `serviceMonitor.metricRelabelings` | MetricRelabelConfigs to apply to samples before ingestion. | `[]` | +| `revisionHistoryLimit` | Number of old ReplicaSets to retain | `10` | +| `imageRenderer.enabled` | Enable the image-renderer deployment & service | `false` | +| `imageRenderer.image.registry` | image-renderer Image registry | `docker.io` | +| `imageRenderer.image.repository` | image-renderer Image repository | `grafana/grafana-image-renderer` | +| `imageRenderer.image.tag` | image-renderer Image tag | `latest` | +| `imageRenderer.image.sha` | image-renderer Image sha (optional) | `""` | +| `imageRenderer.image.pullPolicy` | image-renderer ImagePullPolicy | `Always` | +| `imageRenderer.env` | extra env-vars for image-renderer | `{}` | +| `imageRenderer.envValueFrom` | Environment variables for image-renderer from alternate sources. See the API docs on [EnvVarSource](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#envvarsource-v1-core) for format details. Can be templated | `{}` | +| `imageRenderer.extraConfigmapMounts` | Additional image-renderer configMap volume mounts (values are templated) | `[]` | +| `imageRenderer.extraSecretMounts` | Additional image-renderer secret volume mounts | `[]` | +| `imageRenderer.extraVolumeMounts` | Additional image-renderer volume mounts | `[]` | +| `imageRenderer.extraVolumes` | Additional image-renderer volumes | `[]` | +| `imageRenderer.serviceAccountName` | image-renderer deployment serviceAccountName | `""` | +| `imageRenderer.securityContext` | image-renderer deployment securityContext | `{}` | +| `imageRenderer.podAnnotations` | image-renderer image-renderer pod annotation | `{}` | +| `imageRenderer.hostAliases` | image-renderer deployment Host Aliases | `[]` | +| `imageRenderer.priorityClassName` | image-renderer deployment priority class | `''` | +| `imageRenderer.service.enabled` | Enable the image-renderer service | `true` | +| `imageRenderer.service.portName` | image-renderer service port name | `http` | +| `imageRenderer.service.port` | image-renderer port used by deployment | `8081` | +| `imageRenderer.service.targetPort` | image-renderer service port used by service | `8081` | +| `imageRenderer.appProtocol` | Adds the appProtocol field to the service | `` | +| `imageRenderer.grafanaSubPath` | Grafana sub path to use for image renderer callback url | `''` | +| `imageRenderer.serverURL` | Remote image renderer url | `''` | +| `imageRenderer.renderingCallbackURL` | Callback url for the Grafana image renderer | `''` | +| `imageRenderer.podPortName` | name of the image-renderer port on the pod | `http` | +| `imageRenderer.revisionHistoryLimit` | number of image-renderer replica sets to keep | `10` | +| `imageRenderer.networkPolicy.limitIngress` | Enable a NetworkPolicy to limit inbound traffic from only the created grafana pods | `true` | +| `imageRenderer.networkPolicy.limitEgress` | Enable a NetworkPolicy to limit outbound traffic to only the created grafana pods | `false` | +| `imageRenderer.resources` | Set resource limits for image-renderer pods | `{}` | +| `imageRenderer.nodeSelector` | Node labels for pod assignment | `{}` | +| `imageRenderer.tolerations` | Toleration labels for pod assignment | `[]` | +| `imageRenderer.affinity` | Affinity settings for pod assignment | `{}` | +| `networkPolicy.enabled` | Enable creation of NetworkPolicy resources. | `false` | +| `networkPolicy.allowExternal` | Don't require client label for connections | `true` | +| `networkPolicy.explicitNamespacesSelector` | A Kubernetes LabelSelector to explicitly select namespaces from which traffic could be allowed | `{}` | +| `networkPolicy.ingress` | Enable the creation of an ingress network policy | `true` | +| `networkPolicy.egress.enabled` | Enable the creation of an egress network policy | `false` | +| `networkPolicy.egress.ports` | An array of ports to allow for the egress | `[]` | +| `enableKubeBackwardCompatibility` | Enable backward compatibility of kubernetes where pod's defintion version below 1.13 doesn't have the enableServiceLinks option | `false` | + +### Example ingress with path + +With grafana 6.3 and above + +```yaml +grafana.ini: + server: + domain: monitoring.example.com + root_url: "%(protocol)s://%(domain)s/grafana" + serve_from_sub_path: true +ingress: + enabled: true + hosts: + - "monitoring.example.com" + path: "/grafana" +``` + +### Example of extraVolumeMounts and extraVolumes + +Configure additional volumes with `extraVolumes` and volume mounts with `extraVolumeMounts`. + +Example for `extraVolumeMounts` and corresponding `extraVolumes`: + +```yaml +extraVolumeMounts: + - name: plugins + mountPath: /var/lib/grafana/plugins + subPath: configs/grafana/plugins + readOnly: false + - name: dashboards + mountPath: /var/lib/grafana/dashboards + hostPath: /usr/shared/grafana/dashboards + readOnly: false + +extraVolumes: + - name: plugins + existingClaim: existing-grafana-claim + - name: dashboards + hostPath: /usr/shared/grafana/dashboards +``` + +Volumes default to `emptyDir`. Set to `persistentVolumeClaim`, +`hostPath`, `csi`, or `configMap` for other types. For a +`persistentVolumeClaim`, specify an existing claim name with +`existingClaim`. + +## Import dashboards + +There are a few methods to import dashboards to Grafana. Below are some examples and explanations as to how to use each method: + +```yaml +dashboards: + default: + some-dashboard: + json: | + { + "annotations": + + ... + # Complete json file here + ... + + "title": "Some Dashboard", + "uid": "abcd1234", + "version": 1 + } + custom-dashboard: + # This is a path to a file inside the dashboards directory inside the chart directory + file: dashboards/custom-dashboard.json + prometheus-stats: + # Ref: https://grafana.com/dashboards/2 + gnetId: 2 + revision: 2 + datasource: Prometheus + loki-dashboard-quick-search: + gnetId: 12019 + revision: 2 + datasource: + - name: DS_PROMETHEUS + value: Prometheus + - name: DS_LOKI + value: Loki + local-dashboard: + url: https://raw.githubusercontent.com/user/repository/master/dashboards/dashboard.json +``` + +## BASE64 dashboards + +Dashboards could be stored on a server that does not return JSON directly and instead of it returns a Base64 encoded file (e.g. Gerrit) +A new parameter has been added to the url use case so if you specify a b64content value equals to true after the url entry a Base64 decoding is applied before save the file to disk. +If this entry is not set or is equals to false not decoding is applied to the file before saving it to disk. + +### Gerrit use case + +Gerrit API for download files has the following schema: where {project-name} and +{file-id} usually has '/' in their values and so they MUST be replaced by %2F so if project-name is user/repo, branch-id is master and file-id is equals to dir1/dir2/dashboard +the url value is + +## Sidecar for dashboards + +If the parameter `sidecar.dashboards.enabled` is set, a sidecar container is deployed in the grafana +pod. This container watches all configmaps (or secrets) in the cluster and filters out the ones with +a label as defined in `sidecar.dashboards.label`. The files defined in those configmaps are written +to a folder and accessed by grafana. Changes to the configmaps are monitored and the imported +dashboards are deleted/updated. + +A recommendation is to use one configmap per dashboard, as a reduction of multiple dashboards inside +one configmap is currently not properly mirrored in grafana. + +Example dashboard config: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: sample-grafana-dashboard + labels: + grafana_dashboard: "1" +data: + k8s-dashboard.json: |- + [...] +``` + +## Sidecar for datasources + +If the parameter `sidecar.datasources.enabled` is set, an init container is deployed in the grafana +pod. This container lists all secrets (or configmaps, though not recommended) in the cluster and +filters out the ones with a label as defined in `sidecar.datasources.label`. The files defined in +those secrets are written to a folder and accessed by grafana on startup. Using these yaml files, +the data sources in grafana can be imported. + +Should you aim for reloading datasources in Grafana each time the config is changed, set `sidecar.datasources.skipReload: false` and adjust `sidecar.datasources.reloadURL` to `http://..svc.cluster.local/api/admin/provisioning/datasources/reload`. + +Secrets are recommended over configmaps for this usecase because datasources usually contain private +data like usernames and passwords. Secrets are the more appropriate cluster resource to manage those. + +Example values to add a postgres datasource as a kubernetes secret: + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: grafana-datasources + labels: + grafana_datasource: 'true' # default value for: sidecar.datasources.label +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' # disable/require/verify-ca/verify-full + maxOpenConns: 0 # Grafana v5.4+ + maxIdleConns: 2 # Grafana v5.4+ + connMaxLifetime: 14400 # Grafana v5.4+ + postgresVersion: 1000 # 903=9.3, 904=9.4, 905=9.5, 906=9.6, 1000=10 + timescaledb: false + # allow users to edit datasources from the UI. + editable: false +``` + +Example values to add a datasource adapted from [Grafana](http://docs.grafana.org/administration/provisioning/#example-datasource-config-file): + +```yaml +datasources: + datasources.yaml: + apiVersion: 1 + datasources: + # name of the datasource. Required + - name: Graphite + # datasource type. Required + type: graphite + # access mode. proxy or direct (Server or Browser in the UI). Required + access: proxy + # org id. will default to orgId 1 if not specified + orgId: 1 + # url + url: http://localhost:8080 + # database password, if used + password: + # database user, if used + user: + # database name, if used + database: + # enable/disable basic auth + basicAuth: + # basic auth username + basicAuthUser: + # basic auth password + basicAuthPassword: + # enable/disable with credentials headers + withCredentials: + # mark as default datasource. Max one per org + isDefault: + # fields that will be converted to json and stored in json_data + jsonData: + graphiteVersion: "1.1" + tlsAuth: true + tlsAuthWithCACert: true + # json object of data that will be encrypted. + secureJsonData: + tlsCACert: "..." + tlsClientCert: "..." + tlsClientKey: "..." + version: 1 + # allow users to edit datasources from the UI. + editable: false +``` + +## Sidecar for notifiers + +If the parameter `sidecar.notifiers.enabled` is set, an init container is deployed in the grafana +pod. This container lists all secrets (or configmaps, though not recommended) in the cluster and +filters out the ones with a label as defined in `sidecar.notifiers.label`. The files defined in +those secrets are written to a folder and accessed by grafana on startup. Using these yaml files, +the notification channels in grafana can be imported. The secrets must be created before +`helm install` so that the notifiers init container can list the secrets. + +Secrets are recommended over configmaps for this usecase because alert notification channels usually contain +private data like SMTP usernames and passwords. Secrets are the more appropriate cluster resource to manage those. + +Example datasource config adapted from [Grafana](https://grafana.com/docs/grafana/latest/administration/provisioning/#alert-notification-channels): + +```yaml +notifiers: + - name: notification-channel-1 + type: slack + uid: notifier1 + # either + org_id: 2 + # or + org_name: Main Org. + is_default: true + send_reminder: true + frequency: 1h + disable_resolve_message: false + # See `Supported Settings` section for settings supporter for each + # alert notification type. + settings: + recipient: 'XXX' + token: 'xoxb' + uploadImage: true + url: https://slack.com + +delete_notifiers: + - name: notification-channel-1 + uid: notifier1 + org_id: 2 + - name: notification-channel-2 + # default org_id: 1 +``` + +## Sidecar for alerting resources + +If the parameter `sidecar.alerts.enabled` is set, a sidecar container is deployed in the grafana +pod. This container watches all configmaps (or secrets) in the cluster (namespace defined by `sidecar.alerts.searchNamespace`) and filters out the ones with +a label as defined in `sidecar.alerts.label` (default is `grafana_alert`). The files defined in those configmaps are written +to a folder and accessed by grafana. Changes to the configmaps are monitored and the imported alerting resources are updated, however, deletions are a little more complicated (see below). + +This sidecar can be used to provision alert rules, contact points, notification policies, notification templates and mute timings as shown in [Grafana Documentation](https://grafana.com/docs/grafana/next/alerting/set-up/provision-alerting-resources/file-provisioning/). + +To fetch the alert config which will be provisioned, use the alert provisioning API ([Grafana Documentation](https://grafana.com/docs/grafana/next/developers/http_api/alerting_provisioning/)). +You can use either JSON or YAML format. + +Example config for an alert rule: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: sample-grafana-alert + labels: + grafana_alert: "1" +data: + k8s-alert.yml: |- + apiVersion: 1 + groups: + - orgId: 1 + name: k8s-alert + [...] +``` + +To delete provisioned alert rules is a two step process, you need to delete the configmap which defined the alert rule +and then create a configuration which deletes the alert rule. + +Example deletion configuration: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: delete-sample-grafana-alert + namespace: monitoring + labels: + grafana_alert: "1" +data: + delete-k8s-alert.yml: |- + apiVersion: 1 + deleteRules: + - orgId: 1 + uid: 16624780-6564-45dc-825c-8bded4ad92d3 +``` + +## Statically provision alerting resources + +If you don't need to change alerting resources (alert rules, contact points, notification policies and notification templates) regularly you could use the `alerting` config option instead of the sidecar option above. +This will grab the alerting config and apply it statically at build time for the helm file. + +There are two methods to statically provision alerting configuration in Grafana. Below are some examples and explanations as to how to use each method: + +```yaml +alerting: + team1-alert-rules.yaml: + file: alerting/team1/rules.yaml + team2-alert-rules.yaml: + file: alerting/team2/rules.yaml + team3-alert-rules.yaml: + file: alerting/team3/rules.yaml + notification-policies.yaml: + file: alerting/shared/notification-policies.yaml + notification-templates.yaml: + file: alerting/shared/notification-templates.yaml + contactpoints.yaml: + apiVersion: 1 + contactPoints: + - orgId: 1 + name: Slack channel + receivers: + - uid: default-receiver + type: slack + settings: + # Webhook URL to be filled in + url: "" + # We need to escape double curly braces for the tpl function. + text: '{{ `{{ template "default.message" . }}` }}' + title: '{{ `{{ template "default.title" . }}` }}' +``` + +The two possibilities for static alerting resource provisioning are: + +* Inlining the file contents as shown for contact points in the above example. +* Importing a file using a relative path starting from the chart root directory as shown for the alert rules in the above example. + +### Important notes on file provisioning + +* The format of the files is defined in the [Grafana documentation](https://grafana.com/docs/grafana/next/alerting/set-up/provision-alerting-resources/file-provisioning/) on file provisioning. +* The chart supports importing YAML and JSON files. +* The filename must be unique, otherwise one volume mount will overwrite the other. +* In case of inlining, double curly braces that arise from the Grafana configuration format and are not intended as templates for the chart must be escaped. +* The number of total files under `alerting:` is not limited. Each file will end up as a volume mount in the corresponding provisioning folder of the deployed Grafana instance. +* The file size for each import is limited by what the function `.Files.Get` can handle, which suffices for most cases. + +## How to serve Grafana with a path prefix (/grafana) + +In order to serve Grafana with a prefix (e.g., ), add the following to your values.yaml. + +```yaml +ingress: + enabled: true + annotations: + kubernetes.io/ingress.class: "nginx" + nginx.ingress.kubernetes.io/rewrite-target: /$1 + nginx.ingress.kubernetes.io/use-regex: "true" + + path: /grafana/?(.*) + hosts: + - k8s.example.dev + +grafana.ini: + server: + root_url: http://localhost:3000/grafana # this host can be localhost +``` + +## How to securely reference secrets in grafana.ini + +This example uses Grafana [file providers](https://grafana.com/docs/grafana/latest/administration/configuration/#file-provider) for secret values and the `extraSecretMounts` configuration flag (Additional grafana server secret mounts) to mount the secrets. + +In grafana.ini: + +```yaml +grafana.ini: + [auth.generic_oauth] + enabled = true + client_id = $__file{/etc/secrets/auth_generic_oauth/client_id} + client_secret = $__file{/etc/secrets/auth_generic_oauth/client_secret} +``` + +Existing secret, or created along with helm: + +```yaml +--- +apiVersion: v1 +kind: Secret +metadata: + name: auth-generic-oauth-secret +type: Opaque +stringData: + client_id: + client_secret: +``` + +Include in the `extraSecretMounts` configuration flag: + +```yaml +extraSecretMounts: + - name: auth-generic-oauth-secret-mount + secretName: auth-generic-oauth-secret + defaultMode: 0440 + mountPath: /etc/secrets/auth_generic_oauth + readOnly: true +``` + +### extraSecretMounts using a Container Storage Interface (CSI) provider + +This example uses a CSI driver e.g. retrieving secrets using [Azure Key Vault Provider](https://github.com/Azure/secrets-store-csi-driver-provider-azure) + +```yaml +extraSecretMounts: + - name: secrets-store-inline + mountPath: /run/secrets + readOnly: true + csi: + driver: secrets-store.csi.k8s.io + readOnly: true + volumeAttributes: + secretProviderClass: "my-provider" + nodePublishSecretRef: + name: akv-creds +``` + +## Image Renderer Plug-In + +This chart supports enabling [remote image rendering](https://github.com/grafana/grafana-image-renderer/blob/master/README.md#run-in-docker) + +```yaml +imageRenderer: + enabled: true +``` + +### Image Renderer NetworkPolicy + +By default the image-renderer pods will have a network policy which only allows ingress traffic from the created grafana instance + +### High Availability for unified alerting + +If you want to run Grafana in a high availability cluster you need to enable +the headless service by setting `headlessService: true` in your `values.yaml` +file. + +As next step you have to setup the `grafana.ini` in your `values.yaml` in a way +that it will make use of the headless service to obtain all the IPs of the +cluster. You should replace ``{{ Name }}`` with the name of your helm deployment. + +```yaml +grafana.ini: + ... + unified_alerting: + enabled: true + ha_peers: {{ Name }}-headless:9094 + ha_listen_address: ${POD_IP}:9094 + ha_advertise_address: ${POD_IP}:9094 + + alerting: + enabled: false +``` diff --git a/charts/grafana/templates/service.yaml b/charts/grafana/templates/service.yaml index 3d3b399024..022328c114 100644 --- a/charts/grafana/templates/service.yaml +++ b/charts/grafana/templates/service.yaml @@ -48,9 +48,6 @@ spec: {{- with .Values.service.externalTrafficPolicy }} externalTrafficPolicy: {{ . }} {{- end }} - {{- if .Values.service.sessionAffinity }} - sessionAffinity: {{ .Values.service.sessionAffinity }} - {{- end }} ports: - name: {{ .Values.service.portName }} port: {{ .Values.service.port }} diff --git a/charts/grafana/values.yaml b/charts/grafana/values.yaml index ebe5c698e1..5095c37441 100644 --- a/charts/grafana/values.yaml +++ b/charts/grafana/values.yaml @@ -245,7 +245,6 @@ service: portName: service # Adds the appProtocol field to the service. This allows to work with istio protocol selection. Ex: "http" or "tcp" appProtocol: "" - sessionAffinity: ClientIP serviceMonitor: ## If true, a ServiceMonitor CR is created for a prometheus operator From b74869376d6009345020f2cab800456d94ab988b Mon Sep 17 00:00:00 2001 From: AvivGuiser Date: Tue, 14 Jan 2025 20:03:34 +0200 Subject: [PATCH 3/6] commit without docs Signed-off-by: AvivGuiser --- charts/grafana/Chart.yaml | 2 +- charts/grafana/templates/service.yaml | 5 ++++- charts/grafana/values.yaml | 1 + 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/charts/grafana/Chart.yaml b/charts/grafana/Chart.yaml index 9deccc3ff6..c570d934f1 100644 --- a/charts/grafana/Chart.yaml +++ b/charts/grafana/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v2 name: grafana -version: 8.8.2 +version: 8.8.3 appVersion: 11.4.0 kubeVersion: "^1.8.0-0" description: The leading tool for querying and visualizing time series and metrics. diff --git a/charts/grafana/templates/service.yaml b/charts/grafana/templates/service.yaml index 022328c114..bf21029024 100644 --- a/charts/grafana/templates/service.yaml +++ b/charts/grafana/templates/service.yaml @@ -48,7 +48,10 @@ spec: {{- with .Values.service.externalTrafficPolicy }} externalTrafficPolicy: {{ . }} {{- end }} - ports: + {{- if .Values.service.seessionAffinity }} + sessionAffinity: {{ .Values.service.sessionAffinity }} + {{- end }} +s ports: - name: {{ .Values.service.portName }} port: {{ .Values.service.port }} protocol: TCP diff --git a/charts/grafana/values.yaml b/charts/grafana/values.yaml index 5095c37441..c28f630fdb 100644 --- a/charts/grafana/values.yaml +++ b/charts/grafana/values.yaml @@ -245,6 +245,7 @@ service: portName: service # Adds the appProtocol field to the service. This allows to work with istio protocol selection. Ex: "http" or "tcp" appProtocol: "" + sessionAffinity: "" serviceMonitor: ## If true, a ServiceMonitor CR is created for a prometheus operator From 0337365313d5eb66164aa3d1e51a6eca7ad2cf8c Mon Sep 17 00:00:00 2001 From: AvivGuiser Date: Tue, 14 Jan 2025 20:06:56 +0200 Subject: [PATCH 4/6] fix typo Signed-off-by: AvivGuiser --- charts/grafana/templates/service.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/grafana/templates/service.yaml b/charts/grafana/templates/service.yaml index bf21029024..67b961a34a 100644 --- a/charts/grafana/templates/service.yaml +++ b/charts/grafana/templates/service.yaml @@ -51,7 +51,7 @@ spec: {{- if .Values.service.seessionAffinity }} sessionAffinity: {{ .Values.service.sessionAffinity }} {{- end }} -s ports: + ports: - name: {{ .Values.service.portName }} port: {{ .Values.service.port }} protocol: TCP From 94b3f84c1e64d558e29250e7fb0e74ed5fe5ac7a Mon Sep 17 00:00:00 2001 From: AvivGuiser Date: Tue, 14 Jan 2025 20:12:28 +0200 Subject: [PATCH 5/6] update docs Signed-off-by: AvivGuiser --- charts/grafana/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/charts/grafana/README.md b/charts/grafana/README.md index a78b123605..34a2eeade7 100644 --- a/charts/grafana/README.md +++ b/charts/grafana/README.md @@ -75,6 +75,7 @@ need to instead set `global.imageRegistry`. | `service.enabled` | Enable grafana service | `true` | | `service.ipFamilies` | Kubernetes service IP families | `[]` | | `service.ipFamilyPolicy` | Kubernetes service IP family policy | `""` | +| `service.sessionAffinity` | Kubernetes service session affinity config | `""` | | `service.type` | Kubernetes service type | `ClusterIP` | | `service.port` | Kubernetes port where service is exposed | `80` | | `service.portName` | Name of the port on the service | `service` | From ea6b13a49204bae00a3f611a5946b014e9bc4e10 Mon Sep 17 00:00:00 2001 From: AvivGuiser Date: Tue, 14 Jan 2025 21:35:03 +0200 Subject: [PATCH 6/6] Update charts/grafana/templates/service.yaml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jan-Otto Kröpke Signed-off-by: AvivGuiser --- charts/grafana/templates/service.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/charts/grafana/templates/service.yaml b/charts/grafana/templates/service.yaml index 67b961a34a..8684d9c549 100644 --- a/charts/grafana/templates/service.yaml +++ b/charts/grafana/templates/service.yaml @@ -48,8 +48,8 @@ spec: {{- with .Values.service.externalTrafficPolicy }} externalTrafficPolicy: {{ . }} {{- end }} - {{- if .Values.service.seessionAffinity }} - sessionAffinity: {{ .Values.service.sessionAffinity }} + {{- with .Values.service.seessionAffinity }} + sessionAffinity: {{ . }} {{- end }} ports: - name: {{ .Values.service.portName }}