À la fin de ce TP, tu seras capable de :
- Comprendre l'écosystème Helm (chart, release, repository, values)
- Installer, mettre à jour et rollback des releases Helm
- Créer tes propres charts propres et réutilisables (templates, helpers, hooks, dependencies)
- Orchestrer plusieurs charts avec Helmfile
- Gérer plusieurs environnements (dev, staging, prod) sans dupliquer ta config
- Appliquer les bonnes pratiques DevOps (DRY, secrets, CI/CD-ready)
Tu es DevOps chez BookStore Inc.. L'équipe te demande de déployer une stack composée de :
| Composant | Rôle | Image |
|---|---|---|
bookstore-frontend |
UI statique (Nginx) | nginx:1.25-alpine |
bookstore-api |
Backend REST (mock) | mendhak/http-https-echo:31 |
postgresql |
Base de données | chart Bitnami |
redis |
Cache | chart Bitnami |
Le tout sur 3 environnements : dev, staging, prod, chacun avec ses spécificités (nb de réplicas, ressources, mots de passe, ingress, etc.).
# Vérifier Docker
docker --version
# Installer kind (cluster Kubernetes local) — alternative : minikube ou k3d
# Linux/macOS :
brew install kind # ou : go install sigs.k8s.io/kind@latest
# Installer kubectl
brew install kubectl
# Installer Helm 3
brew install helm
# Installer Helmfile
brew install helmfile
# Plugin Helm indispensable pour Helmfile
helm plugin install https://github.com/databus23/helm-diff# Cluster simple
kind create cluster --name tp-helm
# Vérifier
kubectl cluster-info
kubectl get nodesmkdir -p ~/tp-helm/{charts,helmfile}
cd ~/tp-helm| Concept | Définition |
|---|---|
| Chart | Un package Helm = un dossier contenant des templates Kubernetes paramétrables |
| Release | Une instance d'un chart déployée dans un cluster (un chart peut être installé plusieurs fois) |
| Repository | Un serveur HTTP qui héberge des charts (ex : https://charts.bitnami.com/bitnami) |
| Values | Les valeurs de configuration injectées dans les templates |
| Revision | Chaque install/upgrade crée une nouvelle révision (utile pour rollback) |
Analogie : un chart est à une release ce qu'une classe est à une instance en programmation orientée objet.
# Ajouter un repo
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
# Chercher un chart
helm search repo nginx
# Voir les valeurs disponibles d'un chart
helm show values bitnami/nginx > /tmp/nginx-default-values.yaml
less /tmp/nginx-default-values.yaml
# Installer (dry-run d'abord, toujours !)
helm install my-nginx bitnami/nginx --dry-run --debug
# Installation réelle
helm install my-nginx bitnami/nginx \
--namespace demo --create-namespace \
--set service.type=ClusterIP \
--set replicaCount=2# Lister les releases
helm list -A
# État détaillé
helm status my-nginx -n demo
# Voir les manifests générés
helm get manifest my-nginx -n demo
# Voir les valeurs utilisées
helm get values my-nginx -n demo
# Mettre à jour
helm upgrade my-nginx bitnami/nginx -n demo --set replicaCount=3
# Historique
helm history my-nginx -n demo
# Rollback à la révision 1
helm rollback my-nginx 1 -n demo
# Désinstaller
helm uninstall my-nginx -n demo- Installe le chart
bitnami/redisdans le namespacecacheavec :architecture=standaloneauth.enabled=false
- Vérifie qu'un pod tourne (
kubectl get pods -n cache). - Upgrade pour activer la persistence avec
master.persistence.size=2Gi. - Affiche l'historique, fais un rollback, puis désinstalle proprement.
Astuce : utilise un fichier
values.yamlplutôt que--setdès que tu as plus de 2-3 paramètres. C'est versionnable, lisible, et c'est la pratique pro.
helm install my-redis bitnami/redis -n cache --create-namespace -f my-values.yamlOn va créer un chart pour notre API bookstore-api.
cd ~/tp-helm/charts
helm create bookstore-api
tree bookstore-apiTu obtiens cette structure :
bookstore-api/
├── Chart.yaml # Métadonnées du chart
├── values.yaml # Valeurs par défaut
├── charts/ # Dépendances (sous-charts)
├── templates/
│ ├── _helpers.tpl # Templates réutilisables (helpers)
│ ├── deployment.yaml
│ ├── service.yaml
│ ├── ingress.yaml
│ ├── hpa.yaml
│ ├── serviceaccount.yaml
│ ├── NOTES.txt # Affiché après l'install
│ └── tests/
└── .helmignore
# bookstore-api/Chart.yaml
apiVersion: v2
name: bookstore-api
description: API REST pour BookStore
type: application
version: 0.1.0 # Version du chart (SemVer)
appVersion: "1.0.0" # Version de l'application
maintainers:
- name: Ton Nom
email: toi@bookstore.comHelm utilise le template engine de Go + des fonctions Sprig. La syntaxe : {{ ... }}.
Ouvre templates/deployment.yaml généré par helm create et observe ces patterns essentiels :
# Référence aux values
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
# Helpers (définis dans _helpers.tpl)
name: {{ include "bookstore-api.fullname" . }}
# Conditions
{{- if .Values.serviceAccount.create }}
serviceAccountName: {{ include "bookstore-api.serviceAccountName" . }}
{{- end }}
# Boucles
{{- range .Values.env }}
- name: {{ .name }}
value: {{ .value | quote }}
{{- end }}
# Indentation et nettoyage de whitespaces
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}Le tiret
-dans{{-et-}}supprime les espaces/sauts de ligne. C'est crucial pour produire du YAML valide.
Remplace le contenu de bookstore-api/values.yaml :
# bookstore-api/values.yaml
replicaCount: 1
image:
repository: mendhak/http-https-echo
tag: "31"
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 8080
targetPort: 8080
ingress:
enabled: false
className: ""
hosts:
- host: api.bookstore.local
paths:
- path: /
pathType: Prefix
env:
- name: HTTP_PORT
value: "8080"
- name: LOG_WITHOUT_NEWLINE
value: "true"
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
cpu: 200m
memory: 256Mi
# Healthchecks (à brancher dans le deployment)
probes:
liveness:
enabled: true
path: /
initialDelaySeconds: 10
readiness:
enabled: true
path: /
initialDelaySeconds: 5
autoscaling:
enabled: false
minReplicas: 1
maxReplicas: 5
targetCPUUtilizationPercentage: 80
serviceAccount:
create: true
name: ""
nodeSelector: {}
tolerations: []
affinity: {}Ouvre templates/deployment.yaml et adapte-le pour utiliser notre targetPort et nos env (le squelette généré ne les gère pas tous correctement). Voici la version cible :
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "bookstore-api.fullname" . }}
labels:
{{- include "bookstore-api.labels" . | nindent 4 }}
spec:
{{- if not .Values.autoscaling.enabled }}
replicas: {{ .Values.replicaCount }}
{{- end }}
selector:
matchLabels:
{{- include "bookstore-api.selectorLabels" . | nindent 6 }}
template:
metadata:
labels:
{{- include "bookstore-api.selectorLabels" . | nindent 8 }}
spec:
serviceAccountName: {{ include "bookstore-api.serviceAccountName" . }}
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- name: http
containerPort: {{ .Values.service.targetPort }}
protocol: TCP
{{- if .Values.env }}
env:
{{- range .Values.env }}
- name: {{ .name }}
value: {{ .value | quote }}
{{- end }}
{{- end }}
{{- if .Values.probes.liveness.enabled }}
livenessProbe:
httpGet:
path: {{ .Values.probes.liveness.path }}
port: http
initialDelaySeconds: {{ .Values.probes.liveness.initialDelaySeconds }}
{{- end }}
{{- if .Values.probes.readiness.enabled }}
readinessProbe:
httpGet:
path: {{ .Values.probes.readiness.path }}
port: http
initialDelaySeconds: {{ .Values.probes.readiness.initialDelaySeconds }}
{{- end }}
resources:
{{- toYaml .Values.resources | nindent 12 }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}Ce fichier contient des templates nommés réutilisables. Exemple typique :
{{/* Génère un nom complet pour les ressources */}}
{{- define "bookstore-api.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name .Chart.Name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{/* Labels communs */}}
{{- define "bookstore-api.labels" -}}
helm.sh/chart: {{ printf "%s-%s" .Chart.Name .Chart.Version }}
app.kubernetes.io/name: {{ .Chart.Name }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}L'appel se fait avec {{ include "bookstore-api.labels" . }}, le . final passe le contexte courant.
cd ~/tp-helm/charts/bookstore-api
# Linter (vérifie la syntaxe)
helm lint .
# Templating local (sans installer) — ESSENTIEL pour debug
helm template my-api . --debug
# Dry-run sur le cluster
helm install my-api . --namespace bookstore --create-namespace --dry-run --debug
# Install réel
helm install my-api . --namespace bookstore --create-namespace
# Tester
kubectl port-forward -n bookstore svc/my-api-bookstore-api 8080:8080
# Dans un autre terminal :
curl http://localhost:8080Modifie templates/NOTES.txt pour qu'après installation, l'utilisateur voie une commande kubectl port-forward prête à coller, adaptée au nom de la release.
Ajoute dans values.yaml une option podAnnotations (map vide par défaut) et propage-la dans le deployment.yaml sous spec.template.metadata.annotations.
Indice :
{{- with .Values.podAnnotations }}+{{- toYaml . | nindent 8 }}.
Notre bookstore-api a besoin d'une base PostgreSQL. On va la déclarer comme dépendance.
# bookstore-api/Chart.yaml
dependencies:
- name: postgresql
version: "15.x.x"
repository: "https://charts.bitnami.com/bitnami"
condition: postgresql.enabled# bookstore-api/values.yaml — ajouter à la fin
postgresql:
enabled: true
auth:
username: bookstore
password: changeme
database: bookstore
primary:
persistence:
size: 1Gi# Récupérer les dépendances
helm dependency update
# Tu vois apparaître charts/postgresql-x.y.z.tgz
ls charts/
# Réinstaller
helm upgrade --install my-api . -n bookstore
kubectl get pods -n bookstoreNotes importantes :
- Les valeurs d'un sous-chart se mettent sous une clé du nom du sous-chart (
postgresql:).condition: postgresql.enabledpermet de désactiver la dépendance via--set postgresql.enabled=false.- Pour partager une valeur entre charts (ex : la DB), regarde
global:etimport-values.
Les hooks permettent d'exécuter des actions à des moments précis du lifecycle :
| Hook | Quand |
|---|---|
pre-install / post-install |
Avant/après création des ressources |
pre-upgrade / post-upgrade |
Avant/après upgrade |
pre-delete / post-delete |
Avant/après uninstall |
test |
Lors d'un helm test |
Exemple : un Job qui initialise la base après installation.
# bookstore-api/templates/db-init-job.yaml
{{- if .Values.dbInit.enabled }}
apiVersion: batch/v1
kind: Job
metadata:
name: {{ include "bookstore-api.fullname" . }}-db-init
annotations:
"helm.sh/hook": post-install,post-upgrade
"helm.sh/hook-weight": "5"
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
spec:
template:
spec:
restartPolicy: Never
containers:
- name: init
image: postgres:15-alpine
command: ["sh", "-c"]
args:
- |
echo "Init DB pour la release {{ .Release.Name }}"
sleep 5
echo "Done"
{{- end }}# values.yaml
dbInit:
enabled: trueCrée un test simple dans templates/tests/test-connection.yaml (généré par helm create, à adapter) :
apiVersion: v1
kind: Pod
metadata:
name: "{{ include "bookstore-api.fullname" . }}-test"
annotations:
"helm.sh/hook": test
"helm.sh/hook-delete-policy": hook-succeeded
spec:
restartPolicy: Never
containers:
- name: curl
image: curlimages/curl:8
command: ["curl"]
args:
- "{{ include "bookstore-api.fullname" . }}:{{ .Values.service.port }}/"helm test my-api -n bookstore# Valeur par défaut
{{ .Values.image.tag | default .Chart.AppVersion }}
# Quote pour forcer une string (très utile avec les nombres-comme-string)
{{ .Values.port | quote }}
# Required (échoue si manquant)
{{ required "image.repository est obligatoire" .Values.image.repository }}
# Conditionnel ternaire
replicas: {{ ternary 3 1 .Values.production }}
# Génération aléatoire (mots de passe)
password: {{ randAlphaNum 16 }}
# Lookup d'une ressource existante (ex : preserver un secret)
{{- $existing := lookup "v1" "Secret" .Release.Namespace "my-secret" -}}Crée un second chart bookstore-frontend qui :
- Déploie un Nginx servant une page HTML statique (via ConfigMap montée dans le pod).
- A une dépendance optionnelle vers
redis(chart Bitnami) aveccondition: redis.enabled. - Inclut une variable
apiUrldans le values, injectée comme variable d'env dans le pod. - Expose un Service
ClusterIPconfigurable.
Pour la page HTML, utilise
templates/configmap.yamlavec :data: index.html: | <h1>BookStore - {{ .Release.Name }}</h1> <p>API: {{ .Values.apiUrl }}</p>Et monte la ConfigMap dans
/usr/share/nginx/html/.
Imagine que tu doives installer 5 charts pour dev, 5 pour staging, 5 pour prod. Avec Helm seul :
helm install api ./bookstore-api -f values-dev.yaml -n dev
helm install frontend ./bookstore-frontend -f values-dev.yaml -n dev
helm install monitoring prometheus-community/kube-prometheus-stack -f mon-dev.yaml -n monitoring
# ... répéter pour staging, prod, à chaque modifC'est non-déclaratif, sujet aux erreurs, et impossible à versionner proprement.
Helmfile = fichier déclaratif qui décrit toutes les releases d'un environnement. Une seule commande helmfile sync reconcilie l'état du cluster avec ton fichier.
Pense à Helmfile comme un
docker-compose.yamlpour Helm.
mkdir -p ~/tp-helm/helmfile
cd ~/tp-helm/helmfile# helmfile.yaml
repositories:
- name: bitnami
url: https://charts.bitnami.com/bitnami
releases:
- name: my-redis
namespace: cache
chart: bitnami/redis
version: "20.x.x"
values:
- architecture: standalone
auth:
enabled: false
- name: my-postgres
namespace: db
chart: bitnami/postgresql
version: "15.x.x"
values:
- auth:
username: bookstore
password: changeme
database: bookstore# Voir le diff (ce qui sera changé) — comme terraform plan
helmfile diff
# Appliquer (install + upgrade ce qui doit l'être)
helmfile apply
# Sync force (install/upgrade systématique)
helmfile sync
# Détruire toutes les releases du fichier
helmfile destroy
# Templater (voir le YAML final, sans appliquer)
helmfile template
# Lister les releases gérées
helmfile list
# Cibler une seule release
helmfile -l name=my-redis apply
apply=diff+sync(uniquement si différences). À privilégier en CI/CD.
Ajoute notre chart local bookstore-api au helmfile.yaml. Indice :
releases:
- name: bookstore-api
namespace: bookstore
chart: ../charts/bookstore-api # Chemin relatif !
values:
- replicaCount: 2Lance helmfile apply et vérifie que tout se déploie en une commande.
C'est là que Helmfile brille vraiment.
# helmfile.yaml
environments:
dev:
values:
- environments/dev.yaml
staging:
values:
- environments/staging.yaml
prod:
values:
- environments/prod.yaml
--- # ⚠️ Important : sépare la config des envs du reste
repositories:
- name: bitnami
url: https://charts.bitnami.com/bitnami
releases:
- name: bookstore-api
namespace: bookstore-{{ .Environment.Name }}
chart: ../charts/bookstore-api
values:
- replicaCount: {{ .Values.api.replicaCount }}
- image:
tag: {{ .Values.api.imageTag | quote }}
- resources:
requests:
cpu: {{ .Values.api.resources.cpu }}
memory: {{ .Values.api.resources.memory }}
- ingress:
enabled: {{ .Values.api.ingress.enabled }}
hosts:
- host: api.{{ .Values.domain }}
paths:
- path: /
pathType: Prefix# environments/dev.yaml
domain: dev.bookstore.local
api:
replicaCount: 1
imageTag: "31"
resources:
cpu: 50m
memory: 64Mi
ingress:
enabled: false# environments/staging.yaml
domain: staging.bookstore.local
api:
replicaCount: 2
imageTag: "31"
resources:
cpu: 100m
memory: 128Mi
ingress:
enabled: true# environments/prod.yaml
domain: bookstore.com
api:
replicaCount: 4
imageTag: "31" # On épingle une version stable en prod
resources:
cpu: 500m
memory: 512Mi
ingress:
enabled: true# Sélection de l'env via flag --environment ou -e
helmfile -e dev diff
helmfile -e dev apply
helmfile -e staging apply
helmfile -e prod diff # Toujours faire un diff avant prod !releases:
- name: bookstore-api
namespace: bookstore-{{ .Environment.Name }}
labels:
tier: backend
app: bookstore
chart: ../charts/bookstore-api
# ...
- name: bookstore-frontend
namespace: bookstore-{{ .Environment.Name }}
labels:
tier: frontend
app: bookstore
chart: ../charts/bookstore-frontend
# ...# Ne déployer que le backend
helmfile -e dev -l tier=backend apply
# Ne déployer qu'une release
helmfile -e dev -l name=bookstore-api applyHelmfile supporte les go-templates dans le helmfile.yaml lui-même (différent des templates Helm) :
releases:
{{- range $service := list "bookstore-api" "bookstore-frontend" }}
- name: {{ $service }}
namespace: bookstore-{{ $.Environment.Name }}
chart: ../charts/{{ $service }}
values:
- environments/{{ $.Environment.Name }}/{{ $service }}.yaml
{{- end }}Dans Helmfile, on a deux niveaux de templating :
- Helmfile lui-même (résolu avant que Helm soit appelé)
- Templates Helm dans le chart (résolus par Helm)
- Restructure ton projet ainsi :
~/tp-helm/ ├── charts/ │ ├── bookstore-api/ │ └── bookstore-frontend/ └── helmfile/ ├── helmfile.yaml └── environments/ ├── dev.yaml ├── staging.yaml └── prod.yaml - Configure 3 environnements avec des spécificités réelles :
- dev : 1 réplica, ressources mini, pas d'ingress, pas de persistence DB.
- staging : 2 réplicas, ressources moyennes, ingress activé, persistence 1Gi.
- prod : 3+ réplicas, ressources confortables, ingress + autoscaling, persistence 5Gi.
- Vérifie avec
helmfile -e <env> templateque le YAML généré est correct avant de déployer.
mon-projet/
├── charts/ # Tes charts maison
│ ├── bookstore-api/
│ └── bookstore-frontend/
├── helmfile/
│ ├── helmfile.yaml
│ ├── environments/ # Values par env
│ ├── releases/ # (optionnel) helmfile.yaml par groupe
│ └── secrets/ # Secrets chiffrés (sops)
├── .gitignore # Ignorer charts/*/charts/, *.lock optionnel
└── README.md
Ne jamais commit de mots de passe en clair. Solution : helm-secrets (plugin Helm) + sops (chiffrement) + KMS / age / GPG.
# Installation
helm plugin install https://github.com/jkroepke/helm-secrets
brew install sops age
# Générer une clé age
age-keygen -o ~/.config/sops/age/keys.txt
# Configurer .sops.yaml dans ton repo
cat > .sops.yaml <<EOF
creation_rules:
- path_regex: secrets/.*\.yaml$
age: <ta-public-key-age>
EOF
# Chiffrer un fichier
sops --encrypt secrets/prod.yaml > secrets/prod.enc.yamlDans helmfile.yaml :
releases:
- name: bookstore-api
chart: ../charts/bookstore-api
secrets:
- secrets/{{ .Environment.Name }}.enc.yamlTu peux exécuter des commandes shell autour des actions :
releases:
- name: bookstore-api
chart: ../charts/bookstore-api
hooks:
- events: ["prepare"]
showlogs: true
command: "echo"
args: ["Préparation du déploiement de bookstore-api"]
- events: ["postsync"]
command: "kubectl"
args: ["rollout", "status", "deployment/bookstore-api", "-n", "bookstore-{{ `{{ .Environment.Name }}` }}"]Pipeline type (GitLab/GitHub Actions) :
# .github/workflows/deploy.yml (extrait)
- name: Lint charts
run: |
for chart in charts/*/; do
helm lint "$chart"
done
- name: Helmfile diff (dev)
run: helmfile -e dev diff --detailed-exitcode
# Exit 2 = changements détectés (utile pour fail si pas attendu)
- name: Helmfile apply (dev)
if: github.ref == 'refs/heads/main'
run: helmfile -e dev apply-
values.yamldocumenté (commentaires sur chaque option) -
Chart.yamlversionné en SemVer,appVersionà jour - Labels standards (
app.kubernetes.io/*) - Resources (requests + limits) toujours définies
- Probes (liveness, readiness) configurables
-
securityContext(runAsNonRoot, readOnlyRootFilesystem) -
NetworkPolicyoptionnelle -
PodDisruptionBudgetoptionnel - Tests Helm (
helm test) -
README.mddu chart avec table des values (utiliser helm-docs) - CI :
helm lint+helm template+kubectl apply --dry-run=server
Tu dois livrer le déploiement complet de BookStore sur les 3 environnements, en respectant ces contraintes :
-
2 charts maison :
bookstore-apietbookstore-frontend(déjà commencés). -
2 charts externes :
postgresqletredis(Bitnami), gérés via Helmfile (pas en dependency cette fois — pour pratiquer les deux approches). -
3 environnements avec ces specs :
dev staging prod API replicas 1 2 3 Frontend replicas 1 2 3 DB persistence 1Gi 5Gi 20Gi Ingress Non Oui Oui Resources xs s m DB password en clair (dev.yaml) secrets sops secrets sops -
Le frontend doit afficher une page HTML qui mentionne dynamiquement l'environnement courant (via une variable d'env injectée).
-
Une seule commande doit suffire à déployer un environnement complet :
helmfile -e <env> apply. -
Bonus :
- Tests Helm sur chaque chart maison.
- Hook
pre-installqui crée le namespace si absent (ou utilisercreateNamespace: true). helm-docspour générer la doc des values automatiquement.
helmfile -e dev applypuiskubectl get all -n bookstore-devmontre tout enRunning.helmfile -e prod templategénère du YAML valide avec les bonnes valeurs.helmfile -e <env> destroynettoie tout proprement.- Aucune valeur sensible en clair dans Git pour staging/prod.
- Code organisé, lisible, commenté.
- Documentation officielle Helm : https://helm.sh/docs/
- Documentation Helmfile : https://helmfile.readthedocs.io/
- Best practices Helm : https://helm.sh/docs/chart_best_practices/
- Sprig functions (très utile pour les templates) : https://masterminds.github.io/sprig/
- Awesome Helm (charts + outils) : https://github.com/cdwv/awesome-helm
- helm-secrets : https://github.com/jkroepke/helm-secrets
- helm-docs (génération doc) : https://github.com/norwoodj/helm-docs
- Artifact Hub (catalogue de charts) : https://artifacthub.io/
# Supprimer toutes les releases via helmfile
helmfile -e dev destroy
helmfile -e staging destroy
helmfile -e prod destroy
# Détruire le cluster
kind delete cluster --name tp-helm| Notion | Partie |
|---|---|
| Chart, Release, Repository, Values, Revision | 1 |
helm install/upgrade/rollback/uninstall |
1 |
| Création de chart, structure | 2 |
| Templates Go, helpers, NOTES.txt | 2 |
| Dependencies (subcharts) | 3 |
Hooks (pre-install, post-upgrade...) |
3 |
helm test, fonctions Sprig |
3 |
| Helmfile basics, commandes principales | 4 |
| Multi-environnements, selectors | 5 |
| Templating Helmfile (go-templates) | 5 |
| Secrets (sops), structure projet, CI/CD | 6 |
Ce TP a été réalisé par Hamidou NDIAYE dans le cadre d'un apprentissage approfondi de Helm et Helmfile.
Contact :
- Email : ndiayehamidou9853@gmail.com
- LinkedIn : Hamidou NDIAYE
- GitHub : @hndiaye9854
Vous avez trouvé une erreur, une coquille, ou vous avez une suggestion pour améliorer ce TP ? Toute contribution est la bienvenue !
Plusieurs façons de me faire un retour :
-
Ouvrir une issue (recommandé) : Signaler un problème
- Décrivez le problème rencontré
- Précisez la partie du TP concernée
- Joignez si possible un message d'erreur ou un screenshot
-
Proposer une correction directe via une Pull Request :
git clone https://github.com/hndiaye9854/learn_helm-and-helmfile.git
git checkout -b fix/ma-correction
# ... vos modifications ...
git commit -m "fix: description de la correction"
git push origin fix/ma-correction- Me contacter directement par email ou LinkedIn pour toute question.
Les contributions qui enrichissent le TP sont particulièrement bienvenues :
- Ajout d'exercices ou de cas pratiques
- Corrections de bugs ou de typos
- Améliorations de la documentation
- Adaptations pour d'autres outils (k3d, microk8s...)
Ce TP est partagé librement à des fins éducatives. N'hésitez pas à le réutiliser, le forker et l'adapter à vos besoins.
Bon TP ! N'hésite pas à expérimenter, casser les choses et regarder ce qui se passe, c'est comme ça qu'on apprend le mieux.
⭐ Si ce TP vous a été utile, n'hésitez pas à mettre une étoile au repo ! ⭐