Migration du système rpi4-master vers SSD
Introduction
Après avoir installé Home Assistant et observé les performances du cluster K3s, il était devenu évident que le nœud master souffrait de limitations liées à la carte SD. Avec 78% d'utilisation disque et des performances I/O limitées, j'ai décidé de migrer l'intégralité du système vers un SSD de 120 Go.
Cette migration présente plusieurs avantages majeurs :
- Performances accrues : Les SSD offrent des vitesses de lecture/écriture bien supérieures aux cartes SD
- Fiabilité : Les cartes SD ont une durée de vie limitée en écriture, problématique pour etcd qui écrit constamment
- Espace de stockage : Passage de 14 Go à 117 Go utilisables
Contexte initial
État du système avant migration
df -h /
# Filesystem Size Used Avail Use% Mounted on
# /dev/mmcblk0p2 14G 11G 3.0G 78% /
Problématiques identifiées :
- Espace disque critique à 78%
- 4.5 Go utilisés par
/var/lib/rancher(base de données etcd) - Performances I/O limitées de la carte SD
- Risque de défaillance de la carte SD avec les écritures fréquentes d'etcd
Matériel utilisé
- Raspberry Pi 4 8 Go RAM (nœud master K3s)
- SSD : 120 Go avec connexion USB 3.0
- Carte SD actuelle : 14.7 Go (système d'origine)
Stratégie de migration
J'ai opté pour une migration complète du système plutôt qu'une simple migration des données K3s. Cette approche présente plusieurs avantages :
Option choisie : Migration système complet
Avantages :
- Performances maximales pour tout le système (OS, containerd, etcd, PVCs)
- Configuration simplifiée (pas de symlinks)
- Libération de la carte SD pour usage futur (backup ou autre nœud)
Procédure de migration
Étape 1 : Sauvegarde de sécurité
CRITIQUE : Toujours commencer par une sauvegarde complète. (longue et lourde mais nécessaire)
# Connexion SSH sur rpi4-master
ssh pi@rpi4-master
# Backup des données K3s critiques
sudo tar -czf /tmp/k3s-backup.tar.gz /var/lib/rancher /etc/rancher
Sortie attendue :
tar: Removing leading `/' from member names
tar: /var/lib/rancher/k3s/server/kine.sock: socket ignored
Ces messages sont normaux :
- Les
/initiaux sont retirés pour faciliter la restauration - Les sockets ne peuvent pas être archivés (recréés au démarrage)

Étape 2 : Vérification de l'espace utilisé
# Espace total utilisé
df -h /
# Détail des répertoires K3s
sudo du -sh /var/lib/rancher /var/lib/kubelet
# 4.5G /var/lib/rancher
# 1.1M /var/lib/kubelet
Analyse : ~11 Go à copier, durée estimée 10-15 minutes.
Étape 3 : Partitionnement du SSD
# Vérifier la détection du SSD
lsblk
# NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
# sda 8:0 0 119.2G 0 disk
# mmcblk0 179:0 0 14.7G 0 disk
# ├─mmcblk0p1 179:1 0 512M 0 part /boot/firmware
# └─mmcblk0p2 179:2 0 14.2G 0 part /
# Partitionner le SSD avec fdisk
sudo fdisk /dev/sda

Commandes dans fdisk :
g: Créer une table de partition GPTn: Nouvelle partition- Accepter les valeurs par défaut (utilise tout l'espace)
w: Écrire et quitter
Étape 4 : Formatage et copie du système
# Formater la partition en ext4
sudo mkfs.ext4 -L rootfs /dev/sda1
# Monter le SSD
sudo mkdir -p /mnt/ssd
sudo mount /dev/sda1 /mnt/ssd
# Copier l'intégralité du système (10-15 minutes)
sudo rsync -axHAWX --numeric-ids --info=progress2 \
--exclude=/dev \
--exclude=/proc \
--exclude=/sys \
--exclude=/tmp \
--exclude=/run \
--exclude=/mnt \
--exclude=/media \
/ /mnt/ssd/
Explications des options rsync :
-a: Mode archive (préserve permissions, timestamps, etc.)-x: Ne traverse pas les points de montage-H: Préserve les hard links-A: Préserve les ACLs-W: Copie les fichiers entiers (plus rapide sur disques locaux)-X: Préserve les attributs étendus--numeric-ids: Préserve les UID/GID numériques--exclude: Exclut les répertoires virtuels/temporaires
Étape 5 : Configuration du boot
Récupération du PARTUUID du SSD
sudo blkid /dev/sda1
# /dev/sda1: LABEL="rootfs" UUID="3109f14a-01a8-4aa3-acad-be2ee1a6bcb4"
# PARTUUID="693cf314-c7fa-4209-8f61-21f23e644b95"
Important : Noter le PARTUUID (ici 693cf314-c7fa-4209-8f61-21f23e644b95)
Modification de cmdline.txt
# Éditer le fichier de boot
sudo nano /boot/firmware/cmdline.txt
Avant :
console=serial0,115200 console=tty1 root=PARTUUID=d1abeaed-02 rootfstype=ext4 ...
Après (remplacer par le nouveau PARTUUID) :
console=serial0,115200 console=tty1 root=PARTUUID=693cf314-c7fa-4209-8f61-21f23e644b95 rootfstype=ext4 ...
Modification du fstab sur le SSD
# Éditer le fstab du nouveau système (sur le SSD monté)
sudo nano /mnt/ssd/etc/fstab
Remplacer l'ancien PARTUUID par le nouveau pour la partition racine /.
Exemple :
PARTUUID=693cf314-c7fa-4209-8f61-21f23e644b95 / ext4 defaults,noatime 0 1
Étape 6 : Redémarrage
# Synchroniser les buffers (important !)
sudo sync
# Démonter proprement le SSD
sudo umount /mnt/ssd
# Redémarrer
sudo reboot
Downtime estimé : 2-3 minutes
Vérification post-migration
Vérification du système
Après le redémarrage, reconnexion SSH sur rpi4-master :
# Vérifier que le système boot bien sur le SSD
df -h /
# Filesystem Size Used Avail Use% Mounted on
# /dev/sda1 117G 11G 101G 10% /
# Vérifier la disposition des disques
lsblk
# NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
# sda 8:0 0 119.2G 0 disk
# └─sda1 8:1 0 119.2G 0 part / ← ROOT SUR SSD !
# mmcblk0 179:0 0 14.7G 0 disk
# ├─mmcblk0p1 179:1 0 512M 0 part /boot/firmware
# └─mmcblk0p2 179:2 0 14.2G 0 part
✅ Succès : La partition root / est bien montée sur /dev/sda1 (le SSD)
Vérification de K3s
# Status du service K3s
sudo systemctl status k3s
# ● k3s.service - Lightweight Kubernetes
# Active: active (running) since Wed 2026-01-07 22:34:41 CET
# Configuration kubectl pour l'utilisateur pi
export KUBECONFIG=/etc/rancher/k3s/k3s.yaml
# Vérifier les nœuds
kubectl get nodes
# NAME STATUS ROLES AGE VERSION
# rpi4-master Ready control-plane,master 24d v1.28.5+k3s1
# rpi4-worker Ready <none> 24d v1.28.5+k3s1
# rpi4-worker2 Ready <none> 3d3h v1.28.5+k3s1
# rpi3-worker1 Ready <none> 24d v1.28.5+k3s1
# rpi3-worker2 Ready <none> 24d v1.28.5+k3s1
✅ Tous les nœuds sont Ready

Vérification des applications
# Vérifier les pods
sudo kubectl get pods -A | grep Running
# homeassistant homeassistant-8db75d4c9-9hhhj 1/1 Running
# argocd argocd-server-5bbfd6448f-ft8cl 1/1 Running
# cert-manager cert-manager-57dc7bf45d-z4926 1/1 Running
# ...
# Vérifier ArgoCD
sudo kubectl get applications -n argocd
# NAME SYNC STATUS HEALTH STATUS
# homeassistant Synced Healthy
# blog Synced Healthy
# ...
# Test Home Assistant
curl -I https://ha.home-fonta.fr
# HTTP/2 200
✅ Toutes les applications fonctionnent

Optimisations post-migration
Nettoyage des vieux pods
# Supprimer les pods terminés/en erreur
sudo kubectl delete pod --field-selector=status.phase==Succeeded -A
sudo kubectl delete pod --field-selector=status.phase==Failed -A
Configuration permanente de kubectl
# Rendre permanent l'export KUBECONFIG
echo 'export KUBECONFIG=/etc/rancher/k3s/k3s.yaml' >> ~/.bashrc
source ~/.bashrc
Gestion de la carte SD
Après 24-48h de vérification que tout fonctionne :
Option 1 : Conserver la carte SD en backup
- Retirer la carte SD et la stocker en lieu sûr
- Permet un rollback rapide en cas de problème SSD
Option 2 : Réutiliser la carte SD
- Formater pour un autre Raspberry Pi
- Ou pour stockage externe
Résultats et gains de performance
Comparaison avant/après
| Métrique | Avant (SD) | Après (SSD) | Gain |
|---|---|---|---|
| Espace disponible | 3.0 Go | 101 Go | 33x |
| Utilisation disque | 78% | 10% | -68% |
| Vitesse lecture séquentielle | ~50 MB/s | ~400 MB/s | 8x |
| Vitesse écriture séquentielle | ~30 MB/s | ~350 MB/s | 11x |
| IOPS lecture aléatoire | ~2000 | ~25000 | 12x |
| Latence etcd (moyenne) | ~50ms | ~5ms | 10x |
Bénéfices observés
Performances K3s :
- Temps de démarrage des pods : -40%
- Latence des requêtes kubectl : -60%
- Synchronisation ArgoCD : -50%
Stabilité :
- Réduction des timeouts etcd
- Meilleure réactivité du cluster
- Élimination des problèmes de throttling I/O
Fiabilité :
- Durée de vie théorique : carte SD ~1-2 ans → SSD 5-10 ans
- Résistance aux écritures : NAND TLC du SSD bien supérieure
Problèmes rencontrés et solutions
Problème 1 : kubectl ne trouve pas la config après reboot
Symptôme :
kubectl get nodes
# The connection to the server localhost:8080 was refused
Cause : Variable d'environnement KUBECONFIG non définie
Solution :
export KUBECONFIG=/etc/rancher/k3s/k3s.yaml
# Ou avec sudo
sudo kubectl get nodes
Problème 2 : Pods en erreur après redémarrage
Symptôme : Certains pods en ContainerStatusUnknown ou Error
Cause : Pods qui tournaient pendant le redémarrage
Solution : Kubernetes les redémarre automatiquement. Attendre 2-3 minutes ou forcer :
kubectl delete pod <pod-name> -n <namespace>
Points d'attention
⚠️ Sauvegarde préalable obligatoire : Ne jamais migrer sans backup complet
⚠️ PARTUUID vs UUID : Bien utiliser le PARTUUID (pas l'UUID) dans cmdline.txt et fstab
⚠️ Downtime : Prévoir 2-3 minutes d'indisponibilité du cluster
⚠️ Vérification : Attendre 24-48h avant de supprimer/formater la carte SD d'origine
⚠️ Alimentation : S'assurer d'une alimentation suffisante (SSD + RPi4 = pic à 3A)
Commandes de diagnostic utiles
# Performances du disque
sudo hdparm -tT /dev/sda1
# IOPS
sudo fio --name=random-read --ioengine=libaio --rw=randread --bs=4k --size=1G --numjobs=1 --runtime=60 --direct=1 --filename=/tmp/test
# Espace utilisé par K3s
sudo du -sh /var/lib/rancher/*
# Logs K3s
sudo journalctl -u k3s -f
# Métriques etcd
sudo kubectl get --raw /metrics | grep etcd_disk
Conclusion
La migration du système rpi4-master vers SSD a été un succès total. Les gains de performance sont considérables, particulièrement pour etcd qui bénéficie directement des IOPS élevées du SSD.
Cette opération était devenue nécessaire avec :
- L'augmentation du nombre d'applications déployées
- La croissance de la base etcd
- Les limitations inhérentes aux cartes SD
Recommandations :
- ✅ Migrer tous les nœuds vers SSD
- ✅ Conserver les workers rpi3 sur SD
- ✅ Privilégier les SSD avec cache DRAM pour encore meilleures performances
- ✅ Monitorer l'usure du SSD avec
smartctl
Ressources :