Installation cluster K3s sur Raspberry Pi
Le projet prend forme
Tout a commencé simplement : un ami m'a offert une Raspberry Pi 4 2GB pour que je m'entraîne et acquière des compétences en infrastructure. Puis un autre ami m'a donné une Raspberry Pi 3+ 1GB pour que je découvre Home Assistant. J'ai également réussi à récupérer une Raspberry Pi 3 1GB qui traînait.
Au fur et à mesure que mes idées prenaient forme, je me suis rendu compte que ce que je voulais faire demandait un peu plus de ressources. J'ai donc investi dans une Raspberry Pi 4 8GB, et pour faire les choses proprement, j'ai acheté :
- Un dock d'alimentation (~25€) pour éviter de gaspiller des prises électriques
- Un rack à Raspberry Pi (~15€) pour organiser tout ce petit monde
Budget total investi : ~160€ (sans compter les Pi offertes/récupérées)
L'architecture finale
Mon cluster K3s se compose de 4 nœuds :
Node Master (Control Plane)
- rpi4-master - 192.168.1.51
- Raspberry Pi 4 8GB
- Rôles : control-plane, master
- Héberge l'API server, le scheduler, et etcd
Nodes Workers
- rpi4-worker - 192.168.1.50 (Raspberry Pi 4 2GB)
- rpi3-worker1 - 192.168.1.36 (Raspberry Pi 3+ 1GB)
- rpi3-worker2 - 192.168.1.15 (Raspberry Pi 3 1GB)
Tous les nœuds tournent sous Raspberry Pi OS (basé sur Debian 13 trixie) avec le kernel 6.12.47+rpt-rpi-v8 et K3s v1.28.5+k3s1.
Mon NAS QNAP (192.168.1.18) est également intégré au cluster pour fournir du stockage persistant via NFS.
Pourquoi K3s ?
K3s est une distribution Kubernetes légère parfaitement adaptée aux environnements edge, IoT, et homelab. Quelques avantages :
- Léger : Binary de ~100MB vs plusieurs GB pour Kubernetes vanilla
- Simple : Installation en une commande
- Complet : Inclut un load balancer (Traefik), un stockage local, et tout le nécessaire
- Faible empreinte mémoire : Idéal pour les Raspberry Pi avec 1-2GB de RAM
Concepts clés Kubernetes/K3s
Pour comprendre comment fonctionne le cluster, voici les concepts essentiels :
Control Plane (nœud master) :
- API Server : Point d'entrée unique pour toutes les commandes kubectl
- Scheduler : Décide sur quel nœud placer les nouveaux Pods en fonction des ressources disponibles
- etcd : Base de données clé-valeur qui stocke l'état du cluster (où sont les Pods, quelle configuration, etc.)
- Controller Manager : Surveille l'état du cluster et agit pour atteindre l'état désiré
Worker Nodes :
- Kubelet : Agent qui s'assure que les conteneurs tournent correctement
- Container Runtime : containerd dans notre cas, qui exécute les conteneurs
- Kube-proxy : Gère le réseau et les règles iptables
Ressources Kubernetes :
- Pod : Plus petite unité déployable, contient un ou plusieurs conteneurs
- Service : IP fixe pour accéder à un groupe de Pods (car les Pods peuvent être supprimés/recréés)
- Ingress : Règles de routage HTTP/HTTPS pour exposer les services à l'extérieur
- PersistentVolume (PV) : Stockage qui persiste même si le Pod est supprimé
- PersistentVolumeClaim (PVC) : Demande de stockage par une application
Préparation du réseau
Attribution d'IPs fixes
Pour un cluster stable, il est crucial d'avoir des IPs fixes pour chaque nœud. Pourquoi ?
- Le nœud master doit toujours être accessible à la même adresse (192.168.1.51:6443)
- Les workers doivent pouvoir rejoindre le master de manière fiable
- Facilite le debug et le monitoring
J'ai configuré mon routeur pour réserver :
192.168.1.51pour rpi4-master192.168.1.50pour rpi4-worker192.168.1.36pour rpi3-worker1192.168.1.15pour rpi3-worker2
Configuration réseau sur chaque Pi
Sur chaque Raspberry Pi, j'ai configuré /etc/network/interfaces :
auto eth0
iface eth0 inet static
address 192.168.1.51/24 # Adapter l'IP pour chaque nœud
gateway 192.168.1.1
dns-nameservers 192.168.1.1 8.8.8.8
Puis désactivé dhcpcd pour éviter les conflits :
sudo systemctl disable dhcpcd
sudo systemctl stop dhcpcd
sudo systemctl enable networking
sudo reboot
Préparation système
Avant d'installer K3s, quelques configurations système sont nécessaires :
1. Désactiver le swap
Kubernetes ne fonctionne pas correctement avec le swap activé. Pourquoi ?
- Le swap interfère avec la gestion mémoire des Pods
- Kubernetes veut contrôler précisément combien de RAM chaque Pod utilise
- Le swap ralentit les performances de manière imprévisible
sudo dphys-swapfile swapoff
sudo dphys-swapfile uninstall
sudo systemctl disable dphys-swapfile
2. Activer les cgroups
Les cgroups (control groups) sont essentiels pour Kubernetes car ils permettent :
- D'isoler les ressources (CPU, RAM) de chaque conteneur
- De limiter l'utilisation des ressources par Pod
- D'éviter qu'un conteneur monopolise toutes les ressources du nœud
Éditer /boot/firmware/cmdline.txt et ajouter à la fin de la ligne (sans retour à la ligne) :
cgroup_memory=1 cgroup_enable=memory
Puis redémarrer :
sudo reboot
3. Installer les dépendances
sudo apt update
sudo apt install -y curl iptables
Installation du nœud master
Sur rpi4-master (192.168.1.51), j'ai installé K3s en mode server :
curl -sfL https://get.k3s.io | sh -s - server \
--disable traefik \
--write-kubeconfig-mode 644 \
--node-ip 192.168.1.51 \
--advertise-address 192.168.1.51
Explications des options :
--disable traefik: Je désactive Traefik car j'utilise nginx-ingress-controller--write-kubeconfig-mode 644: Permet de lire le kubeconfig sans sudo--node-ip: Force l'IP du nœud (important avec des IPs fixes)--advertise-address: IP sur laquelle l'API server écoute (les workers se connecteront ici)
Récupération du token
Pour que les workers puissent rejoindre le cluster, il faut récupérer le token :
sudo cat /var/lib/rancher/k3s/server/node-token
Exemple de token :
K10abc123def456ghi789jkl012mno345pqr678stu901vwx234yz::server:abcdef1234567890
Vérification
kubectl get nodes
Résultat :
NAME STATUS ROLES AGE VERSION
rpi4-master Ready control-plane,master 2m v1.28.5+k3s1
Installation des workers
Sur chaque worker (rpi4-worker, rpi3-worker1, rpi3-worker2), j'ai exécuté :
curl -sfL https://get.k3s.io | K3S_URL=https://192.168.1.51:6443 \
K3S_TOKEN="<TOKEN_RÉCUPÉRÉ>" sh -s - agent \
--node-ip <IP_DU_WORKER>
Par exemple, sur rpi4-worker (192.168.1.50) :
curl -sfL https://get.k3s.io | K3S_URL=https://192.168.1.51:6443 \
K3S_TOKEN="K10abc123def456ghi789jkl012mno345pqr678stu901vwx234yz::server:abcdef1234567890" sh -s - agent \
--node-ip 192.168.1.50
Vérification finale du cluster
De retour sur le master :
kubectl get nodes -o wide
Résultat :
NAME STATUS ROLES AGE VERSION INTERNAL-IP OS-IMAGE
rpi4-master Ready control-plane,master 10m v1.28.5+k3s1 192.168.1.51 Raspberry Pi OS
rpi4-worker Ready <none> 5m v1.28.5+k3s1 192.168.1.50 Raspberry Pi OS
rpi3-worker1 Ready <none> 4m v1.28.5+k3s1 192.168.1.36 Raspberry Pi OS
rpi3-worker2 Ready <none> 3m v1.28.5+k3s1 192.168.1.15 Raspberry Pi OS
Le cluster est opérationnel ! 🎉
Premiers pas
Configuration kubectl en local
Pour gérer le cluster depuis mon PC, j'ai copié le kubeconfig :
# Sur le master
sudo cat /etc/rancher/k3s/k3s.yaml
Puis sur mon PC, j'ai créé ~/.kube/config en remplaçant 127.0.0.1 par 192.168.1.51.
Test avec un Pod simple
kubectl run nginx-test --image=nginx --port=80
kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-test 1/1 Running 0 10s
Nettoyage
kubectl delete pod nginx-test
Points d'attention
Limitations matérielles
Les Raspberry Pi 3 avec 1GB de RAM ont des limitations :
- Éviter de programmer des Pods gourmands sur ces nœuds
- Utiliser des
nodeSelectorounodeAffinitypour cibler les nœuds appropriés - Monitorer l'utilisation mémoire régulièrement
Surveillance du cluster
# Utilisation CPU/Mémoire des nœuds
kubectl top nodes
# Utilisation des Pods
kubectl top pods -A
Gestion de l'alimentation
Le dock d'alimentation est essentiel :
- Assure une alimentation stable pour tous les Pi
- Évite les sous-tensions qui causent des redémarrages
- Réduit l'encombrement des prises
La suite
Maintenant que le cluster est en place, voici les prochaines étapes pour construire ce homelab :
-
Migration du site web vers Docker et K3s
- Dockerisation du site statique Flask
- Premier déploiement dans K3s
-
Exposition des services du NAS QNAP
- Redirection des services externes (Plex, Passbolt, Fonas, arr-stack)
- Configuration des Endpoints manuels dans K3s
-
Accès distant avec Tailscale
- Installation sur les 4 Raspberry Pi et le PC
- Gestion du cluster depuis n'importe où avec kubectl
-
Découverte de Helm
- Premiers pas avec les Helm charts
- Templating et gestion des applications
-
Infrastructure as Code
- nginx-ingress-controller, cert-manager, NFS provisioner
- GitOps avec ArgoCD
- Gestion sécurisée des secrets avec Sealed Secrets
Le cluster K3s est la fondation de tout le homelab. Avec ces 4 Raspberry Pi et un investissement de ~160€, je dispose maintenant d'une infrastructure Kubernetes complète, prête à héberger tous mes projets !