Aller au contenu
Conteneurs & Orchestration medium

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

60 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

Un cluster RKE2 ne démarre pas si ces flux sont bloqués, et le symptôme est trompeur : le service se lance normalement, mais les agents n'apparaissent jamais dans kubectl get nodes. Retenez surtout le 9345, propre à RKE2 et souvent oublié dans les règles de pare-feu, et le 8472 en UDP qu'utilise le réseau overlay Canal entre les nœuds.

PortProtocoleSource → DestinationRôle
6443TCPAgents, kubectl → ServerAPI Kubernetes
9345TCPAgents → ServerRegistration RKE2
10250TCPServer → Agentskubelet API
8472UDPTous nœuds ↔ Tous nœudsVXLAN (Canal)

Vérifiez ces points avant de commencer : un manque à ce stade se manifeste bien plus tard, sous la forme d'une erreur qui ne le désigne pas.

Trois éléments sont nécessaires côté hôte : la pile KVM/libvirt pour créer les machines virtuelles, l'utilitaire cloud-localds (paquet cloud-image-utils) pour fabriquer les images cloud-init, et le client kubectl pour piloter le cluster une fois debout. Le binaire kubectl se vérifie avec la somme de contrôle publiée à côté de lui, ne l'installez jamais sans ce contrôle.

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 et sa somme de contrôle officielle
KUBECTL_VERSION="$(curl -Ls https://dl.k8s.io/release/stable.txt)"
curl -LO "https://dl.k8s.io/release/${KUBECTL_VERSION}/bin/linux/amd64/kubectl"
curl -LO "https://dl.k8s.io/release/${KUBECTL_VERSION}/bin/linux/amd64/kubectl.sha256"
# Vérifier l'empreinte avant installation (doit afficher "kubectl: OK")
echo "$(cat kubectl.sha256) kubectl" | sha256sum --check -
chmod +x kubectl && sudo mv kubectl /usr/local/bin/

Les images cloud sont des disques préinstallés, déjà équipés de cloud-init, qui évitent toute installation manuelle du système. Canonical publie un fichier SHA256SUMS dans le même répertoire : vérifiez l'empreinte avant de fabriquer les disques des trois VMs, sinon vous propagerez une image corrompue sur tout le cluster.

Fenêtre de terminal
# Télécharger l'image cloud Ubuntu 24.04 et les sommes de contrôle
wget https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img
wget https://cloud-images.ubuntu.com/noble/current/SHA256SUMS
# Vérifier l'empreinte (doit afficher "OK" pour l'image téléchargée)
sha256sum --ignore-missing --check SHA256SUMS
# Renommer une fois la vérification réussie
mv noble-server-cloudimg-amd64.img ubuntu-24.04-cloudimg.img

Les trois machines virtuelles sont créées à partir de la même image cloud, en copie sur écriture : chaque disque QCOW2 ne stocke que ses différences avec l'image de base, ce qui rend la création quasi instantanée. La configuration (nom d'hôte, clé SSH, adresse IP fixe, désactivation du swap) est injectée par cloud-init au premier démarrage, sans aucune intervention manuelle.

  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

Le nœud server héberge le control plane et etcd, c'est lui qui doit démarrer en premier. L'installation se déroule en deux temps : le script dépose le binaire et les unités systemd, mais ne démarre rien. Vous écrivez ensuite /etc/rancher/rke2/config.yaml, puis vous lancez le service. Cet ordre compte : un service démarré avant l'écriture du fichier de configuration générerait des certificats sans les noms alternatifs (tls-san) attendus.

  1. Installer RKE2 sur le server

    Fenêtre de terminal
    ssh kube@192.168.122.10 << 'EOF'
    # Télécharger le script officiel puis l'exécuter (inspectez-le au préalable)
    curl -sfL https://get.rke2.io -o rke2-install.sh
    sudo sh rke2-install.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 -o rke2-install.sh
    INSTALL_RKE2_TYPE="agent" sudo sh rke2-install.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

RKE2 génère un kubeconfig complet dans /etc/rancher/rke2/rke2.yaml, avec les certificats et le compte administrateur du cluster. Ce fichier pointe vers 127.0.0.1 puisqu'il est prévu pour un usage local sur le server : pour l'utiliser depuis votre poste, il faut remplacer cette adresse par l'IP du nœud. Traitez ce fichier comme un secret, il donne un accès complet au cluster.

  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

Trois nœuds Ready ne signifient pas que le cluster est utilisable. Il reste à confirmer que les composants système tournent, que le planificateur répartit bien les charges sur les workers, et que la résolution DNS interne fonctionne. Ces trois vérifications prennent deux minutes et évitent des heures de diagnostic sur la première application déployée.

Tous les composants de RKE2 tournent dans le namespace kube-system. Les processus du control plane y apparaissent sous forme de static pods, gérés directement par le kubelet à partir de manifestes sur disque, et non par l'API server.

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)

Ce déploiement à deux réplicas valide toute la chaîne : téléchargement d'image par containerd, planification, et démarrage effectif des conteneurs. L'option -o wide ajoute la colonne NODE, indispensable ici puisque c'est la répartition qui nous intéresse.

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).

Sans DNS interne, aucune application ne peut joindre un Service par son nom, et les symptômes ressemblent à s'y méprendre à un problème réseau. Le Pod de test est éphémère grâce à --rm, il disparaît dès la fin de la résolution.

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

Supprimez le déploiement de validation avant de passer à la suite : ses Pods continueraient sinon à consommer de la mémoire sur des workers déjà justes en ressources.

Fenêtre de terminal
kubectl delete deployment nginx

RKE2 range tout au même endroit, ce qui simplifie beaucoup le diagnostic : la configuration dans /etc/rancher/rke2/, les données et les binaires dans /var/lib/rancher/rke2/. Les deux réflexes à acquérir sont la lecture des journaux du service avec journalctl et l'inspection des conteneurs avec crictl, puisque aucune commande docker n'existe sur ces nœuds.

Ce tableau vous évitera de chercher : c'est ici que se trouvent la configuration à modifier, les données etcd à sauvegarder et les journaux à consulter en cas d'incident.

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)

RKE2 installe ses propres binaires (kubectl, crictl) dans /var/lib/rancher/rke2/bin/, répertoire absent du PATH. Vous devez donc les appeler par leur chemin complet, ou ajouter ce répertoire au PATH de votre session comme indiqué plus haut.

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

Les cinq incidents ci-dessous couvrent l'essentiel de ce qui bloque un premier déploiement RKE2. Trois d'entre eux se ramènent à deux causes : une VM sous-dimensionnée en mémoire, ou une erreur de jonction entre agent et server (token, port ou connectivité). Chaque cas donne le symptôme observé, la cause et la correction.

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.

Le nettoyage se fait dans cet ordre : désinstaller RKE2 sur les nœuds, puis détruire les machines virtuelles. Si vous comptez de toute façon supprimer les VMs, la première étape est facultative ; elle reste indispensable en revanche pour réinstaller RKE2 proprement sur des machines que vous conservez, car des données résiduelles empêchent une nouvelle initialisation.

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

Le cluster obtenu est fonctionnel mais reste un lab : un seul server, donc un point de défaillance unique sur etcd et l'API. Trois axes le rapprochent d'une architecture de production, dans cet ordre de priorité : la haute disponibilité du control plane, l'activation du profil CIS, puis l'intégration à Rancher Manager pour la gestion multi-clusters.

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 tracking. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn