k0s ("zero friction Kubernetes") est une distribution Kubernetes certifiée packagée en un seul binaire statique sans aucune dépendance système. Contrairement à k3s, k0s ne regroupe pas d'Ingress controller ni de provisioner de stockage par défaut : il fournit le strict minimum pour un cluster fonctionnel, laissant le choix de la stack réseau et stockage à l'opérateur.
Idéal pour : clusters multi-distribution Linux, edge computing, environnements air-gapped, automatisation via k0sctl.
Informations essentielles
Origine : Mirantis (États-Unis) · Licence : Apache 2.0 · Architectures : x86_64, ARM64, ARMv7
Liens : Site officiel · Documentation · GitHub · Releases
Support : k0s suit le cycle Kubernetes upstream - les 3 dernières versions mineures sont maintenues (~15 mois par version). La version k0s suit le schéma v1.35.3+k0s.0 (version Kubernetes + patch k0s).
Stack par défaut
| Composant | Valeur |
|---|---|
| Runtime | containerd (inclus) |
| CNI | kube-router |
| Ingress controller | Aucun (à installer séparément) |
| Stockage | Aucun (à installer séparément) |
| Base de données | SQLite/kine (nœud unique), etcd (multi-nœuds) |
| DNS | CoreDNS |
Composants embarqués
| Composant | Rôle |
|---|---|
| containerd | Runtime de conteneurs |
| kube-router | CNI (réseau pods, BGP natif) |
| CoreDNS | DNS interne cluster |
| Metrics Server | Métriques CPU/RAM |
| Konnectivity | Tunnel control plane ↔ workers |
| kine | Adaptateur SQLite/MySQL/PostgreSQL pour remplacer etcd |
Chaque composant peut être désactivé ou remplacé dans k0s.yaml. Aucun Ingress ni provisioner de stockage n'est inclus - à ajouter selon le besoin.
Prérequis
Système d'exploitation
- N'importe quel Linux 64-bit - aucun paquet OS requis
- Kernel ≥ 3.10 (4.x+ recommandé)
iptablesounftablesdisponible
Ports à ouvrir
| Port | Protocole | Nœud | Rôle |
|---|---|---|---|
| 6443 | TCP | Controller | API Kubernetes |
| 9443 | TCP | Controller | API join k0s (workers et controllers) |
| 8132 | TCP | Controller | Konnectivity (tunnel workers → control plane) |
| 10250 | TCP | Worker | kubelet (metrics) |
| 179 | TCP | Tous | kube-router BGP (inter-nœuds) |
| 2379–2380 | TCP | Controller | etcd (HA uniquement) |
Installation
Nœud unique (controller + worker)
# Télécharger et installer le binaire
curl --proto '=https' --tlsv1.2 -sSf https://get.k0s.sh | sudo sh
# Installer et démarrer en mode single
sudo k0s install controller --single
sudo k0s start
Le service systemd s'appelle k0scontroller.
--singlefusionne controller et worker dans un seul processus. Pour un cluster multi-nœuds où le controller doit aussi exécuter des workloads, utiliser--enable-workerà la place lors de l'installation du controller - équivalent du detaint Kubernetes.
Vérifier le statut
sudo systemctl status k0scontroller
sudo k0s kubectl get nodes
Configurer kubectl en local (sans sudo)
mkdir -p ~/.kube
sudo cp /var/lib/k0s/pki/admin.conf ~/.kube/config
sudo chown $(id -u):$(id -g) ~/.kube/config
# Si accès distant, remplacer 127.0.0.1 par l'IP du controller
sed -i 's/127.0.0.1/<IP_CONTROLLER>/' ~/.kube/config
kubectl get nodes
Installer une version spécifique
curl --proto '=https' --tlsv1.2 -sSf https://get.k0s.sh | \
sudo K0S_VERSION=v1.35.3+k0s.0 sh
Cluster multi-nœuds
Déploiement manuel
1. Installer le controller
# Générer la config par défaut
mkdir -p /etc/k0s && k0s config create > /etc/k0s/k0s.yaml
# Installer sans --single (workers séparés)
sudo k0s install controller -c /etc/k0s/k0s.yaml
sudo k0s start
2. Générer un token worker
# Sur le controller
sudo k0s token create --role=worker --expiry=24h > /tmp/worker-token
3. Rejoindre un worker
# Copier /tmp/worker-token sur le worker, puis :
sudo k0s install worker --token-file /path/to/worker-token
sudo k0s start
Le service worker s'appelle k0sworker.
4. Vérifier les nœuds
sudo k0s kubectl get nodes -o wide
Déploiement avec k0sctl (recommandé)
k0sctl est l'outil officiel pour déployer et gérer des clusters k0s de façon déclarative, via SSH.
Installer k0sctl
# Linux (téléchargement direct)
curl -sSLf https://github.com/k0sproject/k0sctl/releases/latest/download/k0sctl-linux-amd64 \
-o /usr/local/bin/k0sctl && chmod +x /usr/local/bin/k0sctl
# macOS
brew install k0sproject/tap/k0sctl
Déployer un cluster
# Générer un template de config
k0sctl init > k0sctl.yaml
# Éditer k0sctl.yaml avec les IPs et clés SSH des nœuds, puis :
k0sctl apply --config k0sctl.yaml
# Récupérer le kubeconfig
k0sctl kubeconfig --config k0sctl.yaml > ~/.kube/config
# Vérifier
kubectl get nodes
Template k0sctl.yaml
apiVersion: k0sctl.k0sproject.io/v1beta1
kind: Cluster
metadata:
name: mon-cluster
spec:
hosts:
- role: controller
ssh:
address: 192.168.1.10
user: root
keyPath: ~/.ssh/id_rsa
- role: worker
ssh:
address: 192.168.1.11
user: root
keyPath: ~/.ssh/id_rsa
- role: worker
ssh:
address: 192.168.1.12
user: root
keyPath: ~/.ssh/id_rsa
k0s:
version: v1.35.3+k0s.0
Configuration (k0s.yaml)
Le fichier de configuration principal se trouve dans /etc/k0s/k0s.yaml.
# Générer la config par défaut
k0s config create > /etc/k0s/k0s.yaml
# /etc/k0s/k0s.yaml
apiVersion: k0s.k0sproject.io/v1beta1
kind: ClusterConfig
metadata:
name: k0s
spec:
api:
address: 192.168.1.10 # IP du controller
port: 6443
externalAddress: 192.168.1.100 # IP du LB (HA uniquement)
sans:
- 192.168.1.10
- k0s.example.com
network:
provider: kuberouter # ou calico
podCIDR: 10.244.0.0/16
serviceCIDR: 10.96.0.0/12
storage:
type: etcd # ou kine (SQLite)
extensions:
helm:
charts:
- name: ingress-nginx
chartname: ingress-nginx/ingress-nginx
version: "4.10.0"
namespace: ingress-nginx
values: |
controller:
service:
type: NodePort
Tout changement de config nécessite un redémarrage de k0s.
Ingress
k0s n'inclut pas d'Ingress controller - à déployer selon le besoin. Un Ingress expose des Services HTTP/HTTPS via un point d'entrée unique avec routage par nom d'hôte ou chemin.
Installer ingress-nginx
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=NodePort
# Vérifier
kubectl -n ingress-nginx rollout status deployment/ingress-nginx-controller
kubectl get svc -n ingress-nginx
Sur bare-metal, le Service est de type
NodePort. Pour une IP externe stable, voir MetalLB.
Exemple de ressource Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: mon-app
namespace: production
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: app.mondomaine.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: mon-service
port:
number: 80
Gateway API est le successeur officiel des Ingress (plus expressif, multi-tenant). À considérer pour les nouveaux clusters : gateway-api.sigs.k8s.io.
Stockage persistant (PVC / StorageClass)
k0s ne fournit aucun provisioner de stockage par défaut.
local-path-provisioner (labo / single-node)
kubectl apply -f https://raw.githubusercontent.com/rancher/local-path-provisioner/master/deploy/local-path-storage.yaml
# En faire la StorageClass par défaut
kubectl patch storageclass local-path \
-p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
kubectl get storageclass
Longhorn (stockage distribué, multi-nœuds)
helm repo add longhorn https://charts.longhorn.io
helm repo update
helm install longhorn longhorn/longhorn \
--namespace longhorn-system --create-namespace
Exemple : PVC + Pod
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mon-volume
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: Pod
metadata:
name: pod-avec-volume
spec:
containers:
- name: app
image: nginx
volumeMounts:
- mountPath: /data
name: data
volumes:
- name: data
persistentVolumeClaim:
claimName: mon-volume
kubectl apply -f pvc-pod.yaml
kubectl get pvc
kubectl get pv
RBAC (contrôle d'accès)
Kubernetes utilise le RBAC (Role-Based Access Control) pour contrôler qui peut faire quoi sur le cluster. Activé par défaut dans k0s.
| Ressource | Portée | Description |
|---|---|---|
| Role | Namespace | Permissions dans un namespace donné |
| ClusterRole | Cluster | Permissions à l'échelle du cluster |
| RoleBinding | Namespace | Associe un Role à un sujet |
| ClusterRoleBinding | Cluster | Associe un ClusterRole à un sujet |
Les sujets peuvent être : User, Group, ou ServiceAccount.
Exemple : accès lecture seule sur un namespace
# role-readonly.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: production
name: readonly
rules:
- apiGroups: [""]
resources: ["pods", "services", "configmaps"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: readonly-binding
namespace: production
subjects:
- kind: User
name: alice
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: readonly
apiGroup: rbac.authorization.k8s.io
kubectl apply -f role-readonly.yaml
# Vérifier les permissions d'un utilisateur
kubectl auth can-i list pods --namespace=production --as=alice
ServiceAccount pour une application
kubectl create serviceaccount mon-app -n production
# Associer un Role existant
kubectl create rolebinding mon-app-binding \
--role=readonly \
--serviceaccount=production:mon-app \
-n production
NetworkPolicy
Par défaut, tous les pods peuvent communiquer entre eux sans restriction. Les NetworkPolicy permettent de filtrer le trafic réseau entre pods.
kube-router (CNI par défaut de k0s) supporte les NetworkPolicy nativement. Si vous avez remplacé kube-router par Calico ou Cilium, le support est identique.
Isoler un namespace (deny-all par défaut)
# deny-all.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
Autoriser uniquement le frontend vers le backend
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend
namespace: production
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
kubectl apply -f deny-all.yaml
kubectl get networkpolicy -n production
Haute disponibilité (HA)
k0s supporte le HA avec 3 ou 5 controllers (quorum etcd) et un load balancer TCP.
# Premier controller
curl --proto '=https' --tlsv1.2 -sSf https://get.k0s.sh | sudo sh
sudo k0s install controller -c /etc/k0s/k0s.yaml
sudo k0s start
# Token pour les autres controllers
sudo k0s token create --role=controller --expiry=1h > /tmp/controller-token
# Autres controllers
sudo k0s install controller \
-c /etc/k0s/k0s.yaml \
--token-file /tmp/controller-token
sudo k0s start
k0sctl gère automatiquement la distribution des certificats PKI en mode HA - recommandé pour éviter les erreurs manuelles.
Sauvegarde et restauration
# Sauvegarder (sur le controller)
sudo k0s stop
k0s backup --save-path=/tmp/
# Crée : /tmp/k0s_backup_<timestamp>.tar.gz
# Restaurer
sudo k0s stop
k0s restore /tmp/k0s_backup_<timestamp>.tar.gz
sudo k0s start
Via k0sctl :
k0sctl backup
k0sctl apply --restore-from ./k0s_backup_<timestamp>.tar.gz
Mise à jour
Règle absolue : ne jamais sauter de version mineure. Mettre à jour de v1.35 → v1.36, jamais de v1.34 → v1.36 directement.
Via k0sctl (recommandé)
Modifier la version dans k0sctl.yaml puis réappliquer :
k0s:
version: v1.36.1+k0s.0 # bumper ici
k0sctl apply --config k0sctl.yaml
k0sctl gère automatiquement l'ordre de mise à jour (controllers d'abord, puis workers).
Manuellement
# Télécharger et installer le nouveau binaire
curl --proto '=https' --tlsv1.2 -sSf https://get.k0s.sh | sudo K0S_VERSION=v1.36.1+k0s.0 sh
# Controllers en premier
sudo systemctl restart k0scontroller
# Puis chaque worker
sudo systemctl restart k0sworker
Ne pas mettre à jour plusieurs controllers simultanément en mode HA.
Mettre à jour les addons
Les composants embarqués (CoreDNS, kube-router, Metrics Server) sont mis à jour avec le binaire k0s. Les addons installés séparément sont à mettre à jour manuellement :
# ingress-nginx (si installé via Helm)
helm repo update
helm upgrade ingress-nginx ingress-nginx/ingress-nginx -n ingress-nginx
# Longhorn (si installé)
helm upgrade longhorn longhorn/longhorn -n longhorn-system
Vérifier la matrice de compatibilité de chaque addon avec la version Kubernetes cible avant de mettre à jour.
Troubleshooting
Logs du controller
sudo journalctl -u k0scontroller -f
sudo journalctl -u k0scontroller --since "10 minutes ago"
Logs d'un worker
sudo journalctl -u k0sworker -f
Inspecter un pod en erreur
kubectl describe pod <nom-pod>
kubectl logs <nom-pod>
kubectl logs <nom-pod> --previous
kubectl exec -it <nom-pod> -- /bin/sh
Pod bloqué en Pending
kubectl describe pod <nom-pod> | grep -A10 Events
kubectl top nodes
kubectl describe nodes | grep -A5 "Allocated resources"
Problèmes réseau kube-router
# Vérifier que kube-router tourne sur chaque nœud
kubectl get pods -n kube-system -l k8s-app=kube-router
# Logs kube-router
kubectl logs -n kube-system -l k8s-app=kube-router
Reset complet
sudo k0s stop
sudo k0s reset
# Recommandé : redémarrer le nœud après reset
sudo reboot
Commandes utiles
# Gestion des contextes (multi-cluster)
kubectl config get-contexts # Lister les contextes disponibles
kubectl config current-context # Contexte actif
kubectl config use-context <nom> # Changer de cluster
kubectl config set-context --current --namespace=<ns> # Namespace par défaut du contexte actif
# Fusionner plusieurs kubeconfig
KUBECONFIG=~/.kube/config:~/.kube/config-cluster2 kubectl config view --flatten > ~/.kube/config-merged
# État du cluster
sudo k0s kubectl get nodes -o wide
sudo k0s kubectl get pods -A
sudo k0s kubectl get svc -A
# Version k0s et Kubernetes
sudo k0s version
sudo k0s kubectl version
# Config active
sudo k0s config status
# Token de jointure (worker)
sudo k0s token create --role=worker --expiry=24h
# Événements du cluster
kubectl get events -A --sort-by='.lastTimestamp' | tail -20
# Port-forward
kubectl port-forward svc/<nom-service> 8080:80
# Redémarrer un deployment
kubectl rollout restart deployment/<nom>
Ressources
- Documentation officielle : https://docs.k0sproject.io
- GitHub k0s : https://github.com/k0sproject/k0s
- GitHub k0sctl : https://github.com/k0sproject/k0sctl
- Releases : https://github.com/k0sproject/k0s/releases