Exercices et Projets
1 - Exercices pratiques
Exercice 1 : Installation et configuration
Objectif : Installer un chart depuis un repository public.
# Tâches :
# 1. Ajouter le repository Bitnami
# 2. Rechercher le chart nginx
# 3. Voir les valeurs disponibles
# 4. Installer avec 3 réplicas et un service NodePort
# 5. Vérifier le déploiement
Solution
# 1. Ajouter le repository
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
# 2. Rechercher nginx
helm search repo nginx
# 3. Voir les valeurs
helm show values bitnami/nginx > nginx-values.yaml
# 4. Installer
helm install my-nginx bitnami/nginx \
--set replicaCount=3 \
--set service.type=NodePort
# 5. Vérifier
helm list
kubectl get pods,svc
Exercice 2 : Créer un chart basique
Objectif : Créer un chart pour une application simple.
# Tâches :
# 1. Créer un nouveau chart "hello-world"
# 2. Modifier pour déployer l'image hashicorp/http-echo
# 3. Configurer le message via values
# 4. Installer et tester
Solution
# 1. Créer le chart
helm create hello-world
# 2-3. Modifier values.yaml
# values.yaml
replicaCount: 1
image:
repository: hashicorp/http-echo
tag: "0.2.3"
pullPolicy: IfNotPresent
message: "Hello from Helm!"
service:
type: ClusterIP
port: 5678
# templates/deployment.yaml (extrait)
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
args:
- "-text={{ .Values.message }}"
ports:
- containerPort: 5678
# 4. Installer et tester
helm install hello ./hello-world
kubectl port-forward svc/hello-hello-world 8080:5678
curl localhost:8080
Exercice 3 : Templates avancés
Objectif : Utiliser les fonctions de templating.
Créez un template qui :
- Génère des labels standards
- Configure les ressources conditionnellement
- Itère sur une liste d'hosts pour l'Ingress
Solution
# _helpers.tpl
{{- define "app.labels" -}}
app.kubernetes.io/name: {{ include "app.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version }}
{{- end }}
# deployment.yaml
metadata:
labels:
{{- include "app.labels" . | nindent 4 }}
spec:
template:
spec:
containers:
- name: app
{{- if .Values.resources }}
resources:
{{- toYaml .Values.resources | nindent 10 }}
{{- end }}
# ingress.yaml
{{- if .Values.ingress.enabled }}
spec:
rules:
{{- range .Values.ingress.hosts }}
- host: {{ .host | quote }}
http:
paths:
{{- range .paths }}
- path: {{ .path }}
pathType: {{ .pathType }}
backend:
service:
name: {{ $.Release.Name }}
port:
number: {{ $.Values.service.port }}
{{- end }}
{{- end }}
{{- end }}
Exercice 4 : Gestion des releases
Objectif : Pratiquer le cycle de vie des releases.
# Tâches :
# 1. Installer une release
# 2. Faire un upgrade avec nouvelles values
# 3. Voir l'historique
# 4. Faire un rollback
# 5. Désinstaller proprement
Solution
# 1. Installer
helm install myapp bitnami/nginx --set replicaCount=1
# 2. Upgrade
helm upgrade myapp bitnami/nginx --set replicaCount=3 --set service.type=LoadBalancer
# 3. Historique
helm history myapp
# 4. Rollback
helm rollback myapp 1
# 5. Désinstaller
helm uninstall myapp
Exercice 5 : Hooks et Tests
Objectif : Créer un hook pre-install et un test.
Solution
# templates/hooks/pre-install.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: "{{ .Release.Name }}-init"
annotations:
"helm.sh/hook": pre-install
"helm.sh/hook-delete-policy": hook-succeeded
spec:
template:
spec:
containers:
- name: init
image: busybox
command: ['sh', '-c', 'echo "Initializing..."']
restartPolicy: Never
# templates/tests/test-connection.yaml
apiVersion: v1
kind: Pod
metadata:
name: "{{ .Release.Name }}-test"
annotations:
"helm.sh/hook": test
spec:
containers:
- name: test
image: busybox
command: ['wget', '-q', '-O-', '{{ include "app.fullname" . }}:{{ .Values.service.port }}']
restartPolicy: Never
# Tester
helm test myapp
2 - Projet complet : Application Web
Description
Créez un chart Helm complet pour une application web avec :
- Frontend (Nginx avec configuration personnalisée)
- Backend API (image personnalisée ou http-echo)
- Base de données PostgreSQL (dépendance)
- Cache Redis (dépendance)
- Ingress avec TLS
Structure du chart
webapp-chart/
├── Chart.yaml
├── values.yaml
├── values-production.yaml
├── templates/
│ ├── _helpers.tpl
│ ├── frontend/
│ │ ├── deployment.yaml
│ │ ├── service.yaml
│ │ └── configmap.yaml
│ ├── backend/
│ │ ├── deployment.yaml
│ │ └── service.yaml
│ ├── ingress.yaml
│ ├── networkpolicy.yaml
│ ├── hooks/
│ │ └── db-migrate.yaml
│ └── tests/
│ └── test-endpoints.yaml
└── ci/
└── test-values.yaml
Chart.yaml
apiVersion: v2
name: webapp
version: 1.0.0
appVersion: "1.0.0"
description: Application web complète avec frontend, backend et dépendances
dependencies:
- name: postgresql
version: "12.x.x"
repository: https://charts.bitnami.com/bitnami
condition: postgresql.enabled
- name: redis
version: "17.x.x"
repository: https://charts.bitnami.com/bitnami
condition: redis.enabled
values.yaml
# Global
global:
imageRegistry: ""
# Frontend
frontend:
replicaCount: 2
image:
repository: nginx
tag: "1.25"
service:
type: ClusterIP
port: 80
resources:
limits:
cpu: 200m
memory: 256Mi
# Backend
backend:
replicaCount: 2
image:
repository: hashicorp/http-echo
tag: "0.2.3"
message: "API Response"
service:
type: ClusterIP
port: 5678
resources:
limits:
cpu: 500m
memory: 512Mi
# Ingress
ingress:
enabled: false
className: nginx
hosts:
- host: webapp.local
paths:
- path: /
pathType: Prefix
service: frontend
- path: /api
pathType: Prefix
service: backend
# Dependencies
postgresql:
enabled: true
auth:
database: webapp
username: webapp
redis:
enabled: true
architecture: standalone
Déploiement
# Dépendances
helm dependency update ./webapp-chart
# Installation développement
helm install webapp-dev ./webapp-chart \
--namespace dev \
--create-namespace
# Installation production
helm install webapp-prod ./webapp-chart \
--namespace production \
--create-namespace \
-f values-production.yaml \
--atomic \
--wait
# Tests
helm test webapp-dev
3 - Quiz de révision
-
Quelle est la différence entre
helm templateethelm install --dry-run? -
Comment surcharger une valeur imbriquée avec --set ?
-
Quel est l'ordre de priorité des values ?
-
Quelle annotation définit un hook pre-upgrade ?
-
Comment voir les values utilisées dans une release ?
Réponses
-
helm templaterend les manifests localement sans connexion au cluster.--dry-runcontacte le cluster pour validation. -
--set parent.child.key=value -
values.yaml < fichiers -f (dans l'ordre) < --set/--set-string
-
"helm.sh/hook": pre-upgrade -
helm get values <release-name>ou--allpour inclure les defaults
Résumé du cours
Félicitations ! Vous avez complété le cours Helm. Vous maîtrisez :
- L'installation et configuration de Helm
- Les concepts fondamentaux (Charts, Releases, Repositories)
- La création de charts personnalisés
- Les templates Go et fonctions Helm
- La gestion des repositories HTTP et OCI
- Le cycle de vie des releases
- Les hooks et tests
- Les bonnes pratiques
Prochaines étapes
- Pratiquer avec des charts existants
- Créer des charts pour vos applications
- Explorer Helmfile pour le multi-release
- Intégrer Helm dans vos pipelines CI/CD