Teissier YannisDéveloppeur · IA & fullstackLyon · sept. 2026
Vue en coupe — le cluster à la maison

L'infrastructure
un cluster à la maison, tenu comme de la production

La plupart des projets de ce site sont déployés par la même chaîne, sur un petit cluster Kubernetes réparti entre un VPS loué et une machine à la maison. Cette page est la vue en coupe, ce qui tourne où, comment un commit devient un pod, et ce qui reste à l'intérieur.

Le cluster

Deux nœuds, un cluster K3s. Le VPS loué porte le plan de contrôle et est cordonné : il ne planifie rien, si bien que ses huit vCPU partagés vont à ce qui doit vivre à côté d'une adresse publique : les serveurs de jeu, qui tournent en natif hors Kubernetes à dessein, et un collecteur en lecture seule qui les observe. La machine à la maison, un bureau à 24 threads, est le seul worker et fait tourner toute la charge : une trentaine de pods au dernier comptage, avec des volumes locaux et une instance MinIO pour le stockage objet.

Les deux sont reliés par un tunnel WireGuard, environ quinze millisecondes aller-retour. Le réseau des pods ne le traverse pas, une contrainte que j'ai choisi d'assumer : tout ce dont le VPS a besoin depuis un pod passe par un port de nœud traité localement. Dix applications sont actives : un panel de supervision Minecraft, la pile de distribution d'un jeu (site, serveur de mise à jour, backend, base, cache), un registry privé, Jenkins, un service d'embeddings qui descend à zéro, MinIO, un bac à sable de ticketing, deux ou trois sites statiques, et treize autres sont archivées, charts et dumps conservés.

Fig. 1 — le cluster · le VPS porte le plan de contrôle et reçoit le trafic, le nœud maison fait tourner toute la charge01

La chaîne de livraison

Un seul dépôt git fait foi pour tout le cluster. Argo CD tourne dessus en app-of-apps, avec prune et self-heal : ce que dit le dépôt est ce qui tourne, et rien ne peut être mis en pause côté cluster. Chaque application est un petit chart Helm copié d'un modèle commenté plutôt qu'un chart tiers, si bien que chaque valeur est une valeur que j'ai écrite.

La construction se fait aussi dans le cluster. Jenkins, lui-même un chart, exécute un pipeline dans un pod pour chaque dépôt d'application : construire l'image (dans un pod, avec kaniko ou un sidecar Docker), la pousser dans le registry privé, puis cloner le dépôt d'infra, réécrire le tag d'image dans le fichier de valeurs de l'application et commiter : deploy(app): tag. Ce commit est le déploiement ; Argo le remarque, rend le chart, l'applique. Revenir en arrière, c'est un git revert. Cert-manager délivre le TLS via Let's Encrypt, KEDA endort les services peu utilisés et les réveille à la première requête HTTP, et un planificateur met des applications entières en sommeil la nuit.

Fig. 2 — d'un git push à un pod qui tourne, avec git pour seul bouton de déploiement02

Réseau, secrets et stockage

Le trafic entre par le DNS Cloudflare (proxifié pour l'HTTP, direct pour les ports de jeu), atteint le VPS en 80 et 443, est relayé par le tunnel jusqu'à Traefik en réseau hôte sur le nœud maison, puis Ingress, Service, pod. Le serveur d'API lui-même ne fait pas partie de ce chemin.

Les secrets vivent dans git, scellés : chiffrés avec la clé publique d'un contrôleur, déchiffrés uniquement dans le cluster, la clé maître gardée hors ligne et jamais sur l'un des nœuds, vingt-cinq à ce jour. Les sauvegardes sont deux tâches : un pg_dump nocturne de la base du panel, vérifié par un listing de restauration avant d'être poussé vers MinIO en rotation de quatorze copies, et les sauvegardes complètes du serveur de jeu expédiées par le tunnel via un timer systemd, écrites en local d'abord et poussées ensuite, pour que le réseau ne soit jamais sur le chemin du gel.

Fig. 3 — entrée, TLS, secrets et sauvegardes03

Ce que ça m'a appris

Trois choses qu'aucun tutoriel ne dit. Le self-heal est un engagement : retirer une application est devenu une convention du dépôt (un dossier à point, une Application supprimée, un dump, une ligne datée) parce que rien ne peut être arrêté à la main. L'ingress en réseau hôte, les services ExternalName et les exclusions de ressources d'Argo ont chacun un mode de panne silencieux, et la seule défense durable a été une liste numérotée de pièges tenue à côté du code. Et l'observabilité n'est pas gratuite : j'ai retiré Prometheus, Grafana et Loki pour rendre 1,6 Go à un serveur de jeu, mesuré que ça ne changeait rien au jeu, et j'ai maintenant un panel qui tient ses propres séries temporelles à la place. Remettre la supervision est le prochain point de la liste.