Kubernetes ou pas
Kubernetes résout un vrai problème, celui d’ordonnancer beaucoup de charges sur beaucoup de machines en se réparant tout seul et il le résout bien. Le piège n’est pas l’outil, c’est de le sortir pour un problème qu’on n’a pas encore, en payant d’avance une taxe opérationnelle permanente pour une résilience qu’on n’utilise pas. Parce que la vraie dépense de Kubernetes n’est pas conceptuelle, elle est opérationnelle: le control plane à tenir, le CNI à comprendre, le stockage à monter, les mises à jour trimestrielles d’API à suivre et une surface d’attaque qui a ses propres billets de durcissement. Avant de signer pour ça, il vaut la peine de descendre les étages et de s’arrêter au premier qui porte la charge, parce que le bon niveau d’abstraction est le plus bas qui règle votre problème, pas le plus prestigieux.
Un hôte, quelques services: systemd suffit presque
L’immense majorité des déploiements sont une poignée de services sur une seule machine et là Kubernetes n’apporte rien qu’une couche à opérer.
Le réflexe est docker-compose et pour développer ou pour un bricolage il est parfait: un fichier, up, down, on comprend tout de suite.
Pour de la production sur un hôte, il y a mieux et plus discret, c’est de laisser systemd faire son travail, puisqu’il est déjà là, déjà superviseur, déjà le gestionnaire de dépendances et de redémarrage de la machine.
Podman et les quadlets rendent ça propre: on décrit un container dans un petit fichier d’unité et le générateur systemd en fait un vrai service, avec les dépendances, les redémarrages, les logs dans le journal et le tout en rootless.
# /etc/containers/systemd/app.container
[Container]
Image=registry.example.org/app:1.4.2
PublishPort=8080:8080
AutoUpdate=registry
[Service]
Restart=always
[Install]
WantedBy=multi-user.target
Un systemctl daemon-reload plus tard, app.service existe, démarre au boot et se relève seul et podman-auto-update.timer tire les nouvelles images sans qu’on y pense. C’est déclaratif, versionnable et ça n’ajoute aucun démon à superviser puisque le superviseur, c’est l’init que la machine fait déjà tourner. Pour un hôte, c’est l’étage où la plupart des projets devraient s’arrêter.
Quelques nœuds, toujours simple: Docker Swarm
Quand il faut vraiment plusieurs machines, pour la disponibilité ou pour la charge, la marche suivante n’est pas Kubernetes, c’est Docker Swarm et je l’ai déjà défendu dans un billet dédié
.
Swarm fait du vrai clustering avec une honnêteté désarmante: mTLS entre nœuds et certificats qui tournent d’emblée, un magasin Raft chiffré, de vrais secrets, un réseau overlay chiffrable d’un drapeau et un modèle mental qui tient dans une page.
On a un docker-compose.yml déjà écrit, on le déploie en stack et on a des répliques, du rolling update et du failover sans avoir rien appris de neuf.
Le reproche fait à Swarm est social plus que technique, il est passé de mode; mais pour trois à une poignée de nœuds qui font tourner des services pas trop nombreux, il porte la charge pour une fraction du coût d’exploitation. Le jour où ce qu’on lui demande dépasse ce qu’il sait faire, on le saura et c’est précisément ce jour-là que la question de Kubernetes redevient légitime.
Plus gros, mais pas prêt pour k8s: Nomad et Consul
Il existe un étage intermédiaire que la hype saute toujours, entre Swarm et Kubernetes: ordonnancer beaucoup de charges sur beaucoup de nœuds, sans avaler toute la complexité de k8s. C’est le terrain de Nomad , l’ordonnanceur de HashiCorp, un binaire unique qui place des tâches sur un parc, avec le même modèle Raft à serveurs impairs qu’on retrouve partout, trois ou cinq pour le quorum. Nomad n’ordonnance d’ailleurs pas que des containers: il lance aussi des binaires bruts, des images de VM, des jobs Java, ce qui est exactement ce qu’il faut quand le parc n’est pas entièrement containerisé.
Consul l’accompagne pour ce que Nomad ne fait pas: la découverte de services, le DNS interne, le magasin clé-valeur et un service mesh avec mTLS par Consul Connect quand on veut chiffrer et autoriser les flux entre services. Ensemble, docker ou podman pour exécuter, Nomad pour placer, Consul pour relier, ils couvrent une large part de ce qu’on croit avoir besoin de Kubernetes pour faire, avec deux binaires qu’un humain peut tenir dans sa tête. Le compromis est franc: on n’a pas l’écosystème de k8s, ni ses opérateurs, ni son catalogue de Helm charts, ni le réservoir de gens qui le connaissent déjà. Si c’est cet écosystème qu’on vient chercher, alors c’est le vrai argument pour k8s et il faut le nommer comme tel plutôt que de se raconter qu’on a un problème d’échelle.
Ce que coûte la colle
Les étages du dessous ont pourtant un coût qu’on oublie de compter, parce qu’il ne figure sur aucune facture, celui de la colle.
Dès qu’on dépasse le docker compose up de démonstration, il faut écrire soi-même ce que Kubernetes livre d’origine et je parle d’expérience, mes propres montages Swarm ayant tous fini par traîner leur Makefile.
Un petit Makefile suffit souvent à agréger tout ça sans devenir un monstre: valider, déployer par stack, vérifier la santé des services et exécuter les smoke tests. Par exemple :
STACK ?= edge
export $(shell test -f .env && grep -v '^#' .env | xargs)
.PHONY: check up down ps smoke
check: ; docker compose -f stacks/$(PROFILE)/$(STACK)/docker-compose.yml config >/dev/null
up: ; docker stack deploy --detach=true -c stacks/$(PROFILE)/$(STACK)/docker-compose.yml $(STACK)
down: ; docker stack rm $(STACK)
ps: ; docker stack ps $(STACK) --no-trunc
smoke: ; curl -fsS https://$(STACK).example.internal/healthz || curl -fsS http://127.0.0.1:8080
Valider et fusionner les fichiers compose selon le profil et la variante TLS, passer le tout au lint, rendre les configurations depuis des templates avec envsubst, générer les secrets, initialiser le cluster et ses réseaux, déployer stack par stack, attendre en boucle que les répliques soient saines avant de lancer les smoke tests et prévoir la sauvegarde et la restauration qui vont avec.
Chacune de ces cibles est simple, mais leur somme forme un outil maison, avec ses conventions, ses bugs et sa documentation, que quelqu’un devra maintenir et que chaque nouvel arrivant devra apprendre.
Kubernetes fournit ces primitives d’origine, les probes de readiness au lieu de la boucle d’attente, les Secrets et les ConfigMaps au lieu des templates, les overlays Kustomize au lieu de la fusion de YAML, le rollout et son statut au lieu du script de déploiement.
Et surtout, il en fait un standard, puisqu’un ingénieur qui arrive connaît déjà kubectl rollout status, alors qu’il ne connaîtra jamais votre Makefile avant d’avoir passé une semaine à le lire.
Ce n’est pas un argument d’échelle, c’est un argument de maintenance et de recrutement et il mérite d’être pesé avec la même honnêteté que la taxe opérationnelle.
Le seuil où Kubernetes se justifie enfin
Il y a un moment où la réponse honnête est “oui, prends Kubernetes” et il vaut mieux le reconnaître que l’éviter par principe. C’est quand on cumule plusieurs de ces besoins réels: beaucoup d’équipes qui se partagent un parc avec un vrai multi-tenant et du RBAC fin, un besoin d’autoscaling horizontal piloté par des métriques, un écosystème d’opérateurs qu’on veut consommer, une plateforme que l’on construit pour d’autres et qui doit offrir une API standard, une colle maison devenue plus coûteuse à maintenir que le cluster à opérer ou simplement une échelle où le nombre de nœuds et de services dépasse ce qu’un humain suit à la main. À ce seuil, la taxe opérationnelle de Kubernetes cesse d’être une dépense gâchée et devient le prix d’un service qu’on utilise vraiment et c’est là que le monter proprement en HA sur bare metal prend tout son sens.
Le symptôme à fuir, c’est l’architecture pilotée par le CV, celle qui met du Kubernetes parce que c’est la ligne qu’on veut sur son profil et non parce que la charge le réclame. Ça se paie en complexité tous les jours, au bénéfice d’un seul.
Où atterrir
Un hôte et quelques services, c’est podman plus quadlet, pour que systemd supervise ce qu’il sait déjà superviser, docker-compose restant parfait pour développer.
Quelques nœuds qui veulent de la disponibilité, c’est Docker Swarm, du vrai clustering pour une fraction du coût d’exploitation et un modèle qui tient en tête.
Beaucoup de charges sur beaucoup de nœuds sans la complexité de k8s, c’est docker ou podman avec Nomad pour ordonnancer et Consul pour relier.
Et Kubernetes quand on a vraiment le multi-tenant, l’autoscaling, l’écosystème d’opérateurs ou l’échelle qui le réclament, auquel cas on le monte sérieusement.
La règle est la même à chaque étage: on choisit le niveau d’abstraction le plus bas qui règle le problème qu’on a, pas celui qui décore le mieux. Descendre coûte moins cher que de faire semblant de savoir piloter ce qu’on n’a pas le besoin de piloter.
À chaque étage aussi, il y a la possibilité de ne pas garder allumé ce qui ne sert personne: un service appelé une fois par semaine n’a aucune raison de rester chaud, c’est tout l’objet du scale-to-zero
.
[edit: 2026] mcorbin a écrit fin 2025 ce que ce billet ne faisait qu’effleurer, le premier intérêt de Kubernetes n’est pas le scaling , mais d’offrir clés en main ce qu’on passe des années à reconstruire soi-même et je le rejoins d’autant plus volontiers que mon dernier monorepo Swarm, deux profils de déploiement et dix-sept stacks, tient dans un Makefile de plus de six cents lignes. Les étages de ce billet restent valables, mais je compte désormais la colle dès le premier jour.
[edit: 2026] L’implémentation Ansible de tout ceci: le rôle k0s .