BUT Informatique study materials
BUT Informatique study resources

Disque plein sur la VM de services : RAID1 et sauvegardes défaillantes

BUT Informatique · Put your knowledge to work in context.

All case studies

Disque plein sur la VM de services : RAID1 et sauvegardes défaillantes

Une VM Debian 12 (4 vCPU, 8 Go de RAM, un disque de 40 Go) héberge six services de l'IUT : nginx, une API Node, PostgreSQL 16, un runner GitLab, un serveur de fichiers et une application PHP. Ce matin, les utilisateurs signalent des erreurs 502 sur l'application PHP et l'API répond par intermittence. df -h indique 98 % d'occupation sur /var (39 Go sur 40). Le dossier /var/log contient 22 Go, dont 2,1 Go par jour produits par l'application PHP ; aucun fichier logrotate n'a été créé pour ce service. Le script de sauvegarde nocturne (cron, 2 h 00) écrit une archive de 6 Go dans /var/backups, sur le même disque, et échoue depuis 11 jours avec « No space left on device » ; le cron n'envoie un mail qu'en cas d'échec du script lui-même, pas de la commande. Le runner GitLab a 14 jobs bloqués en file. Le RAID1 matériel est en place et le responsable pense que cela suffit comme protection. Personne n'a testé de restauration depuis 18 mois.

1. Donnez l'ordre des actions immédiates (première heure) et justifiez chaque étape, notamment ce qu'il ne faut surtout pas supprimer.

Read the worked answer

1. Constater avant d'agir. df -h et df -i (un inode plein produit les mêmes symptômes), puis du -x -h --max-depth=1 /var pour localiser, et lsof +L1 pour repérer les fichiers supprimés encore ouverts : si un processus tient un descripteur sur un log déjà effacé, l'espace n'est pas rendu. C'est le piège classique d'un rm qui « ne libère rien ».

2. Libérer sans casser. Tronquer les logs applicatifs (: > fichier ou logrotate -f) plutôt que les supprimer, pour ne pas casser le descripteur ouvert. journalctl --vacuum-size=500M. Supprimer d'anciennes archives de sauvegarde après avoir vérifié qu'une sauvegarde récente est restaurable, et conserver la dernière bonne.

3. Ce qu'il ne faut pas faire. Supprimer des WAL ou des fichiers de /var/lib/postgresql : base irrécupérable. rm -rf /var/log/* : on perd les preuves d'incident et les descripteurs. Redémarrer PostgreSQL « pour voir » avant d'avoir de l'espace.

4. Restaurer le service. Une fois de l'espace rendu, recharger php-fpm et nginx pour les 502, et suspendre le runner GitLab (systemctl stop) : les 14 jobs en file ne feraient qu'aggraver le remplissage. Noter l'heure de début d'incident et prévenir les utilisateurs pour le post-mortem.

2. Le RAID1 est présent : pourquoi cela ne dispense-t-il pas de sauvegardes ? Proposez un plan de sauvegarde et de restauration réaliste pour cette VM.

Read the worked answer

RAID n'est pas sauvegarde. Le RAID1 protège contre la panne d'un disque, et rien d'autre : il ne protège ni d'un rm malheureux, ni d'une corruption logique, ni d'un rançongiciel, ni du remplissage disque. Ici, l'archive de sauvegarde est sur le même volume que les données : un seul incident détruit les deux copies. C'est précisément le scénario du jour, et le RAID n'a rien empêché.

Plan 3-2-1. Trois copies : production, sauvegarde locale sur un volume distinct, copie hors site (NAS d'un autre bâtiment ou stockage objet). Deux supports différents, une copie hors site. Contenu : pg_dump quotidien, et sauvegarde physique avec PITR si l'objectif de perte (RPO) doit descendre sous 24 h ; fichiers applicatifs ; configuration nginx et unités systemd. Rétention GFS (7 quotidiennes, 4 hebdomadaires, 3 mensuelles), chiffrement, somme de contrôle.

Le point qui a manqué : la supervision du succès. Le script doit utiliser set -euo pipefail, vérifier l'espace libre avant de commencer et remonter tout échec ; une alerte doit se déclencher si la taille de l'archive ou son horodatage est anormal. Enfin, un test de restauration trimestriel, chronométré et documenté : une sauvegarde jamais restaurée n'est pas une sauvegarde.

3. Proposez les correctifs durables pour que l'incident ne se reproduise pas, en distinguant configuration, architecture et supervision.

Read the worked answer

Configuration. Créer /etc/logrotate.d/app-php (daily, rotate 7, compress, copytruncate ou postrotate + reload) pour les 2,1 Go par jour ; plafonner journald avec SystemMaxUse=1G ; limiter le cache du runner GitLab dans config.toml. Chaque mesure répond à un symptôme constaté, pas à une bonne pratique abstraite.

Architecture. Séparer les partitions : /var/log et les sauvegardes ne doivent pas partager le volume de la base de données. La sauvegarde sort de la VM vers un hôte distinct. Un disque plein devient alors un incident local au lieu d'un arrêt de tous les services.

Supervision. Alerte à 80 % d'occupation (node_exporter + Prometheus, ou monit) pour agir avant la saturation ; alerte « sauvegarde absente ou de taille anormale depuis 24 h » ; sonde HTTP sur les endpoints critiques pour détecter les 502 avant les utilisateurs ; runbook « disque plein » versionné dans le dépôt d'exploitation, avec les commandes exactes et les interdits. Enfin, inscrire le test de restauration dans l'agenda de l'équipe avec un responsable nommé : c'est le seul indicateur qui dit la vérité sur la protection réelle.