Aller au contenu

Lab : le chart Helm de Signalements

200 Pratiquer ⏱ 4 h helmkubernetes

Prérequis

Testé avec helm 3.16.3 kubernetes 1.36 , vérifié le 5 octobre 2026

Ce lab rassemble le cours Helm. Vous écrivez le chart de Signalements à partir des manifestes du lab Kubernetes, puis un script vérifie ses propriétés sans cluster, uniquement avec helm lint, helm template et helm package. Un dernier contrôle, facultatif, vérifie son installation sur le cluster kind du cours Kubernetes. Il valide le niveau 200 de la compétence « Packager pour Kubernetes ».

Comptez une demi-journée.

Les exigences

ExigenceLeçon
Chart.yaml en apiVersion: v2, avec une version sémantique et une appVersion distincte4, 9
helm lint --strict réussit4, 8
Un values.schema.json refuse un nombre de répliques non entier et une propriété inconnue à la racine6
Le rendu échoue avec un message clair si aucun Secret de base de données n'est désigné (fonction required)5, 6
Les noms et étiquettes viennent de fonctions d'aide de _helpers.tpl ; chaque objet porte app.kubernetes.io/name et app.kubernetes.io/instance4, 6
L'image est désignée par dépôt et étiquette dans les valeurs, l'étiquette par défaut étant appVersion5, 6
La migration est un Job en hook pre-install,pre-upgrade, avec une politique de suppression8
Un test de chart (helm.sh/hook: test) appelle /sante8
values-preprod.yaml et values-prod.yaml produisent chacun un rendu valide, avec 1 et 3 répliques2, 6
helm package produit une archive nommée d'après la version du chart9

Vérifier

Placez le script à la racine du chart sous verifier-lab.sh, puis lancez bash verifier-lab.sh. Il ne contacte aucun cluster : il isole même Helm de votre configuration en lui donnant un kubeconfig vide.

#!/usr/bin/env bash
# Vérifie les propriétés attendues du lab « le chart Helm de Signalements », sans cluster.
# Usage : bash verifier-lab.sh   (à la racine du chart ; exige helm et python3 avec PyYAML)
# Chaque contrôle affiche OK ou ÉCHEC ; le code de sortie est le nombre d'échecs.
set -uo pipefail
travail=$(mktemp -d)
trap 'rm -rf "$travail"' EXIT
printf 'apiVersion: v1\nkind: Config\nclusters: []\ncontexts: []\nusers: []\n' > "$travail/kubeconfig"
export KUBECONFIG="$travail/kubeconfig"
echecs=0

controle() {   # controle "libellé" commande...
  local libelle=$1; shift
  if "$@" > /dev/null 2>&1; then
    echo "OK     $libelle"
  else
    echo "ÉCHEC  $libelle"
    echecs=$((echecs + 1))
  fi
}

yamlq() {   # yamlq fichier expression-python : évalue une expression sur les documents YAML (liste « docs »)
  python3 -c 'import sys, yaml; docs=[d for d in yaml.safe_load_all(open(sys.argv[1])) if d]; sys.exit(0 if eval(sys.argv[2]) else 1)' "$1" "$2"
}

controle "Chart.yaml : apiVersion v2, version sémantique, appVersion distincte" \
  python3 -c 'import yaml,re,sys; c=yaml.safe_load(open("Chart.yaml")); sys.exit(0 if c.get("apiVersion")=="v2" and re.fullmatch(r"\d+\.\d+\.\d+(-[0-9A-Za-z.-]+)?", str(c.get("version",""))) and c.get("appVersion") and str(c["appVersion"])!=str(c["version"]) else 1)'
controle "helm lint --strict réussit (préproduction)" helm lint --strict . -f values-preprod.yaml
controle "le schéma de valeurs existe" test -f values.schema.json
controle "le schéma refuse un nombre de répliques non entier" \
  bash -c '! helm template t . -f values-preprod.yaml --set-string replicaCount=deux'
controle "le schéma refuse une propriété inconnue à la racine" \
  bash -c '! helm template t . -f values-preprod.yaml --set proprieteInconnue=1'
controle "le rendu échoue si aucun Secret de base n'est désigné" \
  bash -c '! helm template t . > /dev/null 2>&1'
controle "_helpers.tpl définit des fonctions d'aide" \
  bash -c 'grep -q "define" templates/_helpers.tpl'

for env in preprod prod; do
  helm template signalements . -f "values-$env.yaml" > "$travail/$env.yaml" 2>/dev/null
  controle "le rendu $env réussit" test -s "$travail/$env.yaml"
  controle "$env : chaque objet porte les étiquettes name et instance" \
    yamlq "$travail/$env.yaml" 'all("app.kubernetes.io/name" in (d["metadata"].get("labels") or {}) and "app.kubernetes.io/instance" in (d["metadata"].get("labels") or {}) for d in docs)'
done
controle "préproduction : 1 réplique ; production : 3" \
  bash -c 'python3 - "$1" "$2" <<'"'"'EOF'"'"'
import sys, yaml
def rep(f):
    return [d["spec"]["replicas"] for d in yaml.safe_load_all(open(f)) if d and d.get("kind") == "Deployment"]
sys.exit(0 if rep(sys.argv[1]) == [1] and rep(sys.argv[2]) == [3] else 1)
EOF' _ "$travail/preprod.yaml" "$travail/prod.yaml"

controle "l'étiquette d'image par défaut est appVersion" \
  bash -c 'v=$(python3 -c "import yaml; print(yaml.safe_load(open(\"Chart.yaml\"))[\"appVersion\"])"); grep -q "image: .*:$v\"\?$" "$1"' _ "$travail/preprod.yaml"
controle "la migration est un Job en hook pre-install,pre-upgrade avec politique de suppression" \
  yamlq "$travail/preprod.yaml" 'any(d.get("kind")=="Job" and set((d["metadata"].get("annotations") or {}).get("helm.sh/hook","").replace(" ","").split(","))>={"pre-install","pre-upgrade"} and "helm.sh/hook-delete-policy" in (d["metadata"].get("annotations") or {}) for d in docs)'
controle "un test de chart appelle /sante" \
  bash -c 'grep -l "helm.sh/hook\": \?test\|helm.sh/hook: \?\"\?test" templates/tests/*.yaml 2>/dev/null | xargs grep -q "/sante"'

controle "helm package produit l'archive de la version du chart" \
  bash -c 'v=$(python3 -c "import yaml; c=yaml.safe_load(open(\"Chart.yaml\")); print(c[\"name\"]+\"-\"+str(c[\"version\"]))"); helm package . -d "$1" && test -f "$1/$v.tgz"' _ "$travail"

echo
echo "$echecs échec(s)"
exit "$echecs"

Quelques contrôles demandent une explication :

  • Le kubeconfig vide empêche Helm de contacter le cluster de votre configuration courante : helm template et helm lint n'en ont pas besoin, et un chart qui utiliserait lookup ne doit pas dépendre d'un cluster pour se rendre.
  • Le schéma est le seul endroit où Helm valide les valeurs avant le rendu : sans lui, une faute de frappe dans un nom de valeur est simplement ignorée.
  • Le contrôle du Secret de base rend le chart sans fichier de valeurs : required doit faire échouer le rendu, avec un message qui dit quelle valeur fournir.

Installer, en option

Sur le cluster kind formation, installez le chart dans un namespace neuf (helm install signalements . -n signalements-helm --create-namespace -f values-preprod.yaml --wait), lancez helm test signalements -n signalements-helm, puis faites une mise à jour vers une nouvelle appVersion et un helm rollback. Le test doit réussir, l'historique doit montrer trois révisions, et le Job de migration ne doit plus traîner dans le namespace après chaque opération.

Démonter

helm uninstall signalements -n signalements-helm, puis kubectl delete namespace signalements-helm.

Plan du cours