Introduction : Kubernetes Sans la Complexité
Kubernetes est devenu le standard de facto pour l'orchestration de conteneurs. Mais soyons honnêtes : déployer et maintenir un cluster Kubernetes « vanilla » reste une épreuve technique considérable. Entre la gestion d'etcd, les certificats TLS, le networking CNI, les composants du control plane et les innombrables fichiers de configuration, la barrière d'entrée est élevée — surtout pour les petites équipes, les environnements edge ou les homelabs.
C'est exactement le problème que K3s résout. Créé par Rancher Labs (désormais partie de SUSE), K3s est une distribution Kubernetes certifiée CNCF qui tient dans un seul binaire de moins de 100 Mo. Lancé en 2019, K3s est devenu en 2026 la distribution Kubernetes légère la plus populaire au monde, déployée sur des millions de nœuds — des Raspberry Pi aux serveurs edge en passant par les clusters de production en entreprise.
Architecture en un coup d'œil

Dans cet article, nous allons explorer K3s en profondeur : son architecture, ses différences avec Kubernetes standard, l'installation en mode single-node et multi-nodes, la haute disponibilité avec etcd embarqué, le déploiement d'applications, le monitoring, et bien plus encore.
Qu'est-ce que K3s ?
K3s est une distribution Kubernetes certifiée CNCF (Certified Kubernetes Conformant), ce qui signifie qu'elle passe tous les tests de conformité Kubernetes. Toute application compatible Kubernetes fonctionnera sur K3s sans modification.
Le nom « K3s » est un jeu de mots : si Kubernetes (K8s) a 8 lettres entre le K et le s, K3s en a seulement 3 — symbolisant sa légèreté.
Caractéristiques Principales
- Binaire unique de moins de 100 Mo contenant tout le nécessaire
- Kubernetes certifié CNCF à 100% de conformité
- Démarrage en moins de 30 secondes
- Consommation mémoire réduite : ~512 Mo de RAM pour le server, ~256 Mo pour un agent
- Batteries included : Traefik (Ingress), CoreDNS, ServiceLB (ex-Klipper), local-path-provisioner, Flannel (CNI), Helm controller
- SQLite par défaut pour le stockage (remplaçable par etcd, MySQL, PostgreSQL)
- containerd intégré comme runtime de conteneurs
- Support ARM64 et ARMv7 natif (Raspberry Pi, edge devices)
- Mises à jour automatiques possibles via system-upgrade-controller
Ce que K3s Supprime par Rapport à K8s Standard
Pour atteindre sa légèreté, K3s fait des choix opinionés :
- Drivers de stockage in-tree supprimés : Pas de drivers cloud intégrés (AWS, GCE, Azure). Utilisez les CSI drivers à la place.
- Legacy API supprimées : Les API dépréciées sont retirées plus agressivement
- etcd externe optionnel : SQLite par défaut (suffisant pour le single-node), etcd embarqué pour la HA
- Docker non inclus : containerd est le runtime par défaut (Docker peut être ajouté si nécessaire)
Architecture de K3s
L'architecture de K3s se compose de deux types de nœuds :
Server (Control Plane)
Le nœud server exécute les composants du control plane Kubernetes :
- kube-apiserver : Point d'entrée de l'API Kubernetes
- kube-scheduler : Planification des pods sur les nœuds
- kube-controller-manager : Contrôleurs Kubernetes (ReplicaSet, Deployment, etc.)
- Datastore : SQLite (défaut), etcd embarqué, ou base externe
- Tunnel proxy : Communication sécurisée entre server et agents
Par défaut, un nœud server exécute également les workloads (comme un agent). Ce comportement peut être désactivé avec le flag --node-taint.
Agent (Worker Node)
Les nœuds agent exécutent les workloads :
- kubelet : Gestion des pods sur le nœud
- kube-proxy : Gestion du networking des Services
- containerd : Runtime de conteneurs
- Flannel : CNI pour le réseau inter-pods
Composants Intégrés (Batteries Included)
| Composant | Rôle | Alternative |
|---|---|---|
| Traefik | Ingress Controller | Nginx Ingress, HAProxy |
| CoreDNS | DNS interne du cluster | — |
| ServiceLB (Klipper) | Load Balancer pour les Services de type LoadBalancer | MetalLB |
| local-path-provisioner | Provisionnement automatique de PersistentVolumes sur le disque local | Longhorn, NFS, Ceph |
| Flannel | CNI (Container Network Interface) | Calico, Cilium |
| Metrics Server | Métriques des nœuds et pods | — |
| Helm Controller | Déploiement de charts Helm via des manifestes | — |
Installation Single Node
L'installation la plus simple : un seul nœud qui fait à la fois server et agent. Idéal pour le développement, les tests, ou les petits projets.
Prérequis
- Linux (Ubuntu 20.04+, Debian 11+, RHEL/Rocky 8+, SLES 15+)
- Minimum 1 CPU, 512 Mo de RAM (2 CPU / 2 Go recommandés)
- systemd ou openrc
- Accès root ou sudo
Installation Rapide
# Installation en une seule commande
curl -sfL https://get.k3s.io | sh -
# Vérifier que K3s est démarré
sudo systemctl status k3s
# Vérifier que le cluster est opérationnel
sudo k3s kubectl get nodes
# Le kubeconfig est automatiquement créé
sudo cat /etc/rancher/k3s/k3s.yamlC'est tout. En moins de 30 secondes, vous avez un cluster Kubernetes fonctionnel avec Traefik, CoreDNS, et tout le nécessaire.
Installation Personnalisée
# Installation avec des options personnalisées
curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="server" sh -s - \
--write-kubeconfig-mode 644 \
--disable traefik \
--disable servicelb \
--flannel-backend wireguard-native \
--cluster-cidr 10.42.0.0/16 \
--service-cidr 10.43.0.0/16 \
--tls-san mon-serveur.exemple.fr \
--tls-san 192.168.1.100Quelques options notables :
--write-kubeconfig-mode 644: Rend le kubeconfig lisible sans sudo--disable traefik: Désactive Traefik (si vous préférez Nginx Ingress ou autre)--disable servicelb: Désactive le ServiceLB intégré (si vous utilisez MetalLB)--flannel-backend wireguard-native: Chiffrement WireGuard pour le trafic inter-nœuds--tls-san: Ajoute des Subject Alternative Names au certificat TLS de l'API server
Configurer kubectl
# Option 1 : Utiliser la commande k3s kubectl
sudo k3s kubectl get pods -A
# Option 2 : Configurer kubectl standard
mkdir -p ~/.kube
sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
sudo chown $(id -u):$(id -g) ~/.kube/config
export KUBECONFIG=~/.kube/config
# Vérifier
kubectl get nodes
kubectl get pods -ACluster Multi-Nodes : Server + Agents
Pour un cluster multi-nœuds simple (un server, plusieurs agents), la procédure est directe.
Sur le Server (nœud 1)
# Installer le server
curl -sfL https://get.k3s.io | sh -s - server \
--write-kubeconfig-mode 644 \
--tls-san k3s.exemple.fr \
--tls-san 192.168.1.100
# Récupérer le token pour joindre les agents
sudo cat /var/lib/rancher/k3s/server/node-token
# Exemple : K10xxxx::server:yyyySur les Agents (nœuds 2, 3, ...)
# Joindre le cluster comme agent
curl -sfL https://get.k3s.io | K3S_URL=https://192.168.1.100:6443 \
K3S_TOKEN="K10xxxx::server:yyyy" \
sh -s - agent
# Vérifier que l'agent a rejoint le cluster (depuis le server)
sudo k3s kubectl get nodes
# NAME STATUS ROLES AGE VERSION
# node-1 Ready control-plane,master 10m v1.31.4+k3s1
# node-2 Ready <none> 2m v1.31.4+k3s1
# node-3 Ready <none> 1m v1.31.4+k3s1Haute Disponibilité avec Embedded etcd
Pour la production, un seul server constitue un point de défaillance unique (SPOF). K3s supporte la haute disponibilité via etcd embarqué, nécessitant au minimum 3 nœuds server (nombre impair requis pour le consensus etcd).
Architecture HA
Le setup HA typique comprend :
- 3 nœuds server avec etcd embarqué (quorum de 3)
- N nœuds agent pour les workloads
- 1 load balancer devant les servers (HAProxy, Nginx, ou un VIP avec Keepalived)
Installation du Premier Server
# Server 1 : Initialiser le cluster avec etcd embarqué
curl -sfL https://get.k3s.io | sh -s - server \
--cluster-init \
--write-kubeconfig-mode 644 \
--tls-san k3s-vip.exemple.fr \
--tls-san 192.168.1.100 \
--tls-san 192.168.1.101 \
--tls-san 192.168.1.102 \
--node-taint CriticalAddonsOnly=true:NoExecute
# Le flag --cluster-init active etcd embarqué
# --node-taint empêche les workloads utilisateur sur les servers
# Récupérer le token
sudo cat /var/lib/rancher/k3s/server/node-tokenJoindre les Servers 2 et 3
# Server 2
curl -sfL https://get.k3s.io | K3S_TOKEN="K10xxxx::server:yyyy" sh -s - server \
--server https://192.168.1.100:6443 \
--tls-san k3s-vip.exemple.fr \
--tls-san 192.168.1.100 \
--tls-san 192.168.1.101 \
--tls-san 192.168.1.102 \
--node-taint CriticalAddonsOnly=true:NoExecute
# Server 3 (même commande, exécutée sur le 3ème nœud)
curl -sfL https://get.k3s.io | K3S_TOKEN="K10xxxx::server:yyyy" sh -s - server \
--server https://192.168.1.100:6443 \
--tls-san k3s-vip.exemple.fr \
--tls-san 192.168.1.100 \
--tls-san 192.168.1.101 \
--tls-san 192.168.1.102 \
--node-taint CriticalAddonsOnly=true:NoExecuteAjouter les Agents
# Les agents pointent vers le load balancer ou VIP
curl -sfL https://get.k3s.io | K3S_URL=https://k3s-vip.exemple.fr:6443 \
K3S_TOKEN="K10xxxx::server:yyyy" \
sh -s - agentLoad Balancer avec HAProxy
# /etc/haproxy/haproxy.cfg
frontend k3s-api
bind *:6443
mode tcp
default_backend k3s-servers
backend k3s-servers
mode tcp
balance roundrobin
option tcp-check
server server1 192.168.1.100:6443 check
server server2 192.168.1.101:6443 check
server server3 192.168.1.102:6443 checkVérifier le Cluster HA
# Vérifier les nœuds
kubectl get nodes
# NAME STATUS ROLES AGE VERSION
# server-1 Ready control-plane,etcd,master 15m v1.31.4+k3s1
# server-2 Ready control-plane,etcd,master 10m v1.31.4+k3s1
# server-3 Ready control-plane,etcd,master 8m v1.31.4+k3s1
# agent-1 Ready <none> 5m v1.31.4+k3s1
# agent-2 Ready <none> 4m v1.31.4+k3s1
# Vérifier l'état d'etcd
sudo k3s etcd-snapshot list
# Vérifier la santé du cluster etcd
curl -sL https://192.168.1.100:2379/health --cacert /var/lib/rancher/k3s/server/tls/etcd/server-ca.crt --cert /var/lib/rancher/k3s/server/tls/etcd/server-client.crt --key /var/lib/rancher/k3s/server/tls/etcd/server-client.keyInstallation avec k3sup
k3sup (prononcé « ketchup ») est un outil créé par Alex Ellis qui simplifie l'installation de K3s via SSH. Il est particulièrement utile pour provisionner rapidement un cluster depuis votre poste de travail.
# Installer k3sup
curl -sLS https://get.k3sup.dev | sh
sudo install k3sup /usr/local/bin/
# Installer K3s sur le premier server via SSH
k3sup install \
--ip 192.168.1.100 \
--user ubuntu \
--ssh-key ~/.ssh/id_ed25519 \
--cluster \
--k3s-extra-args "--disable traefik --write-kubeconfig-mode 644" \
--local-path ~/.kube/config \
--context k3s-ha
# Joindre un second server
k3sup join \
--ip 192.168.1.101 \
--user ubuntu \
--ssh-key ~/.ssh/id_ed25519 \
--server-ip 192.168.1.100 \
--server-user ubuntu \
--server \
--k3s-extra-args "--disable traefik"
# Joindre un agent
k3sup join \
--ip 192.168.1.110 \
--user ubuntu \
--ssh-key ~/.ssh/id_ed25519 \
--server-ip 192.168.1.100 \
--server-user ubuntu
# Vérifier
export KUBECONFIG=~/.kube/config
kubectl config use-context k3s-ha
kubectl get nodesOptions de Configuration Avancées
Flags Importants
| Flag | Description | Valeur par défaut |
|---|---|---|
--disable |
Désactive un composant intégré | — |
--flannel-backend |
Backend réseau Flannel | vxlan |
--cluster-cidr |
CIDR pour les pods | 10.42.0.0/16 |
--service-cidr |
CIDR pour les services | 10.43.0.0/16 |
--cluster-dns |
IP du service DNS | 10.43.0.10 |
--data-dir |
Répertoire de données K3s | /var/lib/rancher/k3s |
--node-label |
Ajouter des labels au nœud | — |
--node-taint |
Ajouter des taints au nœud | — |
--kubelet-arg |
Arguments supplémentaires pour kubelet | — |
--kube-apiserver-arg |
Arguments pour l'API server | — |
Fichier de Configuration
Au lieu de passer des flags en ligne de commande, vous pouvez utiliser un fichier de configuration YAML :
# /etc/rancher/k3s/config.yaml
write-kubeconfig-mode: "0644"
tls-san:
- "k3s.exemple.fr"
- "192.168.1.100"
cluster-init: true
disable:
- traefik
- servicelb
flannel-backend: wireguard-native
node-taint:
- "CriticalAddonsOnly=true:NoExecute"
kubelet-arg:
- "max-pods=110"
- "eviction-hard=memory.available<200Mi,nodefs.available<10%"
kube-apiserver-arg:
- "default-not-ready-toleration-seconds=30"
- "default-unreachable-toleration-seconds=30"Registres Privés
# /etc/rancher/k3s/registries.yaml
mirrors:
docker.io:
endpoint:
- "https://registry.exemple.fr"
"registry.exemple.fr":
endpoint:
- "https://registry.exemple.fr"
configs:
"registry.exemple.fr":
auth:
username: admin
password: motdepasse
tls:
insecure_skip_verify: falseDéployer une Application Complète
Déployons une application web complète avec base de données, ingress, et certificat TLS pour illustrer les capacités de K3s.
Namespace et Base de Données
# app-namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: demo-app
---
# postgres-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: postgres-secret
namespace: demo-app
type: Opaque
stringData:
POSTGRES_USER: appuser
POSTGRES_PASSWORD: S3cur3P@ssw0rd!
POSTGRES_DB: appdb
---
# postgres-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: postgres-pvc
namespace: demo-app
spec:
accessModes:
- ReadWriteOnce
storageClassName: local-path
resources:
requests:
storage: 5Gi
---
# postgres-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: postgres
namespace: demo-app
spec:
replicas: 1
selector:
matchLabels:
app: postgres
template:
metadata:
labels:
app: postgres
spec:
containers:
- name: postgres
image: postgres:16-alpine
ports:
- containerPort: 5432
envFrom:
- secretRef:
name: postgres-secret
volumeMounts:
- mountPath: /var/lib/postgresql/data
name: postgres-storage
subPath: pgdata
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
volumes:
- name: postgres-storage
persistentVolumeClaim:
claimName: postgres-pvc
---
# postgres-service.yaml
apiVersion: v1
kind: Service
metadata:
name: postgres
namespace: demo-app
spec:
selector:
app: postgres
ports:
- port: 5432
targetPort: 5432Application Web
# app-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
namespace: demo-app
spec:
replicas: 3
selector:
matchLabels:
app: web-app
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app: web-app
spec:
containers:
- name: web-app
image: nginx:alpine
ports:
- containerPort: 80
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
cpu: 200m
memory: 128Mi
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 10
periodSeconds: 10
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 5
---
# app-service.yaml
apiVersion: v1
kind: Service
metadata:
name: web-app
namespace: demo-app
spec:
selector:
app: web-app
ports:
- port: 80
targetPort: 80Ingress avec Traefik
# app-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-app-ingress
namespace: demo-app
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true"
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
tls:
- hosts:
- app.exemple.fr
secretName: web-app-tls
rules:
- host: app.exemple.fr
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-app
port:
number: 80Déployer le Tout
# Appliquer tous les manifestes
kubectl apply -f app-namespace.yaml
kubectl apply -f postgres-secret.yaml
kubectl apply -f postgres-pvc.yaml
kubectl apply -f postgres-deployment.yaml
kubectl apply -f postgres-service.yaml
kubectl apply -f app-deployment.yaml
kubectl apply -f app-service.yaml
kubectl apply -f app-ingress.yaml
# Ou en une seule commande si tout est dans un dossier
kubectl apply -f ./manifests/
# Vérifier le déploiement
kubectl get all -n demo-app
kubectl get ingress -n demo-appHelm : Le Gestionnaire de Paquets Kubernetes
# Installer Helm
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
# Ajouter des repositories
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
# Installer une application avec Helm
helm install my-wordpress bitnami/wordpress \
--namespace wordpress \
--create-namespace \
--set wordpressUsername=admin \
--set wordpressPassword=MonMotDePasse \
--set mariadb.auth.rootPassword=rootpwd \
--set persistence.size=10Gi \
--set service.type=ClusterIP
# Lister les releases Helm
helm list -AK3s inclut également un Helm Controller qui permet de déployer des charts Helm via des manifestes Kubernetes natifs, sans avoir besoin du CLI Helm :
# HelmChart CRD (spécifique à K3s)
apiVersion: helm.cattle.io/v1
kind: HelmChart
metadata:
name: prometheus
namespace: kube-system
spec:
repo: https://prometheus-community.github.io/helm-charts
chart: kube-prometheus-stack
targetNamespace: monitoring
createNamespace: true
valuesContent: |-
grafana:
adminPassword: MonGrafana2026!
ingress:
enabled: true
hosts:
- grafana.exemple.fr
prometheus:
prometheusSpec:
retention: 15d
storageSpec:
volumeClaimTemplate:
spec:
storageClassName: local-path
resources:
requests:
storage: 50GiStockage Persistant avec Longhorn
Le local-path-provisioner intégré à K3s est pratique mais limité : il stocke les données localement sur le nœud, sans réplication. Pour un stockage distribué et résilient, Longhorn (également de Rancher/SUSE) est le choix naturel.
# Installer les prérequis
sudo apt-get install -y open-iscsi nfs-common
sudo systemctl enable --now iscsid
# Installer Longhorn via Helm
helm repo add longhorn https://charts.longhorn.io
helm repo update
helm install longhorn longhorn/longhorn \
--namespace longhorn-system \
--create-namespace \
--set defaultSettings.defaultReplicaCount=2 \
--set defaultSettings.defaultDataPath=/mnt/longhorn \
--set ingress.enabled=true \
--set ingress.host=longhorn.exemple.fr
# Vérifier l'installation
kubectl get pods -n longhorn-system
kubectl get storageclassLonghorn offre :
- Réplication des données entre les nœuds (configurable de 1 à N réplicas)
- Snapshots et backups vers S3 ou NFS
- Interface web de gestion
- Disaster recovery avec restauration cross-cluster
- Expansion de volume en ligne
- Chiffrement des volumes
Ingress : Traefik vs Nginx
Traefik (Par Défaut)
K3s inclut Traefik comme Ingress Controller par défaut. C'est un choix solide avec le support automatique de Let's Encrypt, des middlewares puissants, et une interface dashboard.
Nginx Ingress Controller
Si vous préférez Nginx, désactivez d'abord Traefik puis installez Nginx Ingress :
# Si K3s est déjà installé avec Traefik, désactivez-le
# Ajoutez --disable traefik dans /etc/rancher/k3s/config.yaml
# puis redémarrez K3s
# Installer Nginx Ingress Controller
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
helm install ingress-nginx ingress-nginx/ingress-nginx \
--namespace ingress-nginx \
--create-namespace \
--set controller.service.type=LoadBalancer \
--set controller.publishService.enabled=trueCert-Manager : Certificats TLS Automatiques
# Installer cert-manager
helm repo add jetstack https://charts.jetstack.io
helm repo update
helm install cert-manager jetstack/cert-manager \
--namespace cert-manager \
--create-namespace \
--set crds.enabled=true
# Créer un ClusterIssuer Let's Encrypt
cat <<EOF | kubectl apply -f -
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: admin@exemple.fr
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- http01:
ingress:
class: traefik
EOF
# Vérifier
kubectl get clusterissuer
kubectl describe clusterissuer letsencrypt-prodMonitoring : Prometheus + Grafana
Le monitoring est essentiel pour tout cluster de production. Le stack kube-prometheus-stack fournit tout le nécessaire.
# Installer le stack complet
helm install monitoring prometheus-community/kube-prometheus-stack \
--namespace monitoring \
--create-namespace \
--set grafana.adminPassword=MonGrafana2026! \
--set prometheus.prometheusSpec.retention=30d \
--set prometheus.prometheusSpec.storageSpec.volumeClaimTemplate.spec.storageClassName=local-path \
--set prometheus.prometheusSpec.storageSpec.volumeClaimTemplate.spec.resources.requests.storage=50Gi \
--set alertmanager.alertmanagerSpec.storage.volumeClaimTemplate.spec.storageClassName=local-path \
--set alertmanager.alertmanagerSpec.storage.volumeClaimTemplate.spec.resources.requests.storage=5Gi
# Accéder à Grafana (port-forward pour test rapide)
kubectl port-forward -n monitoring svc/monitoring-grafana 3000:80
# Ou via un Ingress pour un accès permanent
cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: grafana-ingress
namespace: monitoring
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
tls:
- hosts:
- grafana.exemple.fr
secretName: grafana-tls
rules:
- host: grafana.exemple.fr
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: monitoring-grafana
port:
number: 80
EOFLe stack inclut des dashboards Grafana préconfigurés pour :
- Vue d'ensemble du cluster (CPU, RAM, réseau par nœud)
- Métriques des pods et conteneurs
- Performance de l'API server
- État de CoreDNS
- Métriques des PersistentVolumes
- Alertes préconfigurées (nœud down, disque plein, pod en CrashLoopBackOff, etc.)
Backup etcd
Pour les clusters HA avec etcd embarqué, les sauvegardes régulières sont critiques.
# Snapshot etcd manuel
sudo k3s etcd-snapshot save --name pre-upgrade-$(date +%Y%m%d)
# Lister les snapshots
sudo k3s etcd-snapshot list
# Les snapshots sont stockés dans :
ls -la /var/lib/rancher/k3s/server/db/snapshots/
# Configurer les snapshots automatiques
# Dans /etc/rancher/k3s/config.yaml :
# etcd-snapshot-schedule-cron: "0 */6 * * *" # Toutes les 6 heures
# etcd-snapshot-retention: 10 # Garder 10 snapshots
# etcd-snapshot-dir: /mnt/backup/etcd-snapshots # Répertoire custom
# Restaurer depuis un snapshot (ATTENTION : opération destructive)
sudo systemctl stop k3s
sudo k3s server \
--cluster-reset \
--cluster-reset-restore-path=/var/lib/rancher/k3s/server/db/snapshots/pre-upgrade-20260307
sudo systemctl start k3sUpgrade Rolling
K3s supporte les mises à jour via le System Upgrade Controller, qui permet des upgrades automatiques et contrôlés.
# Installer le System Upgrade Controller
kubectl apply -f https://github.com/rancher/system-upgrade-controller/releases/latest/download/system-upgrade-controller.yaml
# Attendre que le contrôleur soit prêt
kubectl get pods -n system-upgrade# Plan d'upgrade pour les servers
apiVersion: upgrade.cattle.io/v1
kind: Plan
metadata:
name: server-plan
namespace: system-upgrade
spec:
concurrency: 1
cordon: true
nodeSelector:
matchExpressions:
- key: node-role.kubernetes.io/control-plane
operator: Exists
serviceAccountName: system-upgrade
upgrade:
image: rancher/k3s-upgrade
version: v1.31.5+k3s1
---
# Plan d'upgrade pour les agents
apiVersion: upgrade.cattle.io/v1
kind: Plan
metadata:
name: agent-plan
namespace: system-upgrade
spec:
concurrency: 1
cordon: true
nodeSelector:
matchExpressions:
- key: node-role.kubernetes.io/control-plane
operator: DoesNotExist
prepare:
args:
- prepare
- server-plan
image: rancher/k3s-upgrade
serviceAccountName: system-upgrade
upgrade:
image: rancher/k3s-upgrade
version: v1.31.5+k3s1# Appliquer les plans
kubectl apply -f upgrade-plans.yaml
# Surveiller la progression
watch kubectl get nodes
kubectl get plans -n system-upgradeUpgrade Manuel
# Méthode manuelle (un nœud à la fois)
# 1. Drainer le nœud
kubectl drain node-1 --ignore-daemonsets --delete-emptydir-data
# 2. Mettre à jour K3s sur le nœud
curl -sfL https://get.k3s.io | INSTALL_K3S_CHANNEL=stable sh -
# 3. Rendre le nœud disponible
kubectl uncordon node-1
# 4. Vérifier
kubectl get nodesComparaison K3s / K0s / MicroK8s / kind
| Critère | K3s | K0s | MicroK8s | kind |
|---|---|---|---|---|
| Éditeur | SUSE/Rancher | Mirantis | Canonical | Kubernetes SIG |
| Certification CNCF | Oui | Oui | Oui | Non (dev only) |
| Taille binaire | ~70 Mo | ~170 Mo | ~200 Mo (snap) | ~10 Mo (CLI) |
| RAM minimale | 512 Mo | 1 Go | 1 Go | Selon workload |
| Installation | Script curl | Script curl | Snap | Go install |
| HA intégrée | Oui (etcd) | Oui (etcd/kine) | Oui (dqlite) | Non |
| Support ARM | Oui | Oui | Oui | Oui |
| Composants intégrés | Traefik, Flannel, CoreDNS, ServiceLB | kube-router, CoreDNS | Calico, CoreDNS, addons | kindnet, CoreDNS |
| Cas d'usage principal | Edge, IoT, prod, homelab | Edge, production | Dev, CI/CD, Ubuntu | CI/CD, tests |
| Windows support | Agents uniquement | Agents uniquement | Non (WSL2) | Oui (Docker Desktop) |
| Communauté | Très large | Moyenne | Large (Ubuntu) | Large (dev/CI) |
Quel Outil Choisir ?
- K3s : Le choix polyvalent. Parfait pour la production légère, l'edge computing, les Raspberry Pi, les homelabs, et même les environnements de développement. Son écosystème (Longhorn, Rancher, k3sup) est le plus riche.
- K0s : Alternative solide à K3s, avec un focus sur l'absence totale de dépendances système (zero friction). Bon choix pour les environnements très contraints.
- MicroK8s : Idéal si vous êtes dans l'écosystème Ubuntu/Canonical. Le système d'addons (enable/disable) est très pratique. Moins adapté au vrai edge computing.
- kind : Uniquement pour le développement local et les pipelines CI/CD. Crée des clusters éphémères dans des conteneurs Docker. Ne convient pas à la production.
Cas d'Usage de K3s
Edge Computing et IoT
K3s est la distribution Kubernetes la plus déployée en edge. Sa faible empreinte mémoire et son support ARM natif en font le choix idéal pour :
- Points de vente : Gestion d'applications retail sur des mini-PC en magasin
- Usines : Orchestration de conteneurs sur des passerelles industrielles
- Télécommunications : Déploiement de fonctions réseau virtualisées (VNF)
- Véhicules autonomes : Traitement d'images et ML embarqué
Homelab
K3s est devenu le standard de facto pour les homelabs :
- Fonctionne sur des Raspberry Pi 4/5 en cluster
- Compatible avec les mini-PC Intel N100/N305
- Parfait pour héberger des services comme Immich, Nextcloud, Home Assistant, etc.
- Facilement extensible avec Longhorn pour le stockage distribué
CI/CD
K3s est utilisé dans de nombreux pipelines CI/CD :
- Clusters éphémères pour les tests d'intégration Kubernetes
- Environnements de staging légers
- Tests de Helm charts et d'opérateurs
Production
De plus en plus d'entreprises utilisent K3s en production :
- Microservices avec des contraintes de ressources
- Clusters Kubernetes sur des VPS ou des serveurs dédiés
- Déploiements multi-régions avec des clusters K3s interconnectés
Bonnes Pratiques de Production
Sécurité
# 1. Restreindre l'accès au kubeconfig
chmod 600 /etc/rancher/k3s/k3s.yaml
# 2. Activer les audit logs
# Dans /etc/rancher/k3s/config.yaml :
# kube-apiserver-arg:
# - "audit-log-path=/var/log/k3s-audit.log"
# - "audit-log-maxage=30"
# - "audit-log-maxbackup=10"
# - "audit-policy-file=/etc/rancher/k3s/audit-policy.yaml"
# 3. Network Policies (exemple : deny all par défaut)
cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
EOF
# 4. Pod Security Standards
# Labeler le namespace avec le niveau de sécurité
kubectl label namespace production \
pod-security.kubernetes.io/enforce=restricted \
pod-security.kubernetes.io/warn=restrictedRessources et Limites
# LimitRange pour imposer des limites par défaut dans un namespace
apiVersion: v1
kind: LimitRange
metadata:
name: default-limits
namespace: production
spec:
limits:
- default:
cpu: 500m
memory: 512Mi
defaultRequest:
cpu: 100m
memory: 128Mi
type: Container
---
# ResourceQuota pour limiter les ressources totales du namespace
apiVersion: v1
kind: ResourceQuota
metadata:
name: namespace-quota
namespace: production
spec:
hard:
requests.cpu: "4"
requests.memory: 8Gi
limits.cpu: "8"
limits.memory: 16Gi
pods: "50"
persistentvolumeclaims: "10"Dépannage Courant
# Vérifier les logs du service K3s
sudo journalctl -u k3s -f
# Vérifier l'état des pods système
kubectl get pods -n kube-system
# Vérifier les événements du cluster
kubectl get events --sort-by=.metadata.creationTimestamp -A
# Problème de DNS ? Tester la résolution depuis un pod
kubectl run dns-test --image=busybox:1.36 --rm -it --restart=Never -- nslookup kubernetes.default
# Problème de networking ? Vérifier Flannel
kubectl get pods -n kube-system -l app=flannel
kubectl logs -n kube-system -l app=flannel
# Réinitialiser complètement K3s (DANGER : supprime tout)
/usr/local/bin/k3s-uninstall.sh # Sur un server
/usr/local/bin/k3s-agent-uninstall.sh # Sur un agentConclusion
K3s a fondamentalement changé la perception de Kubernetes. Ce qui était autrefois réservé aux grandes entreprises avec des équipes platform engineering dédiées est désormais accessible à un développeur seul sur un Raspberry Pi. Et pourtant, K3s ne fait aucun compromis sur la conformité : c'est du vrai Kubernetes, certifié CNCF, compatible avec l'intégralité de l'écosystème.
En 2026, K3s est la distribution Kubernetes légère la plus mature et la mieux supportée. Que vous construisiez un homelab, déployiez des applications en edge, ou cherchiez une alternative plus simple à kubeadm pour vos clusters de production, K3s mérite d'être votre premier choix.
Les points clés à retenir :
- Simplicité d'installation : Une commande curl pour un cluster fonctionnel
- Haute disponibilité : etcd embarqué pour un setup HA sans composants externes
- Batteries included : Traefik, CoreDNS, Flannel, ServiceLB — tout fonctionne out of the box
- Écosystème riche : Longhorn, Rancher, k3sup, System Upgrade Controller
- Polyvalence : Du Raspberry Pi au datacenter, du développement à la production
- 100% Kubernetes : Aucune adaptation nécessaire pour vos manifestes et Helm charts
Ressources utiles :
Site officiel K3s
Documentation K3s
GitHub K3s
k3sup
Longhorn
Rancher