Aller au contenu
English
Conteneurs & Orchestration medium

Concevoir l'API de son chart Helm : values, défauts et dépréciation

65 min de lecture

logo helm

Le fichier values.yaml d'un chart publié est une API : dès qu'une équipe l'utilise, chaque clé devient un engagement que vous ne pouvez plus rompre sans prévenir. Ce guide traite les décisions que les outils ne prennent pas à votre place : ce qui mérite d'être configurable, quelles valeurs par défaut choisir, et comment renommer ou supprimer une clé sans casser les déploiements qui s'en servent déjà.

  • Décider ce qui devient une value et ce qui reste figé dans le template
  • Choisir des défauts qui rendent le chart installable sans aucune surcharge
  • Verrouiller le contrat avec values.schema.json et additionalProperties
  • Renommer une value en gardant l'ancienne fonctionnelle
  • Déprécier puis supprimer une clé avec un message qui évite un ticket
  • Savoir écrire un chart (voir Anatomie d'un chart)
  • Maîtriser la surcharge par -f et --set (voir Values)
  • Un chart qui a au moins un utilisateur autre que vous, sans quoi la question ne se pose pas encore

Parce qu'une value publiée ne vous appartient plus. Tant que vous êtes seul à installer votre chart, renommer logLevel en journal.niveau coûte trente secondes. Le jour où trois équipes ont leur values-prod.yaml versionné dans leur dépôt, le même renommage casse trois chaînes de déploiement, et vous l'apprendrez par un message désagréable un vendredi soir.

La comparaison avec une bibliothèque logicielle est exacte : personne ne renomme une fonction publique sans période de transition. Un chart obéit aux mêmes règles, avec une difficulté supplémentaire : rien ne vous avertit. Aucun compilateur ne signale qu'une clé a disparu ; le déploiement part, la value est ignorée, et le comportement change en silence.

Ce que vous changezCe que l'utilisateur constate
Renommer une cléSa surcharge est ignorée sans erreur, le défaut reprend la main
Changer un défautSon déploiement change alors qu'il n'a rien touché
Supprimer une cléIdentique à un renommage : silence complet
Changer un typeErreur de rendu, la seule qui se voie immédiatement

La bonne question n'est pas « est-ce que quelqu'un pourrait vouloir le changer » mais « est-ce que je m'engage à le maintenir configurable ». Répondre oui à tout produit le chart usine à gaz : deux cents clés, dont personne ne connaît l'effet, impossibles à retirer.

Trois critères suffisent à trancher, et ils se posent dans cet ordre.

Le paramètre varie-t-il d'un environnement à l'autre ? Le nombre de replicas, les limites de ressources, le nom de domaine, la classe de stockage : oui, évidemment. Le nom du port interne sur lequel écoute votre conteneur : non, il est le même partout.

L'utilisateur peut-il en subir les conséquences ? Exposer securityContext complet permet à quelqu'un de lancer vos pods en privileged: true. Ce n'est pas votre décision, mais vous lui en donnez le moyen. Certains charts le font volontairement, d'autres n'exposent que runAsUser. Les deux choix se défendent, à condition d'être conscients.

Sauriez-vous l'expliquer en une ligne ? Si la description d'une clé demande un paragraphe et la connaissance des internes du chart, elle n'appartient probablement pas à l'API publique. Un post-renderer ou un fork couvrira ce cas rare, sans grever le contrat pour tout le monde.

Un chart doit s'installer et fonctionner avec helm install mon-app ./chart, sans aucune surcharge. C'est le test le plus simple de la qualité d'une API de values, et beaucoup de charts publics y échouent.

Deux règles guident le choix, et elles s'opposent parfois.

Le défaut le plus sûr, pas le plus pratique. replicaCount: 1 plutôt que 3, mais securityContext restrictif plutôt que vide. Un utilisateur qui veut moins de sécurité le demandera explicitement ; l'inverse ne se produit jamais.

Le défaut le plus courant, pas le plus complet. service.type: ClusterIP couvre l'immense majorité des cas ; proposer LoadBalancer par défaut coûte une adresse IP publique à qui teste votre chart sur un cluster managé.

Le squelette de helm create illustre parfaitement ce qu'il ne faut pas faire sur ce point précis, et c'est utile à savoir : resources: {}, securityContext: {} et podSecurityContext: {} y sont vides. Un chart généré déploie donc des pods sans aucune limite de ressources ni contexte de sécurité. C'est un point de départ neutre pour apprendre, pas un défaut à publier.

values.schema.json : transformer une convention en contrat

Section intitulée « values.schema.json : transformer une convention en contrat »

Le schéma est le seul mécanisme qui rende votre API opposable. Sans lui, une value mal orthographiée est acceptée en silence, et l'utilisateur cherche pendant une heure pourquoi sa configuration ne s'applique pas.

Une seule ligne change tout : additionalProperties: false.

values.schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"additionalProperties": false,
"properties": {
"journal": {
"type": "object",
"properties": {
"niveau": {
"type": "string",
"enum": ["debug", "info", "warn", "error"]
}
}
}
}
}

Une faute de frappe cesse alors d'être silencieuse :

Fenêtre de terminal
helm template api ./chart --set clefantaisiste=1
Error: values don't meet the specifications of the schema(s) in the following chart(s):
api:
- at '': additional properties 'clefantaisiste' not allowed

Et l'enum transforme un commentaire en garantie :

Fenêtre de terminal
helm template api ./chart --set journal.niveau=bavard
Error: values don't meet the specifications of the schema(s) in the following chart(s):
api:
- at '/journal/niveau': value must be one of 'debug', 'info', 'warn', 'error'

Trois situations, trois mécanismes. Le point commun : l'utilisateur doit apprendre le changement de votre chart, pas de son incident de production.

Renommer : accepter les deux clés pendant une transition

Section intitulée « Renommer : accepter les deux clés pendant une transition »

La fonction coalesce rend la première valeur non vide de la liste. Elle permet à l'ancienne clé de continuer à fonctionner pendant que la nouvelle devient la référence :

data:
niveau: "{{ coalesce .Values.logLevel .Values.journal.niveau }}"

L'utilisateur qui n'a rien changé obtient le nouveau défaut :

niveau: "info"

Celui qui surcharge encore l'ancienne clé garde son comportement :

niveau: "debug"

L'ordre des arguments compte : l'ancienne clé passe en premier, sinon le défaut de la nouvelle l'emporterait toujours et la surcharge de l'utilisateur serait ignorée, ce qui est exactement le défaut que l'on cherche à éviter.

Prévenir : signaler l'usage d'une clé dépréciée

Section intitulée « Prévenir : signaler l'usage d'une clé dépréciée »

Accepter l'ancienne clé ne suffit pas, encore faut-il que l'utilisateur sache qu'il doit migrer. Un bloc conditionnel rend l'avertissement visible dans le manifeste :

data:
{{- if .Values.logLevel }}
AVERTISSEMENT: "logLevel est déprécié, utilisez journal.niveau"
{{- end }}
niveau: "{{ coalesce .Values.logLevel .Values.journal.niveau }}"

L'avertissement apparaît dans helm template, dans helm get manifest et dans la ressource elle-même. Il ne bloque rien, et c'est voulu : une dépréciation qui casse n'est pas une dépréciation, c'est une suppression.

Supprimer : refuser franchement, avec un message qui explique

Section intitulée « Supprimer : refuser franchement, avec un message qui explique »

Une fois la période de transition écoulée, fail arrête le rendu et affiche le message de votre choix :

{{- if .Values.ancienneCle }}
{{- fail "La value « ancienneCle » a été SUPPRIMÉE en 2.0. Utilisez « journal.niveau ». Voir le CHANGELOG du chart." }}
{{- end }}
Error: execution error at (chart/templates/config.yaml:2:4): La value « ancienneCle » a été
SUPPRIMÉE en 2.0. Utilisez « journal.niveau ». Voir le CHANGELOG du chart.

C'est infiniment préférable au silence. Sans ce garde-fou, la surcharge est simplement ignorée et l'utilisateur déploie une configuration qu'il croit appliquée. Le message doit contenir trois choses : ce qui a disparu, par quoi le remplacer, et où lire le détail.

Version du chartÉtat de l'ancienne clé
1.4.0Nouvelle clé introduite, ancienne acceptée via coalesce, avertissement affiché
1.5.0, 1.6.0Inchangé, le temps que les utilisateurs migrent
2.0.0Ancienne clé retirée, fail avec message explicite

La suppression tombe sur une version majeure, jamais ailleurs. C'est la seule promesse que le versionnement sémantique fait à vos utilisateurs, et la tenir vous dispense de tout le reste.

Trois signaux, tous observables sans jugement de valeur.

Le values.yaml dépasse la page. Au-delà, personne ne le lit en entier, et les clés du bas ne sont plus jamais utilisées.

Deux clés peuvent se contredire. Un ingress.enabled: false avec un ingress.tls.enabled: true doit-il créer un certificat ? Si vous hésitez, votre utilisateur aussi.

Une clé n'existe que pour un seul utilisateur. C'est le cas classique : une équipe demande une option, elle est ajoutée, et elle devient impossible à retirer. Un subchart ou un post-renderer aurait répondu sans grever l'API de tout le monde.

Objectif : renommer une value sur un chart déjà installé, et vérifier qu'un utilisateur resté sur l'ancienne clé n'est pas affecté.

  1. Créer le chart et son API initiale

    Fenêtre de terminal
    helm create api-lab
    rm -rf api-lab/templates/*.yaml api-lab/templates/NOTES.txt api-lab/templates/tests

    Supprimez bien NOTES.txt et tests/, pas seulement les .yaml. Le fichier de notes du squelette référence des values que le values.yaml minimal ci-dessous n'expose plus, et le rendu échouerait sur un nil pointer sans rapport avec l'exercice.

    Déclarez la première version de l'API dans values.yaml :

    api-lab/values.yaml
    logLevel: info

    Et le template qui la consomme :

    api-lab/templates/config.yaml
    apiVersion: v1
    kind: ConfigMap
    metadata:
    name: {{ .Release.Name }}-config
    data:
    niveau: "{{ .Values.logLevel }}"
  2. Se mettre dans la peau d'un utilisateur

    Fenêtre de terminal
    helm template api-lab ./api-lab --set logLevel=debug | grep niveau

    La sortie doit afficher niveau: "debug". C'est la configuration que cet utilisateur a versionnée dans son dépôt.

  3. Renommer la value, en gardant l'ancienne

    api-lab/values.yaml
    journal:
    niveau: info
    logLevel: ""
    api-lab/templates/config.yaml
    data:
    {{- if .Values.logLevel }}
    AVERTISSEMENT: "logLevel est déprécié, utilisez journal.niveau"
    {{- end }}
    niveau: "{{ coalesce .Values.logLevel .Values.journal.niveau }}"
  4. Vérifier les deux populations d'utilisateurs

    Fenêtre de terminal
    # Celui qui n'a rien changé
    helm template api-lab ./api-lab | grep niveau
    # Celui qui utilise encore l'ancienne clé
    helm template api-lab ./api-lab --set logLevel=debug | grep -E "niveau|AVERTISSEMENT"

    Le premier obtient info, le second conserve debug et reçoit l'avertissement. Personne n'est cassé.

  5. Simuler la version majeure

    Remplacez le bloc conditionnel par un refus franc :

    {{- if .Values.logLevel }}
    {{- fail "La value « logLevel » a été SUPPRIMÉE en 2.0. Utilisez « journal.niveau »." }}
    {{- end }}
    Fenêtre de terminal
    helm template api-lab ./api-lab --set logLevel=debug

    Le rendu s'arrête sur votre message. L'utilisateur sait quoi faire sans ouvrir vos templates.

  6. Verrouiller le contrat

    Ajoutez values.schema.json avec additionalProperties: false, puis tentez une faute de frappe :

    Fenêtre de terminal
    helm template api-lab ./api-lab --set journl.niveau=info

    Le schéma refuse la clé inconnue au lieu de l'ignorer.

  • Le values.yaml d'un chart publié est une API : chaque clé est un engagement
  • Une value renommée ou supprimée est ignorée en silence, aucun outil ne prévient l'utilisateur
  • Ne rendez configurable que ce qui varie par environnement et que vous saurez maintenir
  • Le nom des ressources et les labels app.kubernetes.io/* ne sont jamais des values
  • Un chart doit s'installer sans aucune surcharge : c'est le test de ses défauts
  • additionalProperties: false transforme une faute de frappe silencieuse en erreur claire
  • Renommer se fait avec coalesce, l'ancienne clé en premier, plus un avertissement visible
  • Supprimer se fait avec fail et un message qui dit par quoi remplacer, sur une version majeure

Six questions sur la conception d'une API de chart : ce que deprecated ne fait pas, la ligne de schéma qui attrape une faute de frappe, et l'ordre des arguments de coalesce.

Contrôle de connaissances

Validez vos connaissances avec ce quiz interactif

5 questions
5 min.
80% requis

Informations

  • Le chronomètre démarre au clic sur Démarrer
  • Questions à choix multiples, vrai/faux et réponses courtes
  • Vous pouvez naviguer entre les questions
  • Les résultats détaillés sont affichés à la fin

Lance le quiz et démarre le chronomètre

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracking. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn