Aller au contenu
Conteneurs & Orchestration medium
🔐 Alerte sécurité — Incident supply chain Trivy : lire mon analyse de l'attaque

RKE2 : déployer un cluster Kubernetes sécurisé sur KVM

21 min de lecture

logo kubernetes

RKE2 (Rancher Kubernetes Engine 2) est la distribution Kubernetes orientée sécurité de Rancher/SUSE, conçue pour faciliter la conformité aux benchmarks CIS. Ce guide vous accompagne dans le déploiement d’un cluster RKE2 reproductible sur KVM, prêt à être renforcé pour la production.

Prérequis : Une machine Linux avec KVM/libvirt, accès SSH avec clé, et kubectl installé sur votre poste.

  • Créer des VMs KVM avec cloud-init pour héberger le cluster
  • Installer un nœud server RKE2 (control plane + etcd)
  • Joindre des nœuds agent (workers) au cluster
  • Récupérer l’accès kubectl et valider le déploiement
  • Diagnostiquer les problèmes courants et nettoyer le lab

RKE2 se distingue par son orientation sécurité par défaut et ses options facilitant la conformité aux benchmarks CIS Kubernetes.

CaractéristiqueRKE2
Orienté sécuritéProfils et options CIS, SELinux/AppArmor
Distribution packagéeComposants intégrés, pas d’assemblage
Configuration centraliséeUn fichier /etc/rancher/rke2/config.yaml
Intégration RancherCompatible avec Rancher Manager
Support enterpriseSUSE/Rancher support commercial
CNI par défautCanal (Flannel + Calico policies)
ContainerdRuntime CRI intégré et hardené

Avant de démarrer, comparez RKE2 avec les autres options :

CritèreRKE2kubeadmk0sk3sKubespray
TypeDistributionBootstrap toolDistributionDistributionPlaybooks Ansible
OrientationEnterprise, sécuritéStandard upstreamEdge, prod, CIEdge, IoT, devProd, multi-cloud
InstallationScriptCommandesk0sctl (YAML)Script uniqueAnsible
CNI défautCanalAucunkube-routerFlannelConfigurable
HA native✅ IntégréeManuel✅ Multi-controller✅ Multi-server✅ Ansible
Profil CIS✅ IntégréManuelManuelManuelSelon config
Cas d’usageConformité, prodBare metal, formationEdge, CI/CD, prodEdge, IoT, devProd automatisée

Ce lab déploie un cluster RKE2 minimaliste mais fonctionnel :

Architecture du lab RKE2 avec 1 server et 2 agents sur KVM

PortProtocoleSource → DestinationRôle
6443TCPAgents, kubectl → ServerAPI Kubernetes
9345TCPAgents → ServerRegistration RKE2
10250TCPServer → Agentskubelet API
8472UDPTous nœuds ↔ Tous nœudsVXLAN (Canal)
Fenêtre de terminal
# Paquets KVM/libvirt
sudo apt install qemu-kvm libvirt-daemon-system libvirt-clients virtinst cloud-image-utils
# Vérifier que libvirtd est actif
sudo systemctl status libvirtd
# Télécharger kubectl si absent
curl -LO "https://dl.k8s.io/release/$(curl -Ls https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
chmod +x kubectl && sudo mv kubectl /usr/local/bin/
Fenêtre de terminal
# Télécharger l'image cloud Ubuntu 24.04
wget -O ubuntu-24.04-cloudimg.img \
https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img
  1. Créer les disques QCOW2

    Fenêtre de terminal
    # Créer un disque basé sur l'image cloud
    for VM in rke2-cp1 rke2-worker1 rke2-worker2; do
    qemu-img create -f qcow2 -F qcow2 \
    -b ubuntu-24.04-cloudimg.img \
    ${VM}.qcow2 20G
    done
  2. Générer la configuration cloud-init

    Créez un fichier cloud-init-cp1.yaml pour le server :

    #cloud-config
    hostname: rke2-cp1
    manage_etc_hosts: true
    users:
    - name: kube
    sudo: ALL=(ALL) NOPASSWD:ALL
    shell: /bin/bash
    ssh_authorized_keys:
    - ssh-ed25519 AAAA... votre-clé-publique
    # Désactiver le swap (requis pour Kubernetes)
    swap:
    filename: /swap.img
    size: 0
    # Configuration réseau statique
    write_files:
    - path: /etc/netplan/50-cloud-init.yaml
    content: |
    network:
    version: 2
    ethernets:
    enp1s0:
    addresses: [192.168.122.10/24]
    routes:
    - to: default
    via: 192.168.122.1
    nameservers:
    addresses: [192.168.122.1]
    runcmd:
    - netplan apply
    - swapoff -a
    - sed -i '/swap/d' /etc/fstab
  3. Créer les ISOs cloud-init

    Fenêtre de terminal
    for VM in rke2-cp1 rke2-worker1 rke2-worker2; do
    cloud-localds ${VM}-cloud-init.iso cloud-init-${VM}.yaml
    done
  4. Créer les VMs avec virt-install

    Fenêtre de terminal
    # Server (4 Go RAM)
    virt-install --name rke2-cp1 \
    --memory 4096 --vcpus 2 \
    --disk rke2-cp1.qcow2 \
    --disk rke2-cp1-cloud-init.iso,device=cdrom \
    --os-variant ubuntu24.04 \
    --network network=default \
    --graphics none --console pty,target_type=serial \
    --noautoconsole --import
    # Workers (3 Go RAM chacun)
    for WORKER in rke2-worker1 rke2-worker2; do
    virt-install --name ${WORKER} \
    --memory 3072 --vcpus 2 \
    --disk ${WORKER}.qcow2 \
    --disk ${WORKER}-cloud-init.iso,device=cdrom \
    --os-variant ubuntu24.04 \
    --network network=default \
    --graphics none --console pty,target_type=serial \
    --noautoconsole --import
    done
  5. Attendre la disponibilité SSH

    Fenêtre de terminal
    for IP in 192.168.122.10 192.168.122.20 192.168.122.21; do
    until ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no kube@${IP} exit 2>/dev/null; do
    echo "Attente de ${IP}..."
    sleep 5
    done
    echo "${IP} accessible"
    done
  1. Installer RKE2 sur le server

    Fenêtre de terminal
    ssh kube@192.168.122.10 << 'EOF'
    # Télécharger et exécuter le script d'installation
    curl -sfL https://get.rke2.io | sudo sh -
    EOF
  2. Configurer le server RKE2

    Créez /etc/rancher/rke2/config.yaml sur le server :

    Fenêtre de terminal
    ssh kube@192.168.122.10 << 'EOF'
    sudo mkdir -p /etc/rancher/rke2
    sudo tee /etc/rancher/rke2/config.yaml << 'CONFIG'
    # Token stable pour les agents (à conserver !)
    token: rke2-lab-token-secure-2026
    # Certificats TLS valides pour ces noms/IPs
    tls-san:
    - 192.168.122.10
    - rke2-cp1
    - rke2-cp1.local
    CONFIG
    EOF
  3. Démarrer le service rke2-server

    Fenêtre de terminal
    ssh kube@192.168.122.10 << 'EOF'
    sudo systemctl enable rke2-server
    sudo systemctl start rke2-server
    EOF
  4. Suivre les logs d’initialisation

    Fenêtre de terminal
    ssh kube@192.168.122.10 "sudo journalctl -u rke2-server -f"

    Attendez le message rke2 is up and running (environ 1-2 minutes).

Une fois le server opérationnel, installez RKE2 en mode agent sur les workers :

  1. Installer RKE2 (mode agent) sur chaque worker

    Fenêtre de terminal
    for WORKER_IP in 192.168.122.20 192.168.122.21; do
    ssh kube@${WORKER_IP} << 'EOF'
    curl -sfL https://get.rke2.io | INSTALL_RKE2_TYPE="agent" sudo sh -
    EOF
    done
  2. Configurer les agents

    Fenêtre de terminal
    for WORKER_IP in 192.168.122.20 192.168.122.21; do
    ssh kube@${WORKER_IP} << 'EOF'
    sudo mkdir -p /etc/rancher/rke2
    sudo tee /etc/rancher/rke2/config.yaml << 'CONFIG'
    # Adresse du server RKE2
    server: https://192.168.122.10:9345
    # Token identique au server
    token: rke2-lab-token-secure-2026
    CONFIG
    EOF
    done
  3. Démarrer les agents

    Fenêtre de terminal
    for WORKER_IP in 192.168.122.20 192.168.122.21; do
    ssh kube@${WORKER_IP} << 'EOF'
    sudo systemctl enable rke2-agent
    sudo systemctl start rke2-agent
    EOF
    done
  4. Vérifier le statut des agents

    Fenêtre de terminal
    for WORKER_IP in 192.168.122.20 192.168.122.21; do
    ssh kube@${WORKER_IP} "sudo systemctl status rke2-agent --no-pager | head -5"
    done
  1. Récupérer le kubeconfig depuis le server

    Fenêtre de terminal
    # Copier le kubeconfig
    ssh kube@192.168.122.10 "sudo cat /etc/rancher/rke2/rke2.yaml" > kubeconfig
    # Adapter l'adresse du server
    sed -i 's/127.0.0.1/192.168.122.10/g' kubeconfig
  2. Tester l’accès au cluster

    Fenêtre de terminal
    export KUBECONFIG=$PWD/kubeconfig
    kubectl cluster-info
    kubectl get nodes

    Résultat attendu :

    NAME STATUS ROLES AGE VERSION
    rke2-cp1 Ready control-plane,etcd 10m v1.34.5+rke2r1
    rke2-worker1 Ready <none> 5m v1.34.5+rke2r1
    rke2-worker2 Ready <none> 5m v1.34.5+rke2r1
Fenêtre de terminal
kubectl get pods -n kube-system

Vous devriez retrouver les static pods du control plane et les composants packagés activés :

CatégoriePods
Control planeetcd-*, kube-apiserver-*, kube-controller-manager-*, kube-scheduler-*
CNIrke2-canal-* (un par nœud)
DNSrke2-coredns-*
Composants optionnelsrke2-ingress-nginx-*, rke2-metrics-server-* (selon config)
Fenêtre de terminal
# Créer un déploiement nginx
kubectl create deployment nginx --image=nginx:alpine --replicas=2
# Vérifier le scheduling
kubectl get pods -o wide

Les pods doivent être répartis sur les workers (rke2-worker1 et rke2-worker2).

Fenêtre de terminal
kubectl run test-dns --rm -it --restart=Never --image=busybox:1.36 \
-- nslookup kubernetes.default.svc.cluster.local

Résultat attendu :

Server: 10.43.0.10
Address: 10.43.0.10:53
Name: kubernetes.default.svc.cluster.local
Address: 10.43.0.1
Fenêtre de terminal
kubectl delete deployment nginx
CheminContenu
/etc/rancher/rke2/config.yamlConfiguration du nœud
/etc/rancher/rke2/rke2.yamlKubeconfig local (server)
/var/lib/rancher/rke2/Données du cluster
/var/lib/rancher/rke2/server/db/Données etcd
/var/lib/rancher/rke2/agent/logs/Logs conteneurs
/usr/local/bin/rke2Binaire RKE2
/var/lib/rancher/rke2/bin/Binaires additionnels (kubectl, crictl)
Fenêtre de terminal
# Logs du service
sudo journalctl -u rke2-server -f
sudo journalctl -u rke2-agent -f
# Status du service
sudo systemctl status rke2-server
sudo systemctl status rke2-agent
# kubectl depuis le server
sudo /var/lib/rancher/rke2/bin/kubectl \
--kubeconfig /etc/rancher/rke2/rke2.yaml \
get nodes
# crictl pour inspecter les conteneurs
# Identifiez d'abord le socket containerd sur votre nœud :
ls /run/containerd/ /run/k3s/containerd/ 2>/dev/null
# Puis utilisez crictl avec le socket trouvé
sudo /var/lib/rancher/rke2/bin/crictl \
--runtime-endpoint unix:///run/k3s/containerd/containerd.sock \
ps

Symptôme :

UnexpectedAdmissionError: preemption: error finding a set of pods to preempt:
no set of running pods found to reclaim resources: memory

Cause : Mémoire insuffisante.

Solution : Augmentez la RAM de la VM à 4 Go minimum pour le server.


Symptôme : Nœud jamais visible dans kubectl get nodes

Vérifications :

  1. Token identique au server ? (/etc/rancher/rke2/config.yaml)
  2. URL du server correcte ? (https://IP:9345, pas 6443)
  3. Connectivité réseau ? curl -k https://192.168.122.10:9345
  4. Service démarré ? systemctl status rke2-agent

Kubeconfig : “certificate signed by unknown authority”

Section intitulée « Kubeconfig : “certificate signed by unknown authority” »

Cause : Le kubeconfig local contient un ancien certificat.

Solution :

Fenêtre de terminal
# Récupérer un kubeconfig frais
ssh kube@192.168.122.10 "sudo cat /etc/rancher/rke2/rke2.yaml" > kubeconfig
sed -i 's/127.0.0.1/192.168.122.10/g' kubeconfig

Symptôme : Tous les pods Helm helm-install-* restent en Pending.

Cause possible : Le kube-scheduler n’a pas démarré (voir erreur mémoire).

Vérification :

Fenêtre de terminal
kubectl get pods -n kube-system | grep scheduler

Symptôme : Problèmes réseau après redémarrage.

Solution : Voir la section “Prérequis” pour la configuration de NetworkManager.

Sur chaque nœud, utilisez le script de désinstallation installé par votre méthode d’installation :

Fenêtre de terminal
# Le chemin dépend de la méthode d'installation
# Vérifiez lequel existe sur votre nœud :
ls -la /usr/local/bin/rke2-uninstall.sh \
/opt/rke2/bin/rke2-uninstall.sh \
/usr/bin/rke2-uninstall.sh 2>/dev/null
# Exécutez le script trouvé (exemple avec /usr/local/bin)
sudo /usr/local/bin/rke2-uninstall.sh

Ce script supprime le binaire RKE2, les données et les configurations. Consultez la documentation Uninstall pour les détails.

Depuis l’hyperviseur :

Fenêtre de terminal
# Arrêter et supprimer les VMs
for VM in rke2-cp1 rke2-worker1 rke2-worker2; do
virsh destroy ${VM} 2>/dev/null
virsh undefine ${VM} --remove-all-storage
done
# Supprimer les ISOs cloud-init
rm -f rke2-*-cloud-init.iso

Pour un cluster HA, déployez 3 servers minimum (nombre impair) :

  • Quorum etcd : etcd nécessite une majorité de nœuds disponibles (2 sur 3, 3 sur 5). Avec un nombre impair, vous tolérez la perte d’un server.
  • Adresse de registration fixe : les agents et servers additionnels doivent pointer vers une adresse stable (load balancer ou VIP)
  • Load balancer : HAProxy, keepalived, ou cloud LB devant les servers sur le port 9345/6443
# config.yaml sur chaque server HA
server: https://rke2-lb.example.com:9345
token: votre-token-stable
tls-san:
- rke2-lb.example.com
- 192.168.122.100 # VIP du load balancer

La documentation officielle détaille cette architecture : RKE2 HA

RKE2 propose des options et profils facilitant la conformité CIS :

/etc/rancher/rke2/config.yaml
profile: cis

Cela active des restrictions de sécurité supplémentaires. Attention : l’installation seule ne garantit pas la conformité — elle facilite l’atteinte des benchmarks.

RKE2 s’intègre nativement avec Rancher Manager pour :

  • Gestion centralisée multi-clusters
  • RBAC visuel
  • Monitoring intégré
  • Catalogue d’applications
  • Distribution orientée sécurité : RKE2 facilite la conformité CIS avec des profils et options intégrés — mais l’installation seule ne garantit pas la conformité.
  • Configuration via YAML : Privilégiez /etc/rancher/rke2/config.yaml pour une configuration reproductible et versionnable.
  • Token stable : Définissez un token explicite et conservez-le : il sert au chiffrement, à la restauration et à l’ajout de nœuds.
  • Ports 6443 et 9345 : 6443 pour l’API Kubernetes, 9345 pour l’enregistrement et la supervision RKE2.

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn