Kubernetes fs

De wiki.nexiat.fr
Aller à la navigation Aller à la recherche
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'état Running, sinon passer par kubectl logs ou une connexion directe au nœud.
  • PVC impossible à agrandir — vérifier allowVolumeExpansion sur 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