Aller au contenu principal

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 :

  1. Génère des labels standards
  2. Configure les ressources conditionnellement
  3. 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

  1. Quelle est la différence entre helm template et helm install --dry-run ?

  2. Comment surcharger une valeur imbriquée avec --set ?

  3. Quel est l'ordre de priorité des values ?

  4. Quelle annotation définit un hook pre-upgrade ?

  5. Comment voir les values utilisées dans une release ?

Réponses
  1. helm template rend les manifests localement sans connexion au cluster. --dry-run contacte le cluster pour validation.

  2. --set parent.child.key=value

  3. values.yaml < fichiers -f (dans l'ordre) < --set/--set-string

  4. "helm.sh/hook": pre-upgrade

  5. helm get values <release-name> ou --all pour 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

← Retour à la table des matières