| name | helm-charts |
| description | Gestion de packages Kubernetes avec Helm — création de charts, templating Go, sous-charts, hooks, repositories, CI/CD intégré, rollback, bonnes pratiques |
| version | 1.0.0 |
| author | EVA |
| license | Privée EVA |
| category | mlops |
| metadata | {"EVA":{"tags":["helm","charts","kubernetes","templating","go-templates","package-manager","releases","rollback"],"related_skills":["kubernetes-avance","ci-cd-pipelines","gitops-argocd","docker-avance"]}} |
Helm — Gestion de Charts Kubernetes
Vue d'ensemble
Helm est le gestionnaire de paquets Kubernetes. Il permet de définir, installer et mettre à jour des applications complexes via des charts paramétrables. Cette compétence couvre la création de charts, le templating Go, les sous-charts et dépendances, les hooks, la gestion des repositories, l'intégration CI/CD, et les bonnes pratiques.
Quand l'utiliser
- Packager une application pour des déploiements reproductibles sur Kubernetes
- Paramétrer des déploiements multi-environnements (dev/staging/prod)
- Distribuer des applications via un repository Helm
- Gérer les dépendances entre plusieurs charts
- Automatiser les mises à jour avec des pipelines CI/CD
1. Structure d'un Chart
my-app/
├── Chart.yaml # Métadonnées du chart
├── values.yaml # Valeurs par défaut
├── values.schema.json # Validation JSON Schema (optionnel)
├── charts/ # Sous-charts dépendants
│ └── postgresql/
│ └── ...
├── templates/
│ ├── _helpers.tpl # Templates partagés (named templates)
│ ├── deployment.yaml # Déploiement
│ ├── service.yaml # Service
│ ├── ingress.yaml # Ingress
│ ├── configmap.yaml # Configuration
│ ├── secret.yaml # Secrets
│ ├── hpa.yaml # Autoscaling
│ ├── tests/
│ │ └── test-connection.yaml
│ └── NOTES.txt # Instructions post-install
└── .helmignore # Exclusions
Chart.yaml
apiVersion: v2
name: my-app
description: Application EVA déployée via Helm
type: application
version: 1.2.3
appVersion: "1.2.0"
kubeVersion: ">= 1.28.0"
keywords:
- eva
- api
home: https://eva.local
sources:
- https://git.eva.local/my-app
maintainers:
- name: EVA Team
email: devops@eva.local
dependencies:
- name: postgresql
version: "~15.0"
repository: "oci://registry-1.docker.io/bitnamicharts"
condition: postgresql.enabled
alias: db
- name: redis
version: "~19.0"
repository: "https://charts.bitnami.com/bitnami"
condition:
2. Templating Go (Fonctions Essentielles)
{{- define "my-app.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- define "my-app.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" }}
{{ }}
{{ }}
{{ }}
{{ }}
{{ }}
{{ }}
{{ }}
{{ }}
{{ }}
{{ }}
{{ }}
{{ }}
{{ }}
{{ }}
{{ }}
templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "my-app.fullname" . }}
labels:
{{- include "my-app.labels" . | nindent 4 }}
spec:
{{- if not .Values.autoscaling.enabled }}
replicas: {{ .Values.replicaCount }}
{{- end }}
selector:
matchLabels:
{{- include "my-app.selectorLabels" . | nindent 6 }}
template:
metadata:
{{- with .Values.podAnnotations }}
annotations:
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "my-app.selectorLabels" . | nindent }}
{{ }}
{{ }}
{{ }}
{{ }}
{{ }}
{{ }}
{{ }}
{{ }}
{{ }}
{{ }}
{{ }}
{{ }}
{{ }}
{{ }}
{{ }}
{{ }}
{{ }}
{{ }}
{{ }}
{{ }}
{{ }}
{{ }}
{{ }}
{{ }}
{{ }}
3. values.yaml (Paramétrage)
replicaCount: 2
image:
repository: registry.eva.local/my-app
tag: ""
pullPolicy: IfNotPresent
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
serviceAccount:
create: true
automount: true
annotations: {}
name: ""
podAnnotations: {}
podSecurityContext:
runAsNonRoot: true
runAsUser: 10001
fsGroup: 10001
securityContext:
capabilities:
drop: ["ALL"]
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 10001
service:
type: ClusterIP
port: 8000
ingress:
enabled: false
className: nginx
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
hosts:
{}
[]
{}
Valeurs multi-environnements
replicaCount: 5
resources:
limits:
cpu: 2
memory: 2Gi
requests:
cpu: 1
memory: 1Gi
autoscaling:
maxReplicas: 20
postgresql:
enabled: true
auth:
database: myapp_prod
replicaCount: 1
resources:
limits:
cpu: 200m
memory: 256Mi
requests:
cpu: 100m
memory: 128Mi
postgresql:
enabled: false
4. Commandes Essentielles
helm create my-app
helm dependency update my-app/
helm dependency build my-app/
helm lint my-app/
helm template my-app ./my-app/
helm template my-app ./my-app/ --debug
helm get manifest my-app --namespace prod
helm install my-app ./my-app/ --namespace prod --create-namespace
helm upgrade --install my-app ./my-app/ -f values-prod.yaml --atomic --timeout 10m
helm upgrade --install my-app ./my-app/ --set image.tag=v1.2.3
helm rollback my-app 2 --namespace prod
helm history my-app --namespace prod
helm uninstall my-app --namespace prod
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
helm search repo bitnami/nginx
helm pull bitnami/nginx --untar
5. Hooks Helm
apiVersion: batch/v1
kind: Job
metadata:
name: {{ include "my-app.fullname" . }}-migration
annotations:
"helm.sh/hook": pre-upgrade,pre-install
"helm.sh/hook-weight": "-5"
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
spec:
template:
spec:
restartPolicy: Never
containers:
- name: migration
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
command: ["alembic", "upgrade", "head"]
Annotation helm.sh/hook | Déclencheur |
|---|
pre-install | Avant l'installation |
post-install | Après l'installation |
pre-upgrade | Avant la mise à jour |
post-upgrade | Après la mise à jour |
pre-rollback | Avant le rollback |
post-rollback | Après le rollback |
pre-delete | Avant la suppression |
test | Lors de helm test |
6. Test de Chart
apiVersion: v1
kind: Pod
metadata:
name: "{{ include "my-app.fullname" . }}-test-connection"
labels:
{{- include "my-app.labels" . | nindent 4 }}
annotations:
"helm.sh/hook": test
spec:
containers:
- name: wget
image: busybox
command: ['wget']
args: ['{{ include "my-app.fullname" . }}:{{ .Values.service.port }}']
restartPolicy: Never
helm test my-app --namespace prod
7. Pièges Courants
- values.yaml trop long : 500 lignes de valeurs sont illisibles. Structurer en sections claires, utiliser des valeurs calculées dans
_helpers.tpl.
- Dépendances non verrouillées :
helm dependency update sans Chart.lock dans le repo = build non reproductible. Toujours commiter Chart.lock.
- Templates non testés :
helm template ne déploie pas, mais ne valide pas la logique métier. Utiliser helm unittest (plugin) ou helm test.
- Secrets en clair dans values :
values.yaml est en clair. Utiliser un plugin vault (Helm Secrets, SOPS) ou ArgoCD Vault Plugin.
- Hooks mal priorités : Deux hooks pre-install sans poids peuvent s'exécuter dans n'importe quel ordre. Toujours définir
helm.sh/hook-weight.
- Pas de --atomic : Sans
--atomic, un upgrade qui échoue laisse le release cassé. --atomic rollback automatiquement.
8. Checklist Production