Helm 4 est arrivé en novembre 2025. Six ans après Helm 3, cette nouvelle version majeure promet de réduire la dette technique, d'améliorer les performances et d'introduire de nouvelles fonctionnalités.
Mais alors que la communauté se prépare à célébrer cette évolution et que les entreprises ont déjà commencé à créer des tickets Jira pour préparer la migration, il est temps de poser une question inconfortable : Helm est-il toujours la meilleure solution pour déployer vos applications Kubernetes ? Ou perpétuons-nous simplement une habitude devenue obsolète ?
La version 4 de Helm apporte plusieurs changements (liste non exhaustive) :
Helm 4 se trouve dans une position difficile : il doit innover tout en maintenant une compatibilité quasi-totale avec Helm 3 pour éviter de fragmenter l'écosystème. Cette contrainte, bien qu'elle protège les utilisateurs existants, limite drastiquement la capacité du projet à résoudre ses problèmes fondamentaux.
Helm utilise le moteur de templating Go, ce qui semble logique puisque Helm est écrit en Go. Mais cette décision technique crée une barrière d'entrée importante et des manifestes rapidement illisibles.
Exemple:
{{- if .Values.ingress.enabled -}}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ include "myapp.fullname" . }}
{{- with .Values.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if .Values.ingress.tls }}
tls:
{{- range .Values.ingress.tls }}
- hosts:
{{- range .hosts }}
- {{ . | quote }}
{{- end }}
secretName: {{ .secretName }}
{{- end }}
{{- end }}
rules:
{{- range .Values.ingress.hosts }}
- host: {{ .host | quote }}
http:
paths:
{{- range .paths }}
- path: {{ .path }}
pathType: {{ .pathType }}
backend:
service:
name: {{ $.Values.service.name }}
port:
number: {{ $.Values.service.port }}
{{- end }}
{{- end }}
{{- end }}
Les problèmes :
({{- vs {{) pour gérer les espaces rendent le code fragileHelm maintient l'état des déploiements dans des secrets stockés dans le cluster. En théorie, c'est sympa pour les rollbacks. En pratique, c'est une source de problèmes :
Problème 1 : Divergence entre l'état Helm et la réalité
Imaginons ce scénario courant :
kubectl edithelm upgradeProblème 2 : Pollution du namespace
$ kubectl get secrets -n production | grep helm
sh.helm.release.v1.myapp.v1 helm.sh/release.v1 1 180d
sh.helm.release.v1.myapp.v2 helm.sh/release.v1 1 175d
sh.helm.release.v1.myapp.v3 helm.sh/release.v1 1 170d
...
sh.helm.release.v1.myapp.v47 helm.sh/release.v1 1 2d
Chaque release Helm crée un nouveau secret. Votre cluster accumule ces secrets qui ne servent qu'aux rollbacks Helm.
Problème 3 : Les rollbacks sont trompeurs
helm rollback ne fait PAS un vrai rollback Kubernetes, il ne rollback que l’image que helm se fait de l’état précédent.
Ca peut sembler être un comportement attendu, mais ça veut dire en pratique que des ressources orphelines ou mal gérées peuvent continuer d’exister, notamment des PV, PVC, CRD, jobs, etc.
De plus, helm ne re-télécharge pas systématiquement les dépendances, ce qui pose des problèmes de versionning:
# Chart.yaml
dependencies:
- name: postgresql
version: "12.x.x" # not pinned
repository: "https://charts.bitnami.com/bitnami"
Ici, dans le cas d’un rollback, je n’ai aucune garantie que je vais retrouver le même comportement avant mon upgrade qui a raté. Ceci peut sembler n’être juste une question d'hygiène de gestion des versions, mais quand on commence à dépendre d’une chart externe, qui peut elle-même dépendre d’une autre chart sur laquelle on n’a pas de contrôle car on n’a pas défini de version.
Les charts Helm peuvent avoir des dépendances (sous-charts). C'est puissant sur le papier, mais devient vite ingérable :
# Chart.yaml
dependencies:
- name: postgresql
version: "12.1.2"
repository: "https://charts.bitnami.com/bitnami"
- name: redis
version: "17.3.7"
repository: "https://charts.bitnami.com/bitnami"
Les problèmes :
Helm se présente comme simple : "Kubernetes package manager". Mais en réalité, pour l'utiliser correctement, il faut maîtriser :
C'est un DSL complet à apprendre EN PLUS de Kubernetes (et du templating Go).
Beaucoup de projets open-source fournissent des charts Helm officiels.
Le problème ? Ces charts tentent d'être universels et supportent des dizaines de cas d'usage, résultant en :
values.yaml de 500+ lignesExemple réel : Le chart officiel de Prometheus a plus de 1300 lignes de configuration avec commentaires. Ça fait un document de 1300 lignes à comprendre pour utiliser le produit.
Heureusement, l'écosystème Kubernetes propose des alternatives.
Philosophie : On reste proche des racines
Exemple d'utilisation :
# base/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
replicas: 1
template:
spec:
containers:
- name: myapp
image: myapp:1.0.0
# overlays/production/kustomization.yaml
resources:
- ../../base
replicas:
- name: myapp
count: 3
images:
- name: myapp
newTag: 1.0.5
Avantages :
Inconvénients :
Quand l'utiliser :
Philosophie : On veut du typage, on veut de la fiabilité, on aime la production
Exemple :
// values.cue
#Config: {
metadata: {
name: string & =~"^[a-z0-9-]+$"
namespace: string | *"default"
}
replicas: int & >=1 & <=10
image: {
repository: string
tag: string
}
}
values: #Config & {
metadata: name: "myapp"
replicas: 3
image: {
repository: "myapp"
tag: "v1.2.3"
}
}
Avantages :
Inconvénients :
Quand l'utiliser :
Philosophie : Séparer le templating (ytt) du déploiement (kapp).
ytt pour le templating :
#@ load("@ytt:data", "data")
---
apiVersion: v1
kind: ConfigMap
metadata:
name: myapp-config
data:
database_url: #@ data.values.database.url
#@ if data.values.features.caching:
cache_enabled: "true"
#@ end
kapp pour le déploiement :
kapp deploy -a myapp -f config/ --diff-changes
Avantages :
Inconvénients :
Quand l'utiliser :
Philosophie : Git est notre source de vérité, ce qu’on met dans git, c’est ce qu’on a dans notre cluster Kubernetes. Et en passant, on réconcilie (presque) tout le monde.
Exemple avec ArgoCD :
# Application manifest
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: myapp
spec:
project: default
source:
repoURL: https://github.com/myorg/myapp
targetRevision: main
path: k8s/production
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
Avantages :
Inconvénients :
Quand l'utiliser :
Philosophie : Utiliser un vrai langage de programmation pour définir une infrastructure.
Exemple Pulumi (TypeScript) :
import * as k8s from "@pulumi/kubernetes";
const appLabels = { app: "nginx" };
const deployment = new k8s.apps.v1.Deployment("nginx", {
spec: {
selector: { matchLabels: appLabels },
replicas: 3,
template: {
metadata: { labels: appLabels },
spec: {
containers: [{
name: "nginx",
image: "nginx:1.21",
ports: [{ containerPort: 80 }],
}],
},
},
},
});
const service = new k8s.core.v1.Service("nginx", {
spec: {
type: "LoadBalancer",
selector: appLabels,
ports: [{ port: 80, targetPort: 80 }],
},
});
export const serviceIp = service.status.loadBalancer.ingress[0].ip;
Avantages :
Inconvénients :
Quand l'utiliser :
Parfois, la meilleure solution est la plus simple.
Avantages :
Inconvénients :
Quand l'utiliser :
La réponse est nuancée : Ça dépend.
Helm a été révolutionnaire en 2016. Il a démocratisé le déploiement d'applications sur Kubernetes et a permis à des milliers d'organisations d'adopter cette technologie.
Aujourd'hui, le paysage a changé.
Kubernetes est mature, les équipes sont plus expérimentées, et nous avons compris que l'abstraction n'est pas toujours la réponse.
Parfois, la simplicité d'un overlay Kustomize sera avantageuse par rapport la flexibilité et la réusabilité d'une chart Helm.
Parfois, la mise en place d’une validation stricte avec Timoni permettra de fiabiliser les déploiements.
Parfois, la chart helm nous est fournie, est maintenue, alors pourquoi ne pas l’utiliser, tant qu’on fait confiance à la source.
Helm 4 est une évolution nécessaire pour maintenir l'outil pertinent, mais elle n'adresse pas les problèmes fondamentaux du produit.
La vraie question n'est pas "Faut-il utiliser Helm ?" mais "Quel est le bon outil dans MON contexte pour déployer sur Kubernetes ?"
La maturité technologique, c'est savoir choisir le bon outil pour le bon problème, pas suivre ce que tout le monde utilise.
Et puis aujourd’hui encore, je ne sais toujours pas si on dit “un” chart ou “une” chart helm. Et rien que ça, ça méritait un article.