Construire un cluster Kubernetes complet
Introduction
Kubernetes est une plateforme open-source de gestion de conteneurs qui permet d’automatiser le déploiement, la mise à l’échelle et la gestion des applications conteneurisées. Installer un cluster Kubernetes chez soi peut être une excellente façon d’apprendre et de tester des applications dans un environnement contrôlé.
Personnellement, je veux mettre en place un cluster Kubernetes pour augmenter la disponibilité de mes applications hébergées et pour pouvoir intégrer de nouveaux services avec un meilleur contrôle.
Mon objectif final : Séparer clairement mes services d’entreprise (Namespace Travail) de ma domotique personnelle (Namespace Home).
Sommaire
- Prérequis
- Résumé des étapes
- Étape 1 : Configuration du réseau et des noms
- Étape 2 : Préparation système
- Étape 3 : Installation de Containerd
- Étape 4 : Installation des outils Kubernetes
- Étape 5 : Initialisation du cluster
- Étape 6 : Configuration du réseau avec Calico
- Étape 7 : Ajout des nœuds workers
- Étape 7.5 : Activation du maître comme worker
- Étape 8 : Configuration du stockage avec Longhorn
- Étape 8.5 : Ajout de disques supplémentaires
- Étape 9 : Organisation des namespaces
- Étape 10 : Création du volume persistant
- Étape 11 : Déploiement de la stack Travail
- Conclusion
Prérequis
Avant de commencer l’installation, assurez-vous d’avoir les éléments suivants :
- 3 Ordinateurs (Echo, Delta, Foxtrot dans mon cas) avec une distribution Linux (Ubuntu/Debian recommandés)
- Accès root ou sudo sur les machines
- IPs fixes configurées
- Swap désactivé sur toutes les machines
- Connexion Internet pour télécharger les paquets
Résumé des étapes
- Préparer les machines (Réseau, Swap, Kernel)
- Installer le moteur de conteneur (Containerd)
- Installer les outils Kubernetes (Kubeadm, Kubelet, Kubectl)
- Initialiser le cluster (Sur le Maître avec CIDR Calico)
- Configurer le réseau (Installation de Calico)
- Joindre les nœuds (Création du cluster complet)
- Configurer le stockage (Installation de Longhorn)
- Organiser les environnements (Travail vs Home)
- Préparer le Volume Persistant (Création du PVC partagé)
- Déployer la Stack Travail (Bases de données & Interfaces)
C’est Parti ! 🚀
Étape 1 : Le Réseau et les Noms (Fondamental)
Kubernetes déteste que les noms d’hôtes changent ou se ressemblent.
Donnez un nom unique à chaque machine
# Sur la machine maître (ex: Delta)sudo hostnamectl set-hostname bravo
# Sur les workers (ex: Echo, Foxtrot)sudo hostnamectl set-hostname alphasudo hostnamectl set-hostname foxtrotMappez les IP
Éditez le fichier /etc/hosts sur toutes les machines (sudo nano /etc/hosts). Ajoutez les IP de tout le monde :
192.168.1.10 bravo192.168.1.11 alpha192.168.1.12 foxtrotÉtape 2 : Préparation Système (Kernel & Swap)
Désactiver le Swap et charger les modules
# Désactivation immédiate swapsudo swapoff -a
# Désactivation permanente (sed commente la ligne swap dans fstab)sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
# Chargement des modules noyaucat <<EOF | sudo tee /etc/modules-load.d/k8s.confoverlaybr_netfilterEOF
sudo modprobe overlaysudo modprobe br_netfilter
# Configuration réseau (IP Forwarding requis par K8s)cat <<EOF | sudo tee /etc/sysctl.d/k8s.confnet.bridge.bridge-nf-call-iptables = 1net.bridge.bridge-nf-call-ip6tables = 1net.ipv4.ip_forward = 1EOF
# Appliquer sans redémarrersudo sysctl --systemÉtape 3 : Installer Containerd (Le moteur)
Nous utilisons le dépôt officiel de Docker pour récupérer containerd, car il est plus à jour.
Ajouter les clés et le dépôt
sudo apt-get updatesudo apt-get install -y ca-certificates curl gnupg
# Création du dossier pour les cléssudo install -m 0755 -d /etc/apt/keyrings
# Téléchargement de la clé officielle Dockercurl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpgsudo chmod a+r /etc/apt/keyrings/docker.gpg
# Ajout du dépôtecho \ "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/nullInstaller Containerd
sudo apt-get updatesudo apt-get install -y containerd.ioConfiguration CRITIQUE de Containerd
Il faut générer la config par défaut et activer SystemdCgroup pour éviter les conflits avec Kubelet.
sudo mkdir -p /etc/containerdsudo containerd config default | sudo tee /etc/containerd/config.toml
# La commande magique pour activer SystemdCgroup = true automatiquementsudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml
# On redémarre containerdsudo systemctl restart containerdÉtape 4 : Installer Kubeadm, Kubelet et Kubectl
Nous installons la version 1.29 (Stable).
Ajouter le dépôt Kubernetes
sudo apt-get updatesudo apt-get install -y apt-transport-https gpg
# Télécharger la clé publiquecurl -fsSL https://pkgs.k8s.io/core:/stable:/v1.29/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
# Ajouter le dépôtecho 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.29/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.listInstaller les paquets
sudo apt-get updatesudo apt-get install -y kubelet kubeadm kubectl
# On bloque la mise à jour automatique (pour éviter de casser le cluster lors d'un apt upgrade)sudo apt-mark hold kubelet kubeadm kubectlÉtape 5 : Initialiser le Cluster (Maître Uniquement)
Sur le serveur maître (Delta), nous allons initialiser le Control Plane.
# Initialisation avec la plage IP recommandée pour Calicosudo kubeadm init --pod-network-cidr=192.168.0.0/16Configuration de kubectl
Une fois terminé, configurez kubectl pour votre utilisateur (non-root) :
mkdir -p $HOME/.kubesudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/configsudo chown $(id -u):$(id -g) $HOME/.kube/configÉtape 6 : Installer le Réseau (Calico)
Les pods ne peuvent pas communiquer sans CNI (Container Network Interface). Nous installons Calico via l’opérateur Tigera.
# 1. Installer l'opérateur Tigerakubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.0/manifests/tigera-operator.yaml
# 2. Installer les ressources personnalisées (CRD)kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.0/manifests/custom-resources.yamlVérification
Vérifiez que les pods Calico démarrent (cela peut prendre 2-3 minutes) :
kubectl get pods -n calico-systemÉtape 7 : Ajouter les Nœuds (Workers)
Sur vos autres serveurs (Echo et Foxtrot), exécutez la commande join récupérée à l’étape 5 :
sudo kubeadm join 192.168.1.10:6443 --token <votre-token> --discovery-token-ca-cert-hash sha256:<votre-hash>Vérification
Vérifiez sur le maître que tout le monde est là :
kubectl get nodesÉtape 7.5 : Activer le Maître comme nœud de travail (Important)
Par défaut, Kubernetes “Taint” le maître pour l’empêcher d’exécuter des applications.
Si vous voulez que Longhorn utilise les disques du maître (comme votre disque sdc), il faut autoriser les workloads dessus.
# Autoriser le déploiement de pods sur le Control Planekubectl taint nodes --all node-role.kubernetes.io/control-plane-Étape 8 : Le Stockage Distribué (Longhorn)
Pour une infra “Homelab” avec de multiples disques éparpillés sur les serveurs, nous allons utiliser Longhorn.
Longhorn permet de “mutualiser” l’espace disque de tous les nœuds pour créer un stockage distribué et répliqué (Haute Disponibilité).
1. Prérequis (Sur TOUS les nœuds)
Longhorn a besoin de modules spécifiques pour fonctionner. Sans cela, les volumes ne pourront pas être montés.
sudo apt-get install -y open-iscsi nfs-commonsudo systemctl enable --now iscsid2. Installation de Longhorn (Sur le Master)
Nous appliquons le manifeste officiel.
kubectl apply -f https://raw.githubusercontent.com/longhorn/longhorn/v1.6.2/deploy/longhorn.yaml3. Vérification
Vérifiez que tous les pods sont en statut “Running” dans le namespace longhorn-system :
kubectl get pods -n longhorn-system4. Accès au Dashboard Longhorn
Par défaut, le port-forward n’écoute que sur 127.0.0.1. Si vous lancez cette commande sur le serveur maître mais que vous voulez accéder au dashboard depuis votre PC, il faut écouter sur toutes les interfaces (0.0.0.0).
# Remplacez 8083 par le port de votre choixkubectl port-forward --address 0.0.0.0 -n longhorn-system svc/longhorn-frontend 8083:80Vous pourrez ensuite accéder à http://<IP_DU_SERVEUR>:8083 pour configurer vos disques.
Étape 8.5 : Ajouter des disques physiques supplémentaires
Longhorn ne voit pas automatiquement vos autres disques. Il faut les déclarer.
Cas A : Disque déjà utilisé (Exemple: /mnt/data)
- Compatibilité : Longhorn utilise uniquement l’espace libre
- Action : Pas besoin de reformater. Assurez-vous simplement que le disque est monté
Cas B : Disque vierge (Exemple : disque sdc sur le maître)
Repérage :
lsblk # ici sdc est videFormatage :
sudo mkfs.ext4 /dev/sdcMontage :
sudo mkdir /mnt/storage-sdc
# Ajouter au fstab pour montage autoecho "/dev/sdc /mnt/storage-sdc ext4 defaults 0 0" | sudo tee -a /etc/fstabsudo mount -aConfiguration dans l’interface Web Longhorn (Pour les deux cas)
- Allez dans l’onglet Node
- Sur la ligne du serveur concerné (ex:
bravopoursdc), cliquez sur le menu (trois points) > Edit Node - Cliquez sur Add Disk
- Remplissez les champs :
- Name : Donnez un nom (ex:
sdc-500g) - Path : Le chemin de montage (ex:
/mnt/storage-sdc)
- Name : Donnez un nom (ex:
- Cliquez sur Save
Longhorn va scanner le dossier, voir l’espace disponible, et l’ajouter au pool global du cluster.
Étape 9 : Organisation (Travail & Home)
Pour séparer l’activité professionnelle de la maison, nous créons deux “Namespaces” (espaces de noms) distincts.
# Espace pour l'entreprisekubectl create namespace travail
# Espace pour la maisonkubectl create namespace homeÉtape 10 : Créer le Volume Persistant
Pour nos bases de données, nous allons créer un volume unique partagé (ce qui permet d’économiser de l’espace et de la gestion).
1. Créer le manifeste (demande de stockage)
Créez un fichier database-pvc.yaml ou appliquez directement ce contenu :
📄 Cliquez pour voir le contenu de database-pvc.yaml
apiVersion: v1kind: PersistentVolumeClaimmetadata: name: db-persistence-claim namespace: travailspec: accessModes: - ReadWriteOnce storageClassName: longhorn resources: requests: storage: 5Gi2. Appliquer la configuration
kubectl apply -f database-pvc.yaml3. Sécuriser les données (HA)
Une fois le volume créé, allez dans l’interface Web Longhorn, cliquez sur le volume, et réglez le nombre de répliques sur 3.
Cela garantit que vos données sont copiées sur vos 3 serveurs physiques, même si un serveur tombe en panne.
Étape 11 : Déploiement des Services (Stack Travail)
Voici le déploiement complet pour l’entreprise Travail. Il comprend :
- PostgreSQL (Port 5432)
- MongoDB (Port 27017)
- pgAdmin 4 (Interface graphique Postgres - Port Node 30050)
- Mongo Express (Interface graphique Mongo - Port Node 30051)
Les deux bases de données utilisent le même volume (db-persistence-claim) mais sont isolées dans des sous-dossiers (subPath).
1. Créer le fichier travail-stack.yaml
📄 Cliquez pour voir le contenu complet de travail-stack.yaml (195 lignes)
apiVersion: v1kind: Listitems: # --- 1. POSTGRESQL --- - apiVersion: v1 kind: Service metadata: name: postgres namespace: travail spec: selector: app: postgres ports: - port: 5432 targetPort: 5432
- apiVersion: apps/v1 kind: Deployment metadata: name: postgres namespace: travail spec: replicas: 1 selector: matchLabels: app: postgres template: metadata: labels: app: postgres spec: containers: - name: postgres image: postgres:15 env: - name: POSTGRES_USER value: 'admin' - name: POSTGRES_PASSWORD value: 'MonMotDePasseSuperSecurise' - name: POSTGRES_DB value: 'travail_db' ports: - containerPort: 5432 volumeMounts: - mountPath: /var/lib/postgresql/data name: shared-storage subPath: postgres volumes: - name: shared-storage persistentVolumeClaim: claimName: db-persistence-claim
# --- 2. PGADMIN 4 --- - apiVersion: v1 kind: Service metadata: name: pgadmin namespace: travail spec: type: NodePort selector: app: pgadmin ports: - port: 80 targetPort: 80 nodePort: 30050
- apiVersion: apps/v1 kind: Deployment metadata: name: pgadmin namespace: travail spec: replicas: 1 selector: matchLabels: app: pgadmin template: metadata: labels: app: pgadmin spec: containers: - name: pgadmin image: dpage/pgadmin4 env: - name: PGADMIN_DEFAULT_EMAIL value: 'admin@travail.com' - name: PGADMIN_DEFAULT_PASSWORD value: 'admin' ports: - containerPort: 80
# --- 3. MONGODB --- - apiVersion: v1 kind: Service metadata: name: mongo namespace: travail spec: selector: app: mongo ports: - port: 27017 targetPort: 27017
- apiVersion: apps/v1 kind: Deployment metadata: name: mongo namespace: travail spec: replicas: 1 selector: matchLabels: app: mongo template: metadata: labels: app: mongo spec: containers: - name: mongo image: mongo:6 env: - name: MONGO_INITDB_ROOT_USERNAME value: 'admin' - name: MONGO_INITDB_ROOT_PASSWORD value: 'MonMotDePasseMongo' ports: - containerPort: 27017 volumeMounts: - mountPath: /data/db name: shared-storage subPath: mongo volumes: - name: shared-storage persistentVolumeClaim: claimName: db-persistence-claim
# --- 4. MONGO EXPRESS --- - apiVersion: v1 kind: Service metadata: name: mongo-express namespace: travail spec: type: NodePort selector: app: mongo-express ports: - port: 8081 targetPort: 8081 nodePort: 30051
- apiVersion: apps/v1 kind: Deployment metadata: name: mongo-express namespace: travail spec: replicas: 1 selector: matchLabels: app: mongo-express template: metadata: labels: app: mongo-express spec: containers: - name: mongo-express image: mongo-express env: - name: ME_CONFIG_MONGODB_ADMINUSERNAME value: 'admin' - name: ME_CONFIG_MONGODB_ADMINPASSWORD value: 'MonMotDePasseMongo' - name: ME_CONFIG_MONGODB_SERVER value: 'mongo' - name: ME_CONFIG_BASICAUTH_USERNAME value: 'admin' - name: ME_CONFIG_BASICAUTH_PASSWORD value: 'admin' ports: - containerPort: 80812. Lancer le déploiement
kubectl apply -f travail-stack.yaml3. Accéder aux services
Vous pouvez maintenant accéder à vos outils depuis n’importe quelle machine de votre réseau :
- pgAdmin :
http://<IP_DE_VOTRE_MASTER>:30050 - Mongo Express :
http://<IP_DE_VOTRE_MASTER>:30051
Conclusion
Votre cluster est maintenant complet et taillé pour le Homelab ! 🎉
Récapitulatif
- ✅ Infrastructure : 3 nœuds (Delta, Echo, Foxtrot)
- ✅ Réseau : Calico
- ✅ Stockage : Longhorn (Distribué et HA avec disques multiples)
- ✅ Organisation : Namespaces
travailethome - ✅ Services : Bases de données Postgres et Mongo persistantes et administrables