CltOps
Tutorial

Comment étendre et personnaliser un Helm chart

#grafana#observability#infra#cloud

Quand on utilise Helm, on a rapidement besoin d’aller plus loin que les manifests par défaut fournis par un chart. Il existe plusieurs façons de les étendre ou de les customiser, que ce soit depuis un Helm repository classique ou un OCI registry (stocké comme des artefacts).

Helm Repository vs OCI Registry

helm repo add grafana https://grafana.github.io/helm-charts
helm template grafana/grafana
helm template oci://ghcr.io/grafana/helm-charts/grafana

Les méthodes de customisation sont les mêmes dans les deux cas.

1. Override des values

Chaque chart expose un fichier values.yaml avec les valeurs par défaut. C’est toujours par là qu’il faut commencer.

helm show values grafana/grafana > example.yaml

Aussi visible ici.

Créez un fichier my-values.yaml :

namespaceOverride: monitoring

ingress:
  enabled: true
  hosts:
    - grafana.example.local

persistence:
  enabled: true
  size: 5Gi

extraEnv:
  - name: GF_SECURITY_ALLOW_EMBEDDING
    value: "true"

Chaque variable ajoutée dans ce fichier override la config par défaut fournie avec le chart Helm.

helm template grafana grafana/grafana -f my-values.yaml

Vous devriez maintenant voir les changements dans la sortie de la commande précédente.

2. Ajouter des manifests supplémentaires

Si vous avez besoin de ressources qui ne sont pas couvertes par le chart (par exemple : NetworkPolicy, ServiceMonitor) :

a. Inline avec extraObjects (si supporté)

Le chart Grafana supporte extraObjects :

extraObjects:
  - apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: grafana-allow-same-namespace
    spec:
      podSelector:
        matchLabels:
          app.kubernetes.io/name: grafana
      ingress:
        - from:
            - podSelector:
                matchLabels:
                  access-to-grafana: "true"
      policyTypes:
        - Ingress

b. Wrapper chart (pattern Subchart)

Plutôt que de forker le chart Grafana, vous créez votre propre chart qui déclare Grafana comme dépendance. Ça permet de :

Step 1. Créer un nouveau chart

helm create my-grafana
cd my-grafana

Quand vous créez un nouveau chart, vous obtenez toujours la structure suivante:

my-grafana/
├── Chart.yaml
├── templates
└── values.yaml

Si vous lancez helm template . (avec . le dossier courant), vous verrez les manifests d’exemple dans templates/.

Dans notre cas, on peut vider le dossier templates pour repartir clean.

Ensuite, mettez à jour Chart.yaml pour ajouter la dépendance :

dependencies:
  - name: grafana
    version: 10.0.0
    repository: https://grafana.github.io/helm-charts

Puis lancez :

helm dependency update

Un dossier charts/ et un fichier Chart.lock apparaissent :

my-grafana/
├── Chart.lock
├── charts
├── Chart.yaml
├── templates
└── values.yaml

Si vous relancez helm template ., vous verrez maintenant tout le chart Grafana.

Ajoutez maintenant un fichier templates/network-policy.yaml :

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: grafana-allow-same-namespace
spec:
  podSelector:
    matchLabels:
      app.kubernetes.io/name: grafana
  ingress:
    - from:
        - podSelector:
            matchLabels:
              access-to-grafana: "true"
  policyTypes:
    - Ingress

L’output de helm template inclura maintenant ce manifest supplémentaire.

Vous pouvez aussi override complètement values.yaml avec les valeurs de l’étape 1 pour impacter les manifests Grafana :

namespaceOverride: monitoring

ingress:
  enabled: true
  hosts:
    - grafana.example.local

persistence:
  enabled: true
  size: 5Gi

extraEnv:
  - name: GF_SECURITY_ALLOW_EMBEDDING
    value: "true"

3. Extra templating

Les Helm charts utilisent le moteur de templating Go pour injecter les variables de values.yaml et les métadonnées du chart dans les manifests Kubernetes. C’est ce qui les rend réutilisables et adaptables selon l’environnement.

Exemple avec la NetworkPolicy custom : au lieu de hardcoder grafana, on peut mettre à jour templates/network-policy.yaml avec des variables Helm :

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: {{ .Release.Name }}-allow-same-namespace
spec:
  podSelector:
    matchLabels:
      app.kubernetes.io/name: {{ .Chart.Name }}
  ingress:
    - from:
        - podSelector:
            matchLabels:
              access-to-{{ .Chart.Name }}: "true"
  policyTypes:
    - Ingress

Toute valeur définie dans values.yaml est accessible via {{ .Values.exemple }}.

C’est bien plus propre que de hardcoder vos valeurs. En utilisant le templating, vos manifests additionnels deviennent dynamiques et environment-aware, comme les templates du chart original.

← Retour aux guides