Kubernetes fs
| Fiche express | |
|---|---|
| Type | Procédure de diagnostic disque plein sur un cluster RKE2 |
| Symptôme | Pods en erreur, écritures refusées, nœud instable |
| Causes fréquentes | Logs non rotés, images non nettoyées, PVC saturé |
| Voir aussi | Kubernetes troubleshooting · Kubernetes rancher |
Un système de fichiers saturé — sur un nœud ou dans un volume persistant — est l'une des causes d'instabilité les plus fréquentes d'un cluster Kubernetes en production : pods qui échouent à écrire, kubelet qui rejette de nouveaux pods (condition DiskPressure), ou applications qui plantent silencieusement faute d'espace. Cette page décrit une procédure de diagnostic pas à pas, illustrée sur RKE2, mais transposable à toute distribution Kubernetes basée sur containerd.
Les causes les plus courantes : logs de conteneurs non rotés, images non nettoyées côté containerd, volumes persistants (PVC) saturés par l'application elle-même, données temporaires accumulées dans les pods, ou — plus rarement mais tout aussi bloquant — épuisement des inodes plutôt que de l'espace brut.
Identifier le nœud et le pod concernés
kubectl get pods -A -o wide # localiser le pod en erreur et son nœud
kubectl describe pod <nom-pod> -n <namespace> # événements : No space left on device, etc.
kubectl logs <nom-pod> -n <namespace>
Analyser l'espace disque du nœud
Une fois connecté au nœud worker concerné :
df -h # vue d'ensemble
df -h | grep -E '(8[5-9]|9[0-9]|100)%' # partitions au-delà de 85 % d'usage
df -i # ne pas oublier les inodes
Puis identifier les répertoires les plus volumineux, en particulier ceux propres à RKE2 :
du -sh /var/lib/rancher/rke2/*
du -sh /var/lib/kubelet/*
du -sh /var/log/*
du -h /var/lib/rancher/rke2 | sort -rh | head -20 # plus gros consommateurs
| Répertoire | Contenu | Impact typique |
|---|---|---|
/var/lib/rancher/rke2/ |
Données RKE2 principales (etcd, containerd, manifestes) | Critique |
/var/log/pods/ |
Logs des conteneurs | Croissance rapide, cause la plus fréquente |
/var/lib/kubelet/ |
Données kubelet (volumes montés, plugins) | Modéré |
/var/lib/rancher/rke2/agent/containerd/ |
Images et couches de conteneurs | Important si nettoyage absent |
Vérifier les causes courantes
Logs de conteneurs non rotés
du -sh /var/log/pods/* | sort -rh | head -10
Images containerd non nettoyées
crictl images
du -sh /var/lib/rancher/rke2/agent/containerd/io.containerd.content.v1.content/blobs/
Volumes persistants saturés
kubectl get pvc -A
kubectl describe pv
Volumes éphémères du pod
kubectl exec -it <nom-pod> -n <namespace> -- /bin/sh
df -h
find / -type f -size +100M 2>/dev/null
Investiguer un PVC en détail
Trois angles complémentaires pour localiser précisément ce qui remplit un volume persistant :
# Depuis le pod : quel volume est plein, et à quel point
kubectl exec -it <nom-pod> -n <namespace> -- df -h
# Exemple de sortie révélatrice :
# /dev/sdb1 10G 9.8G 200M 98% /data <- PVC quasi plein
# Depuis le PVC : capacité déclarée et point de montage dans le pod
kubectl describe pvc <nom-pvc> -n <namespace>
kubectl get pod <nom-pod> -n <namespace> -o yaml | grep -A 10 volumeMounts
# Depuis le nœud (volumes hostPath / stockage local) : remonter jusqu'au chemin réel
kubectl get pvc <nom-pvc> -n <namespace> -o jsonpath='{.spec.volumeName}'
kubectl get pv <nom-pv> -o yaml | grep path
Une fois le volume identifié, localiser les gros fichiers à l'intérieur :
kubectl exec -it <nom-pod> -n <namespace> -- /bin/sh
du -sh /data/* | sort -rh | head -10
find /data -type f -size +100M -exec ls -lh {} \; | sort -k5 -rh
Script de vérification systématique
Pour balayer l'ensemble des PVC du cluster plutôt qu'un pod à la fois :
#!/bin/bash
# check-pvc-usage.sh
for ns in $(kubectl get ns -o jsonpath='{.items[*].metadata.name}'); do
for pvc in $(kubectl get pvc -n "$ns" -o jsonpath='{.items[*].metadata.name}'); do
echo "Namespace: $ns | PVC: $pvc"
pods=$(kubectl get pods -n "$ns" -o json \
| jq -r ".items[] | select(.spec.volumes[]?.persistentVolumeClaim.claimName==\"$pvc\") | .metadata.name")
for pod in $pods; do
echo " Pod: $pod"
kubectl exec -n "$ns" "$pod" -- df -h 2>/dev/null | grep -v Filesystem
done
capacity=$(kubectl get pvc "$pvc" -n "$ns" -o jsonpath='{.status.capacity.storage}')
echo " Capacité: $capacity"
done
done
Nettoyage
crictl rmi --prune # images containerd inutilisées
find /var/log/pods -name "*.log" -mtime +7 -delete # logs de plus de 7 jours — à exécuter avec prudence
Pour un PVC applicatif, le nettoyage (suppression de fichiers obsolètes, logs anciens de l'application) se fait en général au cas par cas via kubectl exec, l'application étant seule à savoir ce qui est purgeable.
Rotation des logs (prévention)
Éditer /etc/rancher/rke2/config.yaml pour borner la taille et le nombre de fichiers de logs conservés par kubelet, puis redémarrer le service :
kubelet-arg:
- "container-log-max-files=3"
- "container-log-max-size=10Mi"
systemctl restart rke2-agent # ou rke2-server selon le rôle du nœud
Agrandir un PVC
Possible uniquement si le StorageClass sous-jacent autorise l'expansion (allowVolumeExpansion: true) :
kubectl get storageclass
kubectl edit pvc <nom-pvc> -n <namespace> # modifier spec.resources.requests.storage
kubectl rollout restart deployment/<nom-deployment> -n <namespace>
Si le StorageClass ne permet pas l'expansion, la seule issue est de créer un nouveau PVC de taille suffisante et de migrer les données.
Prévention : limiter le stockage éphémère
Contraindre l'usage du stockage temporaire d'un pod évite qu'un seul workload mal maîtrisé sature un nœud entier :
resources:
limits:
ephemeral-storage: "4Gi"
requests:
ephemeral-storage: "2Gi"
Un script de supervision simple, exécuté périodiquement (cron, ou mieux, une alerte de supervision dédiée), permet d'être notifié avant que la situation ne devienne critique :
#!/bin/bash
# /usr/local/bin/check-disk.sh
THRESHOLD=85
USAGE=$(df -h / | awk 'NR==2 {print $5}' | sed 's/%//')
if [ "$USAGE" -gt "$THRESHOLD" ]; then
echo "ALERT: Disk usage at ${USAGE}%"
du -sh /var/lib/rancher/rke2/* | sort -rh | head -5
fi
Checklist de diagnostic
| # | Question | Commande |
|---|---|---|
| 1 | Quel nœud héberge le pod ? | kubectl get pods -A -o wide
|
| 2 | Quelle partition est pleine ? | df -h
|
| 3 | Les logs sous /var/log/pods sont-ils volumineux ? |
du -sh /var/log/pods/*
|
| 4 | Des images inutilisées traînent-elles ? | crictl images
|
| 5 | Le pod écrit-il beaucoup de données temporaires ? | kubectl exec ... -- df -h
|
| 6 | Un PVC est-il plein ? | kubectl exec ... -- df -h
|
| 7 | Les inodes sont-ils épuisés ? | df -i
|
Dépannage
- Pod injoignable via
kubectl exec— vérifier qu'il est bien à l'étatRunning, sinon passer parkubectl logsou une connexion directe au nœud. - PVC impossible à agrandir — vérifier
allowVolumeExpansionsur le StorageClass ; à défaut, migrer vers un nouveau PVC. - Les logs continuent de croître malgré tout — revérifier la configuration de rotation, limiter la verbosité applicative, ou déporter les logs vers une solution de log shipping externe (voir Fluentbit, Loki) plutôt que de les laisser s'accumuler localement.
Voir aussi
- Kubernetes troubleshooting — méthodologie de diagnostic plus générale (cluster, pods, réseau)
- Kubernetes rancher — spécificités RKE2 (emplacements, services systemd)
- Fluentbit · Loki — déporter les logs plutôt que les laisser saturer le disque local