Orchestration

k3s

Distribution Kubernetes légère par Rancher/SUSE. Un seul binaire sous 100 MB, 512 MB RAM minimum, démarrage en 30 secondes. Idéal pour edge, IoT, CI/CD et ARM.

k3s est une distribution Kubernetes certifiée, packagée en un seul binaire de moins de 100 MB. Développée par Rancher (SUSE), elle embarque tout le nécessaire : containerd, Flannel, CoreDNS, Traefik, metrics-server, local-path-provisioner. Compatible 100 % avec l'API Kubernetes standard.

Idéale pour : edge computing, IoT, CI/CD, développement local, clusters ARM.


Informations essentielles

Origine : Rancher / SUSE  ·  Licence : Apache 2.0  ·  Architectures : x86_64, ARM64, ARMv7

Liens : Site officiel  ·  Documentation  ·  GitHub

Stack par défaut

ComposantValeur
Runtimecontainerd (inclus)
CNIFlannel
Ingress controllerTraefik
Stockagelocal-path-provisioner
Base de donnéesSQLite (défaut), etcd, MySQL, PostgreSQL

Composants embarqués

k3s intègre tout ce qu'il faut pour un cluster fonctionnel sans installation supplémentaire :

ComposantRôle
containerdRuntime de conteneurs
FlannelCNI (réseau pods)
CoreDNSDNS interne cluster
TraefikIngress controller
metrics-serverMétriques CPU/RAM
local-path-provisionerVolumes persistants locaux
kube-proxyProxy réseau
Helm controllerDéploiement de charts Helm natif

Chaque composant peut être désactivé individuellement avec --disable <composant>.


Prérequis

Système d'exploitation

  • Linux 64-bit : Ubuntu 20.04+, Debian 11+, RHEL/CentOS 8+, Raspberry Pi OS
  • Kernel ≥ 4.0
  • iptables ou nftables disponible

Ports à ouvrir

PortProtocoleRôle
6443TCPAPI server Kubernetes
10250TCPkubelet (metrics)
8472UDPFlannel VXLAN (inter-nœuds)
51820UDPFlannel WireGuard (si activé)
2379-2380TCPetcd (HA uniquement)

Désactiver le swap (recommandé)

sudo swapoff -a
# Rendre permanent
sudo sed -i '/ swap / s/^/#/' /etc/fstab

Installation

Nœud server (master) - installation rapide

curl -sfL https://get.k3s.io | sh -

Le script installe k3s, crée un service systemd k3s et le démarre automatiquement.

Vérifier le statut

sudo systemctl status k3s
sudo k3s kubectl get nodes

Configurer kubectl en local (sans sudo)

mkdir -p ~/.kube
sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
sudo chown $(id -u):$(id -g) ~/.kube/config
chmod 600 ~/.kube/config

# Vérification
kubectl get nodes

Installer une version spécifique

curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION="v1.30.2+k3s1" sh -

Installation sans Traefik ni servicelb (cluster nu)

curl -sfL https://get.k3s.io | sh -s - \
  --disable traefik \
  --disable servicelb

Ajouter des nœuds workers

Récupérer le token du server

# Sur le nœud server
sudo cat /var/lib/rancher/k3s/server/node-token

Rejoindre le cluster

# Sur chaque nœud worker
curl -sfL https://get.k3s.io | \
  K3S_URL=https://<IP_SERVER>:6443 \
  K3S_TOKEN=<TOKEN> \
  sh -

Vérifier les nœuds

kubectl get nodes -o wide
NAME       STATUS   ROLES                  AGE   VERSION        INTERNAL-IP
server-1   Ready    control-plane,master   10m   v1.30.2+k3s1   192.168.1.10
worker-1   Ready    <none>                 2m    v1.30.2+k3s1   192.168.1.11
worker-2   Ready    <none>                 1m    v1.30.2+k3s1   192.168.1.12

Premier déploiement

Déployer une application

# Créer un déploiement nginx
kubectl create deployment nginx --image=nginx:alpine --replicas=2

# Attendre que les pods soient prêts
kubectl rollout status deployment/nginx

# Vérifier
kubectl get pods -o wide

Exposer en NodePort

kubectl expose deployment nginx --type=NodePort --port=80

# Trouver le port assigné
kubectl get svc nginx
# NAME    TYPE       CLUSTER-IP      PORT(S)        AGE
# nginx   NodePort   10.43.180.123   80:31234/TCP   5s

# Accéder
curl http://<IP_NODE>:31234

Exposer via un fichier YAML

# service-nginx.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  selector:
    app: nginx
  type: NodePort
  ports:
    - port: 80
      targetPort: 80
      nodePort: 30080
kubectl apply -f service-nginx.yaml

Ingress avec Traefik

Traefik est installé par défaut dans k3s et écoute sur les ports 80 et 443 du nœud server.

Ingress Kubernetes standard

# ingress-nginx.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-ingress
  annotations:
    traefik.ingress.kubernetes.io/router.entrypoints: web
spec:
  rules:
    - host: nginx.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: nginx
                port:
                  number: 80
kubectl apply -f ingress-nginx.yaml
# Accéder via : curl -H "Host: nginx.example.com" http://<IP_SERVER>

IngressRoute Traefik (API native)

# ingressroute.yaml
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: nginx-route
spec:
  entryPoints:
    - web
  routes:
    - match: Host(`nginx.example.com`)
      kind: Rule
      services:
        - name: nginx
          port: 80

TLS avec Let's Encrypt

cert-manager n'est pas inclus dans k3s. Installez-le d'abord : kubectl apply -f https://github.com/cert-manager/cert-manager/releases/latest/download/cert-manager.yaml

# issuer.yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: admin@example.com
    privateKeySecretRef:
      name: letsencrypt-prod
    solvers:
      - http01:
          ingress:
            class: traefik

Stockage persistant

local-path-provisioner (inclus par défaut)

k3s inclut un provisioner de volumes locaux. Il crée des dossiers dans /var/lib/rancher/k3s/storage/.

# pvc-example.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: local-path
  resources:
    requests:
      storage: 5Gi
kubectl apply -f pvc-example.yaml
kubectl get pvc

Utiliser un PVC dans un pod

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-with-storage
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
        - name: app
          image: nginx:alpine
          volumeMounts:
            - name: data
              mountPath: /data
      volumes:
        - name: data
          persistentVolumeClaim:
            claimName: my-pvc

Longhorn (stockage distribué - recommandé en prod)

# 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

Helm sur k3s

Helm CLI (standard)

# Installer Helm
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash

# Vérifier
helm version

# Ajouter un repo et déployer
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update

helm install my-redis bitnami/redis \
  --namespace redis \
  --create-namespace \
  --set auth.enabled=false

kubectl get pods -n redis

HelmChart (controller natif k3s)

k3s inclut un controller Helm natif - déclarer un chart via un objet HelmChart :

# helmchart-grafana.yaml
apiVersion: helm.cattle.io/v1
kind: HelmChart
metadata:
  name: grafana
  namespace: kube-system
spec:
  repo: https://grafana.github.io/helm-charts
  chart: grafana
  targetNamespace: monitoring
  createNamespace: true
  valuesContent: |-
    adminPassword: "admin"
    service:
      type: NodePort
kubectl apply -f helmchart-grafana.yaml
# k3s gère l'installation automatiquement
kubectl get pods -n monitoring

Configuration avancée

Options de démarrage importantes

# Désactiver des composants spécifiques
curl -sfL https://get.k3s.io | sh -s - \
  --disable traefik \       # Désactiver Traefik (utiliser NGINX Ingress)
  --disable servicelb \     # Désactiver Klipper LB
  --disable metrics-server  # Désactiver metrics-server

# Forcer un CIDR de pods spécifique
curl -sfL https://get.k3s.io | sh -s - \
  --cluster-cidr 10.244.0.0/16 \
  --service-cidr 10.96.0.0/12

# Exposer l'API server sur une IP spécifique
curl -sfL https://get.k3s.io | sh -s - \
  --tls-san 192.168.1.10 \
  --tls-san mon-cluster.example.com

Fichier de configuration (recommandé)

Créer /etc/rancher/k3s/config.yaml avant l'installation :

# /etc/rancher/k3s/config.yaml
disable:
  - traefik
  - servicelb
cluster-cidr: "10.244.0.0/16"
service-cidr: "10.96.0.0/12"
tls-san:
  - "192.168.1.10"
  - "k3s.example.com"
node-label:
  - "env=production"

Variables d'environnement utiles

# Installation silencieuse (pas de questions)
INSTALL_K3S_SKIP_START=true       # Installer sans démarrer
INSTALL_K3S_SKIP_ENABLE=true      # Ne pas activer le service systemd
K3S_KUBECONFIG_MODE="644"         # Permissions du kubeconfig (accès sans sudo)
K3S_NODE_NAME="mon-server"        # Nom du nœud

Haute disponibilité (HA)

k3s supporte le mode HA avec un datastore externe ou etcd embarqué.

HA avec etcd (recommandé pour 3+ nœuds)

# Premier server (initialise le cluster etcd)
curl -sfL https://get.k3s.io | sh -s - \
  --cluster-init \
  --tls-san <LOAD_BALANCER_IP>

# Token pour rejoindre
sudo cat /var/lib/rancher/k3s/server/node-token

# Autres servers (rejoignent le cluster)
curl -sfL https://get.k3s.io | sh -s - \
  --server https://<PREMIER_SERVER>:6443 \
  --token <TOKEN> \
  --tls-san <LOAD_BALANCER_IP>

HA avec base de données externe

curl -sfL https://get.k3s.io | sh -s - \
  --datastore-endpoint="mysql://user:pass@tcp(host:3306)/k3s"

Mise à jour

# Mettre à jour vers la dernière version stable
curl -sfL https://get.k3s.io | sh -

# Mettre à jour vers une version spécifique
curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION="v1.30.2+k3s1" sh -

# Vérifier la version
k3s --version
kubectl version

Mettre à jour le server en premier, puis les agents.


Sauvegarde et restauration

Sauvegarder etcd

# Snapshot etcd (mode HA uniquement)
k3s etcd-snapshot save --name backup-$(date +%Y%m%d)

# Lister les snapshots
k3s etcd-snapshot ls

# Snapshots automatiques (toutes les 12h par défaut)
# Vérifier dans /var/lib/rancher/k3s/server/db/snapshots/
ls /var/lib/rancher/k3s/server/db/snapshots/

Restaurer un snapshot

# Arrêter k3s
sudo systemctl stop k3s

# Restaurer
k3s server \
  --cluster-reset \
  --cluster-reset-restore-path=/var/lib/rancher/k3s/server/db/snapshots/backup-20240115

# Redémarrer
sudo systemctl start k3s

Troubleshooting

Logs du server k3s

sudo journalctl -u k3s -f
sudo journalctl -u k3s --since "10 minutes ago"

Logs d'un agent

sudo journalctl -u k3s-agent -f

Inspecter un pod en erreur

# Voir les événements
kubectl describe pod <nom-pod>

# Logs du pod
kubectl logs <nom-pod>
kubectl logs <nom-pod> --previous  # Logs du crash précédent

# Shell dans un pod
kubectl exec -it <nom-pod> -- /bin/sh

Pod bloqué en Pending

# Voir les événements du pod
kubectl describe pod <nom-pod> | grep -A10 Events

# Vérifier les ressources disponibles
kubectl top nodes
kubectl describe nodes | grep -A5 "Allocated resources"

Problème de certificats

# Regénérer les certificats (expire tous les 12 mois)
sudo k3s certificate rotate
sudo systemctl restart k3s

Vérifier la connectivité réseau

# Tester la résolution DNS interne
kubectl run test-dns --image=busybox --rm -it --restart=Never -- nslookup kubernetes.default

# Ping entre pods
kubectl run ping-test --image=busybox --rm -it --restart=Never -- ping <IP_POD>

Reset complet

# Sur les workers (d'abord)
sudo /usr/local/bin/k3s-agent-uninstall.sh

# Sur le server (en dernier)
sudo /usr/local/bin/k3s-uninstall.sh

Commandes utiles

# État général du cluster
kubectl get nodes -o wide
kubectl get pods -A
kubectl get svc -A
kubectl top nodes
kubectl top pods -A

# Contexte et config
kubectl config view
kubectl config current-context

# Events du cluster
kubectl get events -A --sort-by='.lastTimestamp' | tail -20

# Accès shell dans un pod debug
kubectl run debug --image=busybox --rm -it --restart=Never -- /bin/sh

# Redémarrer un deployment
kubectl rollout restart deployment/<nom>

# Scaler un deployment
kubectl scale deployment/<nom> --replicas=3

# Port-forward local
kubectl port-forward svc/<nom-service> 8080:80

Ressources

Newsletter · 2 000+ abonnés

Reste au courant de ce qui bouge en prod

RudeOps veille devops hebdo, droit au but.

Gratuit · Sans spam · Désinscription en un clic