From 28bc4a8c13b7c9e08e82659c18092de9f53a9247 Mon Sep 17 00:00:00 2001 From: Gitea Actions Date: Sun, 27 Sep 2026 21:13:20 +0000 Subject: [PATCH] Auto-update blog content from Obsidian: 2026-09-27 21:13:20 --- .../cover-24.webp | Bin 0 -> 35732 bytes .../index.fr.md | 129 ++++++++++++++++++ .../index.md | 11 +- 3 files changed, 135 insertions(+), 5 deletions(-) create mode 100644 content/post/24-roadmap-migrate-docker-applications-kubernetes/cover-24.webp create mode 100644 content/post/24-roadmap-migrate-docker-applications-kubernetes/index.fr.md diff --git a/content/post/24-roadmap-migrate-docker-applications-kubernetes/cover-24.webp b/content/post/24-roadmap-migrate-docker-applications-kubernetes/cover-24.webp new file mode 100644 index 0000000000000000000000000000000000000000..0b73274735720fbdab80d425c4e60accfc071322 GIT binary patch literal 35732 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 cUW+5i9m literal 0 HcmV?d00001 diff --git a/content/post/24-roadmap-migrate-docker-applications-kubernetes/index.fr.md b/content/post/24-roadmap-migrate-docker-applications-kubernetes/index.fr.md new file mode 100644 index 0000000..a265e12 --- /dev/null +++ b/content/post/24-roadmap-migrate-docker-applications-kubernetes/index.fr.md @@ -0,0 +1,129 @@ +--- +slug: roadmap-migrate-docker-applications-kubernetes +title: Roadmap pour migrer de Docker Compose vers Kubernetes +description: Pourquoi je migre mes applications auto-hébergées d'une VM Docker vers Kubernetes et comment je compte le faire prudemment. +date: 2026-09-27 +draft: true +tags: + - kubernetes + - docker +categories: + - homelab +image: cover-24.webp +--- + +## Introduction + +Depuis des années, mes applications auto-hébergées fonctionnent sous forme de conteneurs Docker gérés avec Docker Compose sur une seule machine virtuelle. Cela fonctionne suffisamment bien, ce qui rend précisément le changement un peu inconfortable. + +Je ne suis pas poussé à migrer par un incident urgent en production. Il n'y a pas de panne mystérieuse ni de matériel sur le point de prendre feu. Je veux simplement apprendre Kubernetes par la pratique et faire évoluer mon homelab vers une plateforme qui me donnera davantage de liberté pour expérimenter. + +😈 Oui, faire tourner un cluster Kubernetes dans un homelab est overkill. Je le sais. C'est aussi le but. + +Cet article présente la feuille de route de cette migration, depuis la mise en place des fondations du cluster jusqu'à la mise hors service de l'ancienne VM Docker. + +## Pourquoi Kubernetes dans un homelab + +La configuration actuelle avec Docker Compose est simple : une VM héberge les applications et Compose décrit la manière dont les conteneurs doivent fonctionner. Pour un petit environnement auto-hébergé, c'est une solution parfaitement raisonnable. + +Kubernetes ajoute une quantité considérable de complexité. Il faut prendre en compte plusieurs nœuds, un control plane, le réseau, le stockage, l'ingress, les certificats, la supervision et les sauvegardes. Je ne prétends pas qu'il s'agit de la manière la plus simple d'héberger mes services. + +La motivation est l'apprentissage. Un homelab offre un endroit sûr pour comprendre le comportement de Kubernetes, tester différentes approches et faire des erreurs sans les contraintes d'un environnement de production. Le but n'est pas de prouver que Kubernetes est meilleur que Docker Compose pour toutes les charges de travail. Le but est d'acquérir une expérience pratique de Kubernetes. + +Il y a une autre raison de faire les choses correctement : je veux rendre la plateforme reproductible. À terme, je veux pouvoir construire un cluster de validation temporaire, y tester des changements, puis reconstruire le cluster et ses applications grâce à l'automatisation avec Terraform et Ansible. + +## La stratégie de migration + +Je ne veux pas tout migrer en une seule opération massive. Cela rendrait le troubleshooting inutilement difficile et transformerait chaque petite erreur en potentielle interruption de service. + +À la place, je découpe le travail en plusieurs étapes. Chaque étape ajoute une capacité importante à la plateforme avant d'y déplacer le groupe d'applications suivant. + +Le cluster Kubernetes lui-même est d'abord bootstrapé manuellement. C'est volontaire. Avant d'automatiser le processus, je veux comprendre ce qui se passe lors de la création du cluster et du déploiement des applications. GitOps fait partie de l'objectif final, mais je le repousse à plus tard afin de pouvoir d'abord expérimenter la plateforme sans dissimuler le processus de déploiement derrière une couche d'automatisation supplémentaire. + +## Étape 1 : construire les fondations du cluster + +La première étape consiste à créer l'infrastructure sur laquelle Kubernetes fonctionnera. Je l'ai déjà fait il y a quelques mois dans [cet article]({{< ref "post/8-create-manual-kubernetes-cluster-kubeadm" >}}), mais cette fois je vais pousser l'automatisation un peu plus loin. + +Je prévois d'utiliser Terraform pour provisionner les machines virtuelles des nœuds Kubernetes. Ansible préparera ensuite ces VMs. Le bootstrap initial du cluster et l'installation de la Container Network Interface seront effectués manuellement. + +Cette approche permet de séparer clairement les responsabilités : + +- Terraform crée les machines. +- Ansible prépare les systèmes d'exploitation. +- Le premier bootstrap Kubernetes reste manuel pour le moment. + +Les fondations du cluster doivent être fiables avant d'y ajouter les applications. Si les nœuds et le réseau ne sont pas sains, déboguer un déploiement applicatif devient une manière particulièrement créative de gâcher une soirée. + +## Étape 2 : ajouter le point d'entrée + +Une fois le cluster en place, il doit pouvoir recevoir du trafic. L'étape suivante concerne donc l'API gateway et la gestion des certificats. + +Je vais déployer une API gateway et `cert-manager`, puis une première application pour vérifier que l'ensemble du chemin fonctionne. Cette première application ne représente pas une migration complète. C'est un test de la plateforme : est-il possible de déployer une application, d'y accéder depuis l'extérieur du cluster et de la sécuriser avec un certificat ? + +Cette étape est importante car elle valide davantage que le scheduling Kubernetes. Elle teste l'intégration entre le cluster, le réseau, l'accès externe et TLS. + +## Étape 3 : stockage, sauvegardes et supervision + +Avant de migrer quoi que ce soit d'important, je dois comprendre ce qui arrive aux données. + +Le plan consiste à définir des storage classes pour les stockages Ceph et TrueNAS. J'ai également besoin d'une configuration de supervision de base et d'une stratégie de sauvegarde pour le cluster. + +C'est à ce moment que le projet cesse de se limiter à faire tourner des conteneurs. Les workloads stateless sont relativement simples à déplacer. Les applications stateful nécessitent de décider où leurs données seront stockées, comment elles seront sauvegardées et comment le service pourra être restauré après une panne. + +Je ne veux pas découvrir que la stratégie de sauvegarde est incomplète après avoir déplacé les applications qui comptent le plus. + +## Étapes 4 à 6 : migrer progressivement les applications + +Une fois les capacités de la plateforme en place, les applications peuvent être déplacées par groupes, selon leur niveau de risque. + +### Applications à faible risque + +Les premières migrations concerneront des applications stateless. Elles sont les meilleures candidates pour valider le processus de déploiement, car elles ne contiennent pas de données critiques et devraient être plus faciles à recréer. + +### Applications à risque moyen et stateful + +Viendront ensuite les services non vitaux et les applications dont les besoins en stockage sont plus complexes. Ces migrations aideront à valider les storage classes, les sauvegardes et les procédures de récupération dans des conditions plus réalistes. + +### Applications critiques + +Les applications vitales arriveront en dernier. À ce moment-là, le cluster aura déjà été éprouvé avec des workloads moins importants et les fondations de la supervision et des sauvegardes devraient être plus matures. + +Cet ordre est volontairement prudent. La migration est aussi un projet d'apprentissage, mais je n'ai pas besoin de transformer chaque leçon en interruption de service. + +## Étape 7 : améliorer la supervision et la reprise après sinistre + +Une fois les applications migrées, la solution de supervision et de sauvegarde devra être revue. + +La configuration initiale est une base, pas un état final. L'objectif est de tendre vers une solution de supervision plus complète et de mettre en place un plan de reprise après sinistre. Un cluster peut sembler sain tout en étant difficile à restaurer, c'est pourquoi le processus de récupération doit être considéré séparément de la supervision quotidienne. + +## Étape 8 : automatiser le cycle de vie du cluster + +L'étape importante suivante consiste à rendre la plateforme temporaire et reconstructible. + +Je veux pouvoir créer un cluster de validation depuis zéro et reconstruire de manière fiable le cluster ainsi que ses applications. Terraform et Ansible seront utilisés pour automatiser ce processus. + +C'est ici que le travail manuel réalisé au début devrait porter ses fruits. En comprenant d'abord les étapes, je peux automatiser un processus que je maîtrise réellement au lieu de convertir aveuglément des commandes en playbooks. + +## Étape 9 : introduire GitOps + +Je n'introduirai GitOps qu'une fois la plateforme et l'automatisation de son cycle de vie opérationnelles. + +Le repository sera réorganisé pour prendre en charge ce mode de fonctionnement, avec l'état souhaité du cluster et des applications géré dans Git. L'objectif est de permettre un déploiement complet du cluster conforme à la stratégie GitOps. + +GitOps est la destination, pas la ligne de départ. L'introduire trop tôt rendrait la première phase d'apprentissage plus difficile, notamment alors que l'architecture du cluster et les méthodes de déploiement des applications sont encore amenées à évoluer. + +## Étape 10 : mettre la VM Docker hors service + +La dernière étape ne prendra pas la forme d'un arrêt brutal. Je veux arrêter la VM Docker pendant un certain temps tout en faisant fonctionner les applications sur Kubernetes. Si tout reste stable et que la nouvelle plateforme se montre fiable, je pourrai finalement détruire l'ancienne VM. + +Conserver l'ancien environnement pendant la transition fournit un filet de sécurité. Cela donne aussi une définition claire de la fin du projet : la migration n'est pas terminée simplement parce qu'une application démarre dans Kubernetes. Elle sera terminée lorsque j'aurai suffisamment confiance pour supprimer la plateforme précédente. + +## Conclusion + +🚀 C'est le plus grand projet de homelab que j'ai planifié jusqu'à présent, et probablement aussi le plus passionnant. + +L'objectif technique est de migrer des applications auto-hébergées depuis une VM Docker Compose unique vers un cluster Kubernetes. L'objectif le plus important est d'apprendre à concevoir, exploiter, automatiser, superviser, sauvegarder et finalement reconstruire cette plateforme. + +La feuille de route progresse de la compréhension vers la migration, puis de la migration vers l'automatisation. Je commence par un cluster manuel, j'ajoute le réseau et le stockage, je migre les applications selon leur niveau de risque, j'améliore la récupération, j'automatise le cycle de vie et je termine avec GitOps. + +🔥 Cela représente beaucoup de travail pour un homelab. C'est précisément pour cela que ce projet devrait être une formidable occasion d'apprendre. diff --git a/content/post/24-roadmap-migrate-docker-applications-kubernetes/index.md b/content/post/24-roadmap-migrate-docker-applications-kubernetes/index.md index b15b50f..d29b382 100644 --- a/content/post/24-roadmap-migrate-docker-applications-kubernetes/index.md +++ b/content/post/24-roadmap-migrate-docker-applications-kubernetes/index.md @@ -9,6 +9,7 @@ tags: - docker categories: - homelab +image: cover-24.webp --- ## Intro @@ -31,7 +32,7 @@ The motivation is learning. A homelab gives me a safe place to understand how Ku There is another reason for doing this properly: I want the platform to become reproducible. Eventually, I want to build a disposable validation cluster, test changes there, and rebuild the cluster and its applications through automation using Terraform and Ansible. -## The migration strategy +## The Migration Strategy I do not want to migrate everything in one massive operation. That would make troubleshooting needlessly difficult and would turn every small mistake into a potential service outage. @@ -41,7 +42,7 @@ The Kubernetes cluster itself is being bootstrapped manually at first. This is i ## Milestone 1: Build the cluster foundation -The first step is to create the infrastructure on which Kubernetes will run. +The first step is to create the infrastructure on which Kubernetes will run. I've done that months ago in that [article]({{< ref "post/8-create-manual-kubernetes-cluster-kubeadm" >}}), this time I'll automate it a bit further. I plan to use Terraform to provision the virtual machines for the Kubernetes nodes. Ansible will then prepare those VMs. The initial cluster bootstrap and the installation of the Container Network Interface will be performed manually. @@ -49,7 +50,7 @@ This approach gives me a useful separation: - Terraform creates the machines. - Ansible prepares the operating systems. -- The first Kubernetes bootstrap remains manual for learning purposes. +- The first Kubernetes bootstrap remains manual for now. The cluster foundation needs to be reliable before applications become part of the picture. If the nodes and network are not healthy, debugging an application deployment becomes a particularly creative way of wasting an evening. @@ -119,10 +120,10 @@ Keeping the old environment available during the transition provides a safety ne ## Conclusion -This is the biggest homelab project I have planned so far, and probably the most exciting one too. +🚀 This is the biggest homelab project I have planned so far, and probably the most exciting one too. The technical goal is to migrate self-hosted applications from a single Docker Compose VM to a Kubernetes cluster. The more important goal is to learn how to design, operate, automate, monitor, back up, and eventually rebuild that platform. The roadmap deliberately moves from understanding to migration, then from migration to automation. I start with a manual cluster, add networking and storage, migrate applications by risk, improve recovery, automate the lifecycle, and finish with GitOps. -It is a lot of work for a homelab. That is exactly why it should be a great learning project. +🔥 It is a lot of work for a homelab. That is exactly why it should be a great learning project.