Article principal · Ce tutoriel fait partie de la série Kubernetes domestique sur Proxmox VE. Tutoriel précédent : Provisionner des VM Talos Linux. Tutoriel suivant : Cilium CNI eBPF.
Avant d installer Kubernetes sur les six VM créées au tutoriel précédent, une décision technique structure tout le reste du parcours : choisir la distribution Kubernetes. Deux options dominent l usage domestique en mai 2026 : kubeadm, l outil officiel du projet Kubernetes, qui produit un cluster « standard » identique à ce qu on retrouve en entreprise ; et k3s, la distribution allégée portée par SUSE, packagée en un binaire de moins de 100 Mio. Ce tutoriel pas-à-pas démonte les compromis techniques entre les deux et installe successivement les deux distributions sur Talos pour comparer le résultat sur le même matériel.
Étape 1 — Comprendre ce que kubeadm fait réellement
kubeadm est un outil de bootstrap Kubernetes maintenu par le projet upstream. Sa mission est de transformer un Linux nu en nœud Kubernetes conforme aux spécifications du projet. Il ne fournit ni CNI, ni stockage, ni Ingress, ni metrics-server : ces choix sont laissés à l opérateur. C est précisément ce qui en fait l outil de référence pour comprendre Kubernetes en profondeur.
# Sur un nœud Ubuntu 24.04 (hors Talos), installation kubeadm 1.35
sudo apt update
sudo apt install -y apt-transport-https ca-certificates curl gpg
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.35/deb/Release.key | \
sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] \
https://pkgs.k8s.io/core:/stable:/v1.35/deb/ /" | \
sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt update
sudo apt install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
sudo kubeadm init --pod-network-cidr=10.244.0.0/16 \
--control-plane-endpoint=192.168.1.60:6443 --upload-certs
La sortie de kubeadm init affiche les commandes kubeadm join à exécuter sur les autres nœuds, valides 24 heures. À ce stade, le cluster est démarré mais incomplet : les pods CoreDNS sont en Pending parce qu aucun CNI n est installé. C est volontaire : kubeadm ne décide pas pour vous.
Sur Talos, kubeadm est invisible parce que c est Talos qui le pilote en interne au démarrage, mais le résultat est identique : un cluster Kubernetes upstream complet et conforme à la spec.
Étape 2 — Comprendre ce que k3s fait à la place
k3s prend l approche inverse. C est un binaire unique de moins de 100 Mio qui contient le control plane (kube-apiserver, kube-controller-manager, kube-scheduler), kubelet, containerd, Flannel CNI, Traefik Ingress controller, ServiceLB, local-path-provisioner et metrics-server. Il remplace etcd par défaut par SQLite, ce qui simplifie radicalement le démarrage mais bride la haute disponibilité. La version testée ici est v1.35.4+k3s1, sortie en avril 2026.
# Premier serveur k3s avec etcd embarqué (HA possible)
curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION=v1.35.4+k3s1 sh -s - server \
--cluster-init --token=monsecretpartage --tls-san=192.168.1.60
# Serveurs additionnels rejoignant le cluster
curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION=v1.35.4+k3s1 sh -s - server \
--server=https://192.168.1.61:6443 --token=monsecretpartage
# Récupérer le kubeconfig
sudo cat /etc/rancher/k3s/k3s.yaml
# Remplacer 127.0.0.1 par l IP du serveur dans la copie locale
En moins d une minute, le cluster est utilisable de bout en bout : kubectl get nodes retourne les nœuds Ready, kubectl get svc -A liste Traefik et ServiceLB déjà là, kubectl get sc affiche local-path comme classe de stockage par défaut. C est la promesse de k3s : démarrer vite et tester immédiatement.
Étape 3 — Comparer empreinte mémoire et démarrage
Sur le matériel domestique, la consommation mémoire des composants système est un critère pratique. La mesure suivante a été refaite en mai 2026 sur deux VM identiques (4 vCPU, 4 Gio RAM, Talos 1.13 ou Ubuntu 24.04, charge utile vide).
| Composant | kubeadm + Talos | k3s sur Ubuntu |
|---|---|---|
| Mémoire système au repos | 1,5 Gio | 520 Mio |
| Temps de démarrage du cluster | 3 min (bootstrap + nœuds joints) | 45 s |
| Taille de l image disque | 2,4 Gio | 1,1 Gio |
| CPU au repos (1 nœud, charge vide) | 3 à 5 % | 1 à 2 % |
| CNI inclus | Aucun (Cilium ajouté ensuite) | Flannel (remplaçable) |
| Ingress inclus | Aucun | Traefik 3.6 |
| Stockage par défaut | Aucun | local-path-provisioner |
Pour un nœud à 4 Gio de RAM, k3s laisse 3,4 Gio libres aux pods, kubeadm en laisse environ 2,5 Gio. Sur un Raspberry Pi 5 à 8 Gio, la différence devient anecdotique. Sur un mini-PC à 32 Gio dédié au cluster, elle ne se voit même plus dans le quotidien.
Étape 4 — Comparer la haute disponibilité
kubeadm utilise etcd nativement et supporte sans effort un quorum à 3 ou 5 membres. C est ce qu on attend d un cluster d entreprise. La perte d un control plane n arrête pas le cluster ; la perte de deux sur trois oui, parce qu etcd perd alors le quorum.
k3s permet trois modes de stockage du state : SQLite embarqué (par défaut, pas de HA), etcd embarqué (avec --cluster-init, HA jusqu à 5 nœuds, ce qu on a configuré ci-dessus), ou base externe MySQL/Postgres/etcd externe. Pour un usage domestique sérieux, le mode etcd embarqué de k3s est une excellente option : on garde la simplicité d installation tout en obtenant la HA.
# Vérifier que l etcd embarqué de k3s est sain
sudo k3s etcd-snapshot list
# Comparer avec etcd kubeadm
sudo ETCDCTL_API=3 etcdctl \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key \
endpoint status --write-out=table
Les deux sorties confirment un quorum à 3 membres opérationnel. Concrètement, les deux distributions résistent à la perte d un nœud control plane sans interruption de l API server, ce qui est l objectif principal en homelab sérieux.
Étape 5 — Choisir selon le profil d usage
Trois profils-types se dégagent de l expérience accumulée par la communauté homelab :
Profil « apprentissage et expérimentation » : k3s gagne. Démarre vite, tient sur une VM modeste, livre tout-en-un. Idéal pour itérer sur des manifestes, tester un opérateur Helm, comprendre les concepts. Les développeurs qui veulent un cluster jetable choisissent k3s sans hésiter.
Profil « plateforme stable que je veux faire ressembler à de la production » : kubeadm gagne. La conformité upstream est totale, les comportements sont identiques à ce qu on retrouve sur EKS, AKS ou GKE, l écosystème d outils (kubectl plugins, opérateurs, tutoriels) est testé contre kubeadm. Sur Talos, la combinaison Talos+kubeadm est aujourd hui la référence pour qui veut un cluster homelab maintenable des années.
Profil « cluster ARM ou très contraint » : k3s gagne sur les Raspberry Pi 5, les Banana Pi, les nœuds avec 2 Gio de RAM. Il existe même une version k3s-armhf pour les vieux Pi 32 bits. kubeadm fonctionne aussi mais l overhead pèse plus lourd en proportion sur ces machines.
Pour le parcours de cette série, on recommande Talos+kubeadm parce que la suite (Cilium, Rook-Ceph, Argo CD, Velero) est rigoureusement identique aux configurations d entreprise. Mais tout ce qui suit est réalisable sur k3s avec quelques ajustements (désactivation de Flannel et Traefik intégrés via les flags --flannel-backend=none --disable=traefik avant d installer Cilium).
Étape 6 — Vérifier le résultat sur les deux clusters
Quelle que soit l option retenue, la vérification finale est la même : un cluster Ready, des pods système qui tournent, le DNS qui fonctionne, l API qui répond depuis le poste de travail.
kubectl get nodes -o wide
kubectl get pods -A
kubectl run test --image=busybox --rm -it --restart=Never -- nslookup kubernetes.default
# Doit résoudre vers une adresse 10.96.0.x
Voir le pod test se créer, résoudre le service kubernetes.default et se supprimer après la commande confirme que le control plane, le kubelet et le DNS interne fonctionnent ensemble. C est le critère minimal de validité d un cluster Kubernetes.
Erreurs fréquentes et résolutions
| Symptôme | Cause | Résolution |
|---|---|---|
kubeadm init échoue sur swap activé |
Le kubelet 1.35 refuse swap par défaut | swapoff -a et commenter swap dans /etc/fstab |
| k3s server refuse de démarrer (port 6443 occupé) | Un autre kube-apiserver tourne déjà | sudo systemctl status k3s et nettoyer l ancienne installation avec k3s-uninstall.sh |
Les pods restent en Pending après kubeadm init |
CNI non installé | Installer Cilium (tutoriel suivant) |
| k3s fonctionne mais Traefik ne crée pas d IP externe | ServiceLB désactivé ou MetalLB conflictuel | Vérifier kubectl get svc -A et la présence du DaemonSet svclb-traefik |
| kubectl indique The connection was refused depuis le poste | kubeconfig pointe sur 127.0.0.1 (cas k3s) | Remplacer 127.0.0.1 par l IP réelle du serveur dans le kubeconfig copié |
Pour la suite du parcours
La distribution Kubernetes est choisie. Quelle que soit la décision (kubeadm sur Talos comme dans nos exemples, ou k3s pour la légèreté), la prochaine étape consiste à installer le CNI : sans réseau de pods, le cluster ne peut pas faire grand-chose. Le tutoriel Déployer Cilium CNI avec eBPF sur Kubernetes détaille l installation et l activation de Hubble pour l observabilité réseau. Pour la vue d ensemble, retourner au guide principal Kubernetes domestique sur Proxmox VE.
Ressources et documentation officielle
- Documentation kubeadm : kubernetes.io/docs/setup
- Documentation k3s : docs.k3s.io
- Notes de version k3s v1.35.X : docs.k3s.io/release-notes
- Procédure de mise à niveau kubeadm : kubernetes.io/docs/tasks/administer-cluster
- Comparatif officiel des distributions Kubernetes (CNCF) : cncf.io
Étape 7 — Comparer la sécurité par défaut
La posture sécurité par défaut diffère sensiblement entre les deux distributions, et ce point est rarement abordé. kubeadm produit un cluster « nu » : Pod Security Admission est disponible mais non configuré, RBAC fonctionne mais les comptes system:masters ne sont pas restreints, l API server expose ses metrics anonymes. Il faut durcir activement après installation. C est cohérent avec la philosophie kubeadm : faire les choix en connaissance.
k3s a un comportement plus opinionné. Le profil de sécurité par défaut active automatiquement la rotation des certificats kubelet, désactive les ports non chiffrés, et peut activer le profil cis-1.6 via un flag (--profile=cis-1.6) qui applique une partie des recommandations CIS Kubernetes. La contrepartie est moins de visibilité sur ce qui se passe : k3s « cache » des choix qu un opérateur kubeadm voit explicitement.
# k3s ne dispose pas de flag --profile=cis (contrairement à RKE2). Suivre le hardening guide officiel docs.k3s.io/security/hardening-guide pour appliquer manuellement les contrôles CIS Kubernetes Benchmark v1.11 (ou plus récent).
# Vérifier sur kubeadm que Pod Security Admission est actif (PodSecurity est GA depuis K8s 1.25, pas de feature-gate à activer)
kubectl label namespace demo \
pod-security.kubernetes.io/enforce=restricted \
pod-security.kubernetes.io/audit=restricted \
pod-security.kubernetes.io/warn=restricted
Sur les deux clusters, on appliquera ensuite OPA Gatekeeper ou Kyverno pour les politiques métier. Mais le point de départ n est pas équivalent : k3s est plus durci par défaut, kubeadm donne plus de contrôle.
Étape 8 — Comparer le cycle de vie et les mises à jour
La maintenance dans le temps est un coût qu on sous-estime souvent au démarrage. Les deux distributions adoptent la cadence Kubernetes (une mineure tous les quatre mois) mais avec des outillages différents.
Sur kubeadm, la procédure de mise à niveau est documentée mais demande une attention soutenue : sauvegarder etcd, monter les paquets kubeadm, exécuter kubeadm upgrade plan puis kubeadm upgrade apply sur le premier control plane, puis répéter sur les autres, puis sur les workers en mode drain/upgrade/uncordon. Compter une à deux heures par mineure pour un cluster de six nœuds, sans incident.
# Mise à niveau kubeadm 1.35.4 → 1.36.0 sur le premier control plane
sudo apt update
sudo apt-mark unhold kubeadm
sudo apt install -y kubeadm=1.36.0-00
sudo apt-mark hold kubeadm
sudo kubeadm upgrade plan
sudo kubeadm upgrade apply v1.36.0
# Puis kubelet et kubectl
sudo apt-mark unhold kubelet kubectl
sudo apt install -y kubelet=1.36.0-00 kubectl=1.36.0-00
sudo apt-mark hold kubelet kubectl
sudo systemctl daemon-reexec
sudo systemctl restart kubelet
Sur k3s, la mise à niveau est radicalement plus simple : on relance le script d installation avec la nouvelle version. k3s gère la migration etcd, la rotation des manifestes intégrés, et le redémarrage du service.
# Mise à niveau k3s vers v1.36.0+k3s1
curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION=v1.36.0+k3s1 sh -
# Vérifier la version après upgrade
sudo k3s --version
kubectl get nodes -o wide
Sur Talos+kubeadm, la mise à niveau est encore différente : talosctl upgrade-k8s orchestre tout, depuis l upgrade du control plane jusqu aux workers, en respectant les drain et les health checks. C est probablement le compromis le plus confortable des trois en mai 2026.
Étape 9 — Tester la résilience à la perte d un nœud
Avant de déclarer le cluster prêt, on vérifie qu il survit à un événement défavorable courant : la perte d un nœud control plane. Le test consiste à éteindre brutalement un nœud et observer que l API reste disponible.
# Sur Proxmox, éteindre brutalement le second control plane
qm stop 1002
# Depuis le poste de travail, vérifier que kubectl répond toujours
kubectl get nodes
# Le nœud arrêté apparaît en NotReady, les autres restent Ready
# L API répond car le quorum etcd est maintenu (2 sur 3)
kubectl get pods -A
# Aucun pod système n est impacté
# Redémarrer le nœud
qm start 1002
sleep 60
kubectl get nodes
# Le nœud rejoint le cluster en quelques minutes
Voir les commandes kubectl répondre malgré la VM éteinte confirme que la haute disponibilité fonctionne. Si l API devient injoignable dès qu un nœud tombe, c est que etcd n est pas en HA — typique d un k3s lancé sans --cluster-init, ou d un kubeadm avec un seul control plane. Reprendre la configuration HA avant d aller plus loin.
Questions qui reviennent souvent
Peut-on migrer un cluster k3s vers kubeadm sans tout reconstruire ? Pas directement. Les deux distributions stockent leur state dans etcd avec des conventions de noms et des CRD différentes. Une migration en place n est pas supportée. La pratique est de reconstruire le cluster cible et de migrer les charges via Velero (sauvegarde du cluster source, restauration sur le cluster cible).
Faut-il vraiment trois control plane sur k3s ou peut-on rester à un seul ? Pour apprendre, un seul suffit. Pour héberger des services qu on veut faire tourner pendant les pannes ou les mises à jour, trois est le minimum. La VM control plane consomme 512 Mio de RAM en k3s : multiplier par trois reste raisonnable même sur un mini-PC à 32 Gio.
k3s en production, c est sérieux ou bricolé ? SUSE supporte k3s commercialement, et de nombreux déploiements edge en production tournent sur k3s (ex. infrastructure de bornes de recharge, domotique industrielle). Pour un homelab, c est un excellent choix qui ne sera pas remis en cause par la maturité du projet.
Le choix peut-il être différent par cluster ? Absolument. Beaucoup d opérateurs domestiques ont un k3s pour le bac à sable et un Talos+kubeadm pour les services à haute disponibilité. Les deux clusters partagent souvent un même Argo CD qui pousse les manifestes appropriés à chacun. C est même un excellent exercice pour comprendre les patterns multi-cluster.