Lab : le chart Helm de Signalements
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
| Exigence | Leçon |
|---|---|
Chart.yaml en apiVersion: v2, avec une version sémantique et une appVersion distincte | 4, 9 |
helm lint --strict réussit | 4, 8 |
Un values.schema.json refuse un nombre de répliques non entier et une propriété inconnue à la racine | 6 |
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/instance | 4, 6 |
L'image est désignée par dépôt et étiquette dans les valeurs, l'étiquette par défaut étant appVersion | 5, 6 |
La migration est un Job en hook pre-install,pre-upgrade, avec une politique de suppression | 8 |
Un test de chart (helm.sh/hook: test) appelle /sante | 8 |
values-preprod.yaml et values-prod.yaml produisent chacun un rendu valide, avec 1 et 3 répliques | 2, 6 |
helm package produit une archive nommée d'après la version du chart | 9 |
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 templateethelm lintn'en ont pas besoin, et un chart qui utiliseraitlookupne 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 :
requireddoit 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.