Votre nœud Proxmox est « up », mais il n’est pas vivant. L’interface web rame. Le SSH met une éternité à renvoyer un caractère. Les VM se mettent en pause comme si elles réfléchissaient à leurs choix de vie. Top indique que le CPU est « idle », pourtant la machine est inutilisable car wa est bloqué à 100%.
C’est la classique prise d’otage par le stockage. L’objectif n’est pas de fixer le load average jusqu’à ce qu’il avoue. L’objectif est d’identifier quelle VM/container martèle le stockage (ou quel disque meurt), de le prouver par des preuves, et d’appliquer un correctif qui arrête les gels au niveau hôte — sans deviner et sans « redémarrer comme stratégie de monitoring ».
Ce que signifie réellement 100% I/O wait (et ce que cela n’est pas)
I/O wait est le CPU qui vous dit : « Je pourrais tourner, mais je suis bloqué en attente d’un achèvement d’E/S. » Sur un hôte Proxmox, cela signifie généralement que le noyau attend des E/S bloc (disques, SSD, NVMe, SAN, Ceph, vdevs ZFS), et tout ce qui est en amont (processus QEMU, charges LXC, journald, pvestatd, même l’interface web) se retrouve coincé derrière le même goulot.
Un iowait élevé n’est pas intrinsèquement « mauvais » lors d’un gros écrit séquentiel sur un array sain. Ce qui est problématique, c’est la combinaison d’un iowait élevé et de blocages visibles par les utilisateurs. Cela provient typiquement d’un des cas suivants :
- Explosion de latence : la demande d’IOPS dépasse ce que le stockage peut servir, la profondeur de file d’attente augmente, et tout commence à attendre.
- Pathologie du périphérique : un disque commence à temporiser, à se réinitialiser ou à remapper des secteurs ; la couche bloc attend, et votre hyperviseur aussi.
- Amplification d’écritures : petites écritures aléatoires plus couches copy-on-write (ZFS, QCOW2, thin provisioning) plus sémantique de sync = douleur.
- Charges concurrentes : jobs de sauvegarde, scrubs, resilvers, et « quelqu’un qui lance fio en production » (oui, ça arrive).
Deux clarifications importantes :
- 100% iowait ne signifie pas que le CPU est « occupé ». Cela signifie que vos threads exécutables sont bloqués sur des E/S. Vous pouvez avoir un CPU tranquille et un nœud complètement gelé.
- La load average peut exploser alors que l’utilisation CPU reste basse. Les tâches bloquées en sommeil non interruptible (souvent affichées avec l’état
D) comptent toujours dans la charge.
Réalité brute : si la latence du stockage passe de 1–5 ms à 500–5000 ms, votre hôte devient un drame monocœur peu importe le nombre de cœurs pour lesquels vous avez payé.
Playbook de diagnostic rapide (premier/deuxième/troisième)
Voici le flux « arrêter l’hémorragie ». Vous pouvez le faire en 5–15 minutes, même si l’hôte est lent.
Première étape : confirmer que c’est la latence stockage, pas le CPU ou la RAM
- Vérifier iowait et file d’exécution (
topouvmstat). - Vérifier la latence par disque et l’utilisation (
iostat -x). Si un périphérique est à ~100% d’utilisation avec un await important, vous avez trouvé le point d’étranglement. - Rechercher les tâches bloquées (
dmesg« blocked for more than » oupspour l’étatD). C’est la signature des iowaits qui figent le système.
Deuxième étape : identifier l’invité bruyant (VM/CT) qui cause la charge
- Trouver quel PID QEMU effectue des E/S (
pidstat -d,iotop). - Mapper ce PID au VMID (la ligne de commande QEMU inclut
-id, ouqm list+ args du processus). - Vérifier les stats I/O par invité Proxmox (
pvesh get /nodes/..., stats viaqm monitor, et métriques de stockage).
Troisième étape : choisir l’action de confinement la moins risquée
- Limiter l’I/O (préféré) : définir des limites disque pour la VM (
qm set) ou des limites cgroup IO pour LXC. - Mettre le guest en pause/suspension (rapide, réversible) :
qm suspendouqm stop --skiplocksi nécessaire. - Tuer le job de sauvegarde/scrub/resilver spécifique : arrêter le job qui surchauffe l’array, pas tout le nœud.
Règle pratique : si le nœud se fige, votre premier objectif est de retrouver le contrôle, pas d’avoir raison au sens philosophique.
Faits et contexte intéressants (ce qui explique les bizarreries)
- L’iowait Linux est une catégorie de comptabilité CPU, pas une métrique de stockage. Il dépend de ce que le scheduler pense que le CPU aurait pu faire pendant le blocage, donc ce n’est pas un nombre direct de « saturation disque ».
- L’état « D » (sommeil non interruptible) est le méchant du film depuis les débuts d’Unix. Les processus en attente d’E/S peuvent devenir effectivement impossibles à tuer jusqu’à ce que l’E/S se termine ou que le périphérique se réinitialise.
- ZFS a été conçu d’abord pour l’intégrité des données. Son modèle copy-on-write rend les « petits writes synchrone sur des pools fragmentés » un thème récurrent des postmortems de performance.
- Les snapshots QCOW2 sont pratiques mais peuvent multiplier la latence. Chaque écriture peut traverser des arbres de métadonnées, et de longues chaînes de snapshots se détériorent vite.
- Les « slow ops » de Ceph sont souvent un système d’alerte précoce. Quand les OSD ou le réseau sont mal en point, la latence monte bien avant la panne complète ; ignorer les slow ops, c’est s’inscrire au panthéon des pannes.
- Barrières d’écriture et flush existent parce que la perte de données est pire que la lenteur. Si votre stockage ment sur la durabilité (cache mal configuré, protection contre la perte de puissance manquante), vous aurez un système rapide jusqu’au jour où vous ne l’aurez plus.
- Les événements de « rebuild » sont des événements de performance. Les resilvers RAID, scrubs ZFS et backfills Ceph changent les patterns d’I/O et peuvent affamer les workloads au premier plan s’ils ne sont pas réglés.
- Les hyperviseurs amplifient les problèmes de stockage. Un SSD qui meurt peut bloquer des dizaines d’invités parce que leurs I/O partagent le même noyau et la même file bloc.
- La couche bloc a beaucoup évolué. Multi-queue (blk-mq) et les planificateurs modernes améliorent le throughput, mais ils ne peuvent pas corriger un périphérique qui renvoie une latence de 2 secondes.
Tâches pratiques : commandes, sorties, décisions (12+)
Ce sont des commandes réelles que vous pouvez exécuter sur un hôte Proxmox. Chaque tâche inclut ce qu’il faut rechercher et quelle décision prendre ensuite.
Task 1: Confirmer rapidement iowait et tâches bloquées
cr0x@server:~$ top -b -n1 | head -n 15
top - 11:24:31 up 47 days, 3:12, 2 users, load average: 54.12, 49.88, 41.03
Tasks: 412 total, 3 running, 409 sleeping, 0 stopped, 0 zombie
%Cpu(s): 1.2 us, 0.6 sy, 0.0 ni, 0.1 id, 98.0 wa, 0.0 hi, 0.1 si, 0.0 st
MiB Mem : 128642.5 total, 12211.7 free, 44210.2 used, 72220.6 buff/cache
MiB Swap: 8192.0 total, 8170.5 free, 21.5 used. 84044.3 avail Mem
Ce que cela signifie : Le CPU attend majoritairement. La charge est massive. Cela correspond à de la latence stockage ou des I/O bloqués.
Décision : Passez à la latence par périphérique (iostat -x) et aux I/O par processus (pidstat/iotop). Ne chasser pas le tuning CPU.
Task 2: Voir la file d’exécution et la tendance iowait
cr0x@server:~$ vmstat 1 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
2 38 0 1249876 89244 72133840 0 0 118 9432 712 1843 1 1 0 98 0
1 41 0 1249804 89244 72133912 0 0 104 10288 680 1721 1 1 0 98 0
2 39 0 1249812 89244 72133980 0 0 112 9816 705 1802 1 1 0 98 0
1 40 0 1249820 89244 72134012 0 0 96 11024 690 1760 1 1 0 98 0
Ce que cela signifie : La colonne b (processus bloqués) est énorme. C’est votre gel d’hôte en chiffres.
Décision : Vérifiez l’utilisation disque et l’await. Si un seul périphérique est le goulot, isolez-le. Si c’est distribué, suspectez une saturation du backend (Ceph/réseau) ou un pattern de workload (writes sync, sauvegarde).
Task 3: Trouver le périphérique chaud avec un iostat étendu
cr0x@server:~$ iostat -x 1 3
Linux 6.8.12-4-pve (server) 12/26/2025 _x86_64_ (32 CPU)
Device r/s w/s rkB/s wkB/s rrqm/s wrqm/s %rrqm %wrqm r_await w_await aqu-sz rareq-sz wareq-sz svctm %util
nvme0n1 12.0 2100.0 512.0 89200.0 0.0 220.0 0.0 9.5 3.2 740.5 1555.2 42.7 42.5 0.45 99.9
nvme1n1 10.0 14.0 480.0 620.0 0.0 1.0 0.0 6.7 2.8 4.1 0.1 48.0 44.3 0.18 0.4
Ce que cela signifie : nvme0n1 est à 99.9% d’utilisation avec un await d’écriture d’environ 740 ms et une file massive. Ce n’est pas « occupé » ; c’est « en souffrance ».
Décision : Identifiez quel workload génère ces écritures. Vérifiez aussi les logs du noyau et SMART pour des problèmes matériel. Une latence aussi élevée peut venir d’une saturation, mais aussi d’un disque qui meurt.
Task 4: Confirmer si le noyau rapporte des erreurs ou réinitialisations d’I/O
cr0x@server:~$ dmesg -T | tail -n 30
[Thu Dec 26 11:23:12 2025] nvme nvme0: I/O 332 QID 4 timeout, aborting
[Thu Dec 26 11:23:12 2025] nvme nvme0: Abort status: 0x371
[Thu Dec 26 11:23:13 2025] nvme nvme0: resetting controller
[Thu Dec 26 11:23:16 2025] EXT4-fs warning (device dm-3): ext4_end_bio:351: I/O error 10 writing to inode 262148 starting block 11534336)
[Thu Dec 26 11:23:18 2025] task jbd2/dm-3-8:219 blocked for more than 120 seconds.
[Thu Dec 26 11:23:18 2025] Tainted: P O 6.8.12-4-pve #1
Ce que cela signifie : Les timeouts et réinitialisations de contrôleur ne sont pas des problèmes de tuning de workload. Ce sont des problèmes « matériel ou firmware qui fond ». L’avertissement de tâche bloquée explique le gel.
Décision : Si vous voyez des timeouts/réinitialisations, traitez le périphérique comme suspect immédiatement : réduisez les I/O, migrez les invités, et planifiez le remplacement. Ne passez pas une heure à tuner l’algorithme d’ascenseur sur un disque qui timeoute activement.
Task 5: Vérifier rapidement SMART/NVMe (triage rapide)
cr0x@server:~$ smartctl -a /dev/nvme0n1 | egrep -i 'critical_warning|media_errors|num_err_log_entries|percentage_used|power_on|temperature'
Critical Warning: 0x00
Temperature: 73 Celsius
Percentage Used: 89%
Power On Hours: 31211
Media and Data Integrity Errors: 18
Error Information Log Entries: 294
Ce que cela signifie : Usure élevée (Percentage Used), erreurs média et un journal d’erreurs croissant indiquent un périphérique proche de la retraite.
Décision : Priorisez l’évacuation des VM critiques. Planifiez une fenêtre de remplacement. Si c’est un mirror ZFS/RAID, lancez un remplacement contrôlé plutôt que d’attendre une défaillance dramatique aux heures de pointe.
Task 6: Identifier quels processus effectuent des E/S disque maintenant
cr0x@server:~$ pidstat -d 1 5
Linux 6.8.12-4-pve (server) 12/26/2025 _x86_64_ (32 CPU)
11:25:44 AM UID PID kB_rd/s kB_wr/s kB_ccwr/s iodelay Command
11:25:45 AM 0 2911 0.00 68420.00 11200.00 98765 qemu-system-x86
11:25:45 AM 0 4187 0.00 10240.00 1800.00 12001 vzdump
11:25:45 AM 0 1332 0.00 220.00 12.00 210 pvestatd
Ce que cela signifie : Un processus QEMU est le principal écrivain ; vzdump est aussi actif (sauvegarde). iodelay est énorme, signifiant que le processus passe beaucoup de temps en attente de complétion d’I/O.
Décision : Mappez le PID 2911 au VMID. Si des sauvegardes tournent, décidez si vous devez les mettre en pause/arrêter pour restaurer la réactivité de l’hôte.
Task 7: Mapper un PID QEMU à un VMID
cr0x@server:~$ ps -p 2911 -o pid,cmd --no-headers
2911 /usr/bin/kvm -id 113 -name vm113-db01,debug-threads=on -m 16384 -smp 8,sockets=1,cores=8 -drive file=/dev/zvol/rpool/data/vm-113-disk-0,if=none,id=drive-scsi0,cache=none,aio=io_uring,discard=on,format=raw
Ce que cela signifie : C’est la VM 113. Le disque est un ZVOL. Le cache est en none, l’I/O asynchrone est io_uring. Rien de tout cela n’a d’importance si le périphérique timeoute, mais ça compte si vous êtes simplement en saturation.
Décision : Récupérez les stats VM 113 et décidez : limiter, mettre en pause ou migrer. Pendant ce temps, confirmez si VM 113 participe aussi à la sauvegarde.
Task 8: Vérifier le débit disque et les indicateurs de latence au niveau Proxmox
cr0x@server:~$ qm status 113 --verbose
status: running
name: db01
cpus: 8
memory: 16384
uptime: 192773
net0: virtio=DE:AD:BE:EF:11:30,bridge=vmbr0
diskread: 0.00
diskwrite: 68.42
diskread_bytes: 0
diskwrite_bytes: 73408602112
Ce que cela signifie : Proxmox rapporte un débit d’écriture élevé. Il n’affiche pas la latence, mais confirme le « qui ».
Décision : Contenez la VM 113. Si c’est une base de données ou une pipeline de logs, elle peut générer des fsync fréquents qui punissent un pool dégradé.
Task 9: Vérifier si un job de sauvegarde est le coupable secondaire
cr0x@server:~$ pgrep -af vzdump
4187 /usr/bin/perl /usr/bin/vzdump --all 1 --mode snapshot --compress zstd --storage backup-nfs --mailnotification failure
4231 /usr/bin/pigz -p 4
Ce que cela signifie : Un vzdump node-wide est en cours. Le mode snapshot peut quand même générer de lourdes lectures et écritures metadata, surtout avec QCOW2 ou des datasets ZFS occupés.
Décision : Si le nœud se fige, arrêtez la sauvegarde en premier (c’est une charge discrétionnaire) plutôt que de tuer des invités de production.
Task 10: Arrêter ou mettre en pause proprement la sauvegarde (confinement)
cr0x@server:~$ kill -TERM 4187
cr0x@server:~$ tail -n 5 /var/log/vzdump/vzdump.log
INFO: vzdump job finished
ERROR: job aborted by signal
INFO: cleanup temporary directory '/var/tmp/vzdumptmp4187'
Ce que cela signifie : Vous avez annulé la sauvegarde. Cela devrait réduire rapidement la pression I/O, mais si l’array/périphérique est malsain vous pourriez rester coincé.
Décision : Re-vérifiez iostat -x. Si l’await baisse et que l’hôte récupère, vous avez gagné du temps pour analyser la cause racine sans que les utilisateurs hurlent dans le chat.
Task 11: Limiter la VM bruyante (confinement préféré)
cr0x@server:~$ qm set 113 --scsi0 rpool:vm-113-disk-0,iops=800,mbps=40
update VM 113: -scsi0 rpool:vm-113-disk-0,iops=800,mbps=40
Ce que cela signifie : Vous plafonnez le débit disque de la VM, donnant au nœud et aux autres invités une chance de respirer. Ce n’est pas une « correction » de perf, c’est du contrôle du rayon d’impact.
Décision : Si la limitation stabilise la latence, maintenez-la pendant que vous enquêtez sur le workload de l’invité (ex. : logs runaway, orage de checkpoints DB) et la santé du stockage.
Task 12: Pour les containers LXC, trouver le plus gros écrivain I/O et mapper au CTID
cr0x@server:~$ iotop -oPa -n 5
Total DISK READ: 0.00 B/s | Total DISK WRITE: 92.15 M/s
PID PRIO USER DISK READ DISK WRITE SWAPIN IO> COMMAND
8432 be/4 root 0.00 B/s 68.42 M/s 0.00 % 99.99 % [kvm]
9211 be/4 root 0.00 B/s 18.11 M/s 0.00 % 95.00 % [kworker/u64:3]
10222 be/4 root 0.00 B/s 4.10 M/s 0.00 % 60.00 % [lxcfs]
Ce que cela signifie : QEMU est le monstre. Mais si vous voyiez un processus de container ici, vous le mapperiez ensuite via les cgroups ou en corrélant montages et PIDs.
Décision : Si c’est un container, utilisez pct status et pct config plus les stats cgroup I/O pour localiser et limiter.
Task 13: Vérifier la santé du pool ZFS et le travail de maintenance en cours qui peut voler des I/O
cr0x@server:~$ zpool status -v
pool: rpool
state: DEGRADED
status: One or more devices has experienced an unrecoverable error. An attempt was made to correct the error.
action: Replace the device using 'zpool replace'.
scan: scrub in progress since Thu Dec 26 09:12:02 2025
2.31T scanned at 652M/s, 1.98T issued at 559M/s, 6.12T total
0B repaired, 32.35% done, 2:11:44 to go
config:
NAME STATE READ WRITE CKSUM
rpool DEGRADED 0 0 0
mirror-0 DEGRADED 0 0 0
nvme0n1 FAULTED 2 18 0 too many errors
nvme1n1 ONLINE 0 0 0
errors: No known data errors
Ce que cela signifie : Le pool est dégradé, un scrub est en cours, et un NVMe est faulted. C’est une recette parfaite pour des pics de latence et des gels d’hôte.
Décision : Arrêtez ou reportez le scrub s’il nuit à la disponibilité, puis remplacez le périphérique fautif. La disponibilité d’abord ; le travail d’intégrité reprend une fois le système repu d’air.
Task 14: Voir quels datasets/zvols ZFS sont les plus actifs
cr0x@server:~$ zfs iostat -v rpool 1 3
capacity operations bandwidth
pool alloc free read write read write
-------------- ----- ----- ----- ----- ----- -----
rpool 5.01T 1.11T 120 2200 4.8M 89.2M
rpool/ROOT 18.2G 97.8G 2 18 64K 2.1M
rpool/data 4.99T 1.01T 118 2182 4.7M 87.1M
vm-113-disk-0 420G 80.0G 12 1620 512K 68.4M
vm-105-disk-0 210G 30.0G 8 260 384K 11.2M
Ce que cela signifie : Vous voyez le zvol le plus chaud : vm-113-disk-0. Cela confirme l’invité bruyant avec une télémétrie au niveau stockage.
Décision : Concentrez-vous sur le workload de VM 113 et envisagez de déplacer son disque vers un pool moins sollicité, ou de modifier son pattern d’écriture (tuning DB), ou d’appliquer des throttles soutenus.
Task 15: Si Ceph est impliqué, vérifier l’état et les slow ops
cr0x@server:~$ ceph -s
cluster:
id: 3f0c2c2d-7f8b-4d17-9e21-2a7d3c3b2a91
health: HEALTH_WARN
2 osds down
154 slow ops, oldest one blocked for 37 sec, osd.12 has slow ops
services:
mon: 3 daemons, quorum mon1,mon2,mon3
mgr: mgr1(active)
osd: 12 osds: 10 up, 10 in
data:
pools: 6 pools, 256 pgs
objects: 4.12M objects, 15 TiB
usage: 46 TiB used, 18 TiB / 64 TiB avail
pgs: 12 pgs degraded, 9 pgs undersized
Ce que cela signifie : Ceph signale des slow ops et des OSD down. Cela se manifestera par de l’iowait sur les nœuds hyperviseurs utilisant RBD, car les lectures/écritures bloquent sur le cluster.
Décision : Un problème Ceph prime sur un problème VM. Stabilisez le cluster (OSD, réseau, limites de backfill) avant d’accuser un invité.
Trouver la VM ou le conteneur bruyant (pour de vrai)
« Voisin bruyant » est une formule polie pour « une VM bouffe le sous-système stockage et tout le monde paye l’addition. » Sur Proxmox, vous avez trois angles pratiques pour le trouver :
- Angle processus : quel PID fait des I/O ? (qemu-system-x86, outils de backup, zfs, ceph-osd).
- Angle objet stockage : quel volume est le plus chaud ? (nom ZVOL, image RBD, LV LVM, fichier qcow2).
- Angle invité Proxmox : quel VMID/CTID rapporte un débit disque élevé ?
The process angle: QEMU is usually the smoking gun
Sur un nœud typique, chaque VM se mappe à un processus qemu-system-x86. Si ce processus écrit 60–200 MB/s sur un périphérique incapable de le soutenir, l’iowait monte. Si le périphérique commence à timeouter, l’hôte se fige. Votre objectif est d’attacher l’I/O à un VMID rapidement.
Quand l’hôte est lent, évitez les commandes coûteuses et « larges ». Préférez des requêtes ciblées :
pidstat -d 1 5est peu coûteux et vous donne une liste classée.ps -p PID -o cmdvous donne le VMID rapidement.iostat -xvous dit si c’est de la saturation ou de la pathologie.
Une plaisanterie en passant : si votre hôte est à 100% iowait, votre CPU n’est pas « inactif ». Il pratique la pleine conscience pendant que les disques paniquent.
L’angle objet stockage : mapper les volumes chauds aux invités
Selon votre backend, « la chose chaude » ressemble à :
- ZFS zvol :
rpool/data/vm-113-disk-0(parfaitement évident). - QCOW2 sur stockage en répertoire : un fichier comme
/var/lib/vz/images/113/vm-113-disk-0.qcow2. - LVM-thin : un LV comme
/dev/pve/vm-113-disk-0. - Ceph RBD : une image comme
vm-113-disk-0dans un pool.
L’astuce est de travailler en sens inverse : identifier le périphérique chaud, puis le volume logique chaud, puis le VMID, puis le workload à l’intérieur de l’invité.
L’angle invité Proxmox : stats rapides par invité
Proxmox peut afficher le débit disque par invité, ce qui est utile mais pas suffisant. Le débit n’est pas le vilain ; la latence l’est. Pourtant, le débit par invité est une excellente liste « qui dois-je interroger ».
cr0x@server:~$ qm list
VMID NAME STATUS MEM(MB) BOOTDISK(GB) PID
105 app01 running 8192 120 2144
113 db01 running 16384 500 2911
127 ci-runner01 running 4096 80 3382
Ce que cela signifie : Vous avez les VMIDs et PIDs ; vous pouvez maintenant marier cela avec la sortie de pidstat/iotop.
Décision : Choisissez l’invité avec le PID QEMU le plus chaud, puis vérifiez au niveau stockage quel volume il touche. Ne « stoppez pas au hasard la plus grosse VM » à moins d’aimer les interruptions inutiles.
Modes de défaillance des backends de stockage : ZFS, Ceph, LVM-thin, NFS/iSCSI
ZFS sur Proxmox : les suspects habituels
ZFS est excellent pour dire la vérité sur les données. Il est moins indulgent face aux workloads sync-heavy et random-write-heavy sur des SSD grand public. Sur Proxmox, les incidents de performance ZFS tombent souvent dans ces catégories :
- Vdev dégradé ou périphérique en panne : pics de latence et timeouts, surtout en écriture.
- Contestation scrub/resilver : le travail en arrière-plan concurrence les invités pour les I/O et peut affamer les workloads sensibles à la latence.
- Pression d’écritures sync : les bases de données et certains systèmes de fichiers forcent des flushs fréquents ; sans SLOG approprié (et des attentes correctes), les écritures se serialisent.
- Fragmentation et petits blocs : des pools anciens avec beaucoup de churn peuvent dégrader les I/O aléatoires, surtout sur HDD.
Opérationnellement, ZFS est amiable car il fournit zpool status et zfs iostat réellement utiles pendant un incident. Servez-vous-en.
Ceph : quand le réseau fait partie de votre disque
Avec Ceph, un iowait élevé sur l’hyperviseur peut n’avoir rien à voir avec les disques locaux. Cela peut être :
- OSD down ou qui flap provoquant des PGs dégradés et des slow ops.
- Orages de backfill/recovery saturant le réseau ou les disques.
- Utilisation inégale des OSD (hotspotting) due à des problèmes CRUSH ou un petit nombre d’images volumineuses.
- Problèmes réseau (drops, MTU mismatch, exhaustion des buffers) transformant le « stockage » en ville des retransmissions.
Si Ceph signale « slow ops », écoutez-le. L’iowait n’est que le messager. Ne le tuez pas ; réparez le cluster.
LVM-thin : la douleur des métadonnées est réelle
LVM-thin peut être rapide et simple. Il peut aussi ruiner votre après-midi quand les métadonnées du thin-pool sont serrées ou que le pool se remplit. Quand la thin provisioning approche la capacité, vous pouvez voir des stalls soudains, des pauses d’allocation et des pics de latence pour les invités.
Règle pratique : gardez les thin pools confortablement en dessous de 80–85% sauf si vous avez un monitoring solide et une procédure d’extension testée.
NFS/iSCSI : « le disque est OK » (chez quelqu’un d’autre)
Les pannes de stockage réseau sont belles parce qu’elles permettent de débattre avec une autre équipe pendant que votre nœud se fige.
Surveillez :
- Saturation d’un point de montage unique : une tête NFS devient le goulot.
- Congestion réseau : les micro-bursts peuvent gonfler la latence de façon dramatique.
- Timeouts HBA/driver sur iSCSI/Fibre Channel qui apparaissent dans les logs noyau et tâches bloquées.
Trois mini-histoires d’entreprise issues du terrain
Mini-histoire 1 : L’incident causé par une mauvaise hypothèse
Ils avaient un petit cluster Proxmox avec un mélange d’apps web et une seule VM de base de données « importante ». Le stockage était des miroirs ZFS locaux sur NVMe. Tout avait été stable pendant des mois, donc l’hypothèse s’est figée en dogme : « NVMe signifie que le stockage ne peut pas être le goulot. »
Un lundi matin, le nœud a commencé à se figer. L’équipe a cherché le CPU, puis la RAM, puis le réseau. Ils ont redémarré quelques services. Ils ont même blâmé la version du noyau. Pendant ce temps, l’iowait restait à 90–100% et les VM bégayaient. Personne n’a regardé dmesg tôt parce que « le matériel est récent ».
Quand quelqu’un a finalement lancé dmesg -T, c’était un mur de timeouts NVMe et de réinitialisations de contrôleur. Le disque n’était pas « lent ». Il disparaissait et réapparaissait sous charge, créant de longs stalls d’I/O qui coinçaient les tâches en état D. La VM base de données n’était pas la cause racine ; c’était juste le workload qui a déclenché les défaillances.
La correction était ennuyeuse : évacuer les VM critiques, remplacer le NVMe, et mettre à jour le firmware des disques restants. Le postmortem était plus intéressant : leur supervision regardait seulement le débit et l’espace, pas la latence et les taux d’erreurs. Ils avaient confondu « interface rapide » avec « périphérique fiable ».
Mini-histoire 2 : L’optimisation qui a mal tourné
Une autre org voulait des sauvegardes plus rapides. Ils ont changé leur planning de vzdump pour courir plus fréquemment et ont augmenté la compression au maximum parce que le stockage « coûtaît cher ». Ils ont aussi activé plus de snapshots sur les disques QCOW2 parce que c’était pratique pour les développeurs.
Au début, c’était un succès apparent : les tailles de sauvegarde ont baissé, et les restaurations « fonctionnaient ». Puis, quelques semaines après, des plaintes de performance sont apparues en heures de bureau. Pas constantes, mais suffisantes pour être gênantes. Le graphe montrait des pics de latence récurrents, et chaque pic coïncidait avec les sauvegardes.
Voici ce qui s’est passé : la combinaison snapshot-heavy QCOW2 + compression de sauvegarde agressive a créé une tempête parfaite de lectures aléatoires et de churn metadata. Le job de sauvegarde ne faisait pas que lire ; il forçait le stockage à naviguer des métadonnées de snapshot complexes pendant que d’autres VM faisaient leurs écritures normales. Sous charge, l’hôte passait plus de temps à attendre des I/O qu’à faire du travail.
La correction a été de reculer sur l’« optimisation » : réduire les chaînes de snapshot, passer certaines VM critiques en raw quand approprié, limiter la concurrence des sauvegardes, et planifier les sauvegardes lourdes hors heures de travail. La compression est restée, mais pas au détriment de la latence de production. Ils ont appris que « optimiser la taille des sauvegardes » peut être indiscernable de « optimiser pour des pannes ».
Mini-histoire 3 : La pratique ennuyeuse mais correcte qui a sauvé la journée
Une équipe qui gère un cluster Proxmox pour des services internes avait une règle simple : tout changement de backend de stockage nécessitait une baseline de latence et un plan de rollback. Pas long. Une page avec « nombres avant », « nombres après », et « comment annuler ».
Un après-midi, l’iowait a monté sur un nœud. L’on-call n’a pas débattu la théorie. Ils ont exécuté les mêmes commandes de base qu’ils lancent toujours : iostat -x, zpool status, zfs iostat, et une vérification rapide des sauvegardes. En cinq minutes ils ont vu : scrub en cours, un vdev montrant une latence élevée, et un seul zvol VM dominant les écritures.
Ils ont limité la VM, mis le scrub en pause, et migré deux invités sensibles à la latence hors du nœud. L’hôte a récupéré immédiatement. Puis ils ont remplacé le SSD suspect pendant une fenêtre planifiée.
Pas d’héroïsme. Pas de conjectures. La partie ennuyeuse — l’habitude de garder une baseline et une checklist d’incident courte — a évité la spirale « on devrait redémarrer » et a contenu l’impact utilisateur.
Erreurs courantes : symptômes → cause racine → correctif
-
Syndrome : iowait 100%, nœud « figé », load average énorme.
Cause racine : tâches bloquées à cause de timeouts/réinitialisations disque (problème matériel/firmware).
Correctif : Vérifierdmesg, lancersmartctl, évacuer les invités, remplacer/mettre à jour le firmware du périphérique. Arrêter scrubs/resilvers pendant l’incident. -
Syndrome : Le nœud ne répond qu’en période de sauvegarde.
Cause racine : trop de concurrence vzdump, QCOW2 snapshot-heavy, stockage de sauvegarde lent, ou goulot NFS.
Correctif : Réduire la concurrence des sauvegardes, échelonner les jobs, limiter l’I/O, envisager raw pour les VM chaudes, s’assurer que la cible de sauvegarde a assez d’IOPS et de bande passante réseau. -
Syndrome : Une VM est lente, les autres se dégradent aussi.
Cause racine : voisin bruyant saturant la file de stockage partagée (vdev unique, SSD unique, ou metadata thin pool).
Correctif : Limiter la VM, la déplacer vers un stockage plus rapide/isolé, corriger le workload invité (tempête de logs, checkpoints DB). -
Syndrome : VMs sur Ceph ont des pauses aléatoires de plusieurs secondes.
Cause racine : slow ops Ceph dues à OSD down/backfill/recovery ou problèmes réseau.
Correctif : Résoudre l’état Ceph d’abord : restaurer les OSD, tuner recovery/backfill, vérifier MTU et pertes réseau, réduire temporairement l’I/O cliente. -
Syndrome : Pics de latence pendant scrub/resilver ZFS.
Cause racine : travail background qui concurrence les I/O invité ; mirror/RAID dégradé amplifie cela.
Correctif : Planifier les scrubs hors heures, envisager de tuner la priorité de scrub, et ne pas lancer de scrubs quand le pool est dégradé sauf nécessité. -
Syndrome : Beaucoup d’espace libre, mais I/O affreux ; petits writes particulièrement mauvais.
Cause racine : workload d’écritures sync (fsync) sans conception appropriée ; les SSD grand public peuvent étouffer sous écritures sync soutenues ; pression des transaction groups ZFS.
Correctif : Vérifier les réglages applicatifs invités (journaling, paramètres de durabilité DB), assurer du matériel adapté aux workloads sync, et éviter « juste mettre sync=disabled » sauf si vous acceptez explicitement la perte de données.
Checklists / plan étape par étape
Checklist de confinement d’incident (10–30 minutes)
- Exécuter
topetvmstatpour confirmer un iowait élevé et des tâches bloquées. - Exécuter
iostat -x 1 3pour identifier le périphérique le plus chaud et observer await/util. - Vérifier
dmesg -T | tailpour timeouts, réinitialisations, erreurs I/O. - Identifier les processus I/O principaux avec
pidstat -douiotop. - Mapper le PID QEMU lourd au VMID via
pset/ouqm list. - Arrêter d’abord les charges discrétionnaires : sauvegardes (
vzdump), scrubs/resilvers, jobs batch. - Limiter la VM/CT bruyante (limites I/O) plutôt que de l’arrêter, si possible.
- Si erreurs matériel : migrer les invités critiques hors du nœud, marquer le périphérique pour remplacement.
- Re-vérifier
iostat -x: l’await doit baisser rapidement si vous avez retiré la pression. - Enregistrer ce que vous avez fait et pourquoi. Le vous du futur est un stakeholder.
Checklist cause racine (même jour)
- Était-ce une défaillance de périphérique, une saturation backend, ou un pic de workload ?
- Quel invité ou processus hôte a le plus contribué ?
- Qu’est-ce qui a changé récemment (sauvegardes, snapshots, kernel/firmware, nouveau workload) ?
- Avez-vous des métriques de latence (pas seulement débit) par périphérique et par backend ?
- La topologie de stockage est-elle appropriée (vdev unique pour beaucoup de VM, thin pool proche du plein, Ceph dégradé) ?
- Avez-vous besoin de limites I/O par VM par défaut sur le stockage partagé ?
Checklist prévention (cette semaine)
- Définir des limites I/O raisonnables pour les workloads « non fiables » (CI, collecteurs de logs, tout ce qui est contrôlé par des développeurs).
- Planifier sauvegardes et scrubs hors heures de pointe ; limiter la concurrence.
- Surveiller la latence et les erreurs : await par disque, erreurs SMART, Ceph slow ops, états ZFS dégradés.
- Garder le sprawl de snapshots sous contrôle ; purger les snapshots QCOW2 et éviter les longues chaînes.
- Planifier de la marge pour le stockage (IOPS et capacité). Tourner à fond n’est pas une optimisation de coût ; c’est un choix de fiabilité.
FAQ
- 1) Pourquoi Proxmox « se fige » quand le stockage est lent ?
- Parce que l’hôte et les invités partagent le même noyau et les mêmes chemins I/O. Quand les E/S bloc se bloquent, les services critiques (y compris QEMU et les démons système) se bloquent en état D, et le nœud devient non réactif.
- 2) Est-ce que 100% iowait est toujours un problème de disque ?
- Non. C’est un problème d’« achèvement d’I/O tardif ». Cela peut être le disque local, le contrôleur RAID, le cluster Ceph, le serveur NFS, le chemin iSCSI, ou même une pression mémoire sévère provoquant des I/O de swap. Mais c’est presque toujours « latence du chemin stockage ».
- 3) Quelle est la façon la plus rapide de trouver la VM bruyante ?
- Utilisez
pidstat -douiotoppour trouver le PID QEMU qui fait le plus d’I/O, puis mappez-le au VMID via la ligne de commande du processus (-id) ouqm list. - 4) Dois-je juste redémarrer l’hôte Proxmox ?
- Seulement si vous acceptez la downtime des invités et que vous ne pouvez pas retrouver le contrôle. Les redémarrages masquent les preuves et ne corrigent pas les périphériques en panne ni les backends saturés. Si vous voyez des timeouts dans
dmesg, un reboot peut acheter des minutes, pas une solution. - 5) Puis-je réparer cela en changeant le scheduler I/O ?
- Parfois cela aide en marge. Cela ne corrigera pas les timeouts, le matériel défaillant, ou un backend incapable de fournir les IOPS/latence requis. Diagnostiquez d’abord. Tuner après.
- 6) Est-ce sûr de définir ZFS
sync=disabledpour réduire l’iowait ? - C’est « sûr » seulement si vous êtes prêt à perdre des écritures récentes en cas de perte de puissance ou de crash. Pour beaucoup de bases de données et systèmes de fichiers, ce n’est pas un risque théorique. Si vous le faites, documentez-le comme un compromis explicite de durabilité.
- 7) Pourquoi les sauvegardes causent-elles autant de problèmes ?
- Les sauvegardes sont trompeusement lourdes : elles lisent beaucoup, touchent les métadonnées, et peuvent interagir très mal avec les snapshots et les couches copy-on-write. Si la cible de sauvegarde est lente, le côté source peut aussi se bloquer.
- 8) Comment empêcher qu’une VM n’abatte le nœud ?
- Utilisez le throttling I/O par disque pour chaque VM, isolez les workloads I/O élevés sur du stockage dédié, et imposez des plannings de sauvegarde/scrub. Surveillez aussi la latence et les erreurs pour détecter la dégradation avant qu’elle ne devienne un gel.
- 9) Et si plusieurs périphériques montrent un await élevé ?
- Alors le goulot peut être au-dessus de la couche périphérique : un contrôleur partagé, un thin pool, Ceph/réseau, ou une congestion writeback système. Confirmez avec les outils spécifiques au backend (ZFS/Ceph) et vérifiez s’il y a un processus dominant.
- 10) Comment savoir si c’est saturation ou disque en train de mourir ?
- La saturation montre généralement une util élevée et un await élevé sans timeouts/réinitialisations dans
dmesg. Un disque mourant montre souvent des timeouts, des réinitialisations, des erreurs I/O, et des erreurs SMART qui augmentent.
Conclusion : prochaines étapes qui réduisent vraiment les incidents
Vous ne « réparez » pas l’iowait. Vous réparez le chemin stockage et le comportement des workloads qui ont créé une latence inacceptable. Commencez par le playbook rapide : prouvez que c’est de la latence I/O, identifiez l’invité bruyant, conservez le rayon d’impact, puis décidez si vous êtes face à une saturation ou à une défaillance.
Prochaines étapes pratiques :
- Ajouter des limites I/O par VM pour les suspects habituels (CI, ingestion de logs, tout workload batch).
- Rendre la latence visible : await/util iostat, état des pools ZFS, slow ops Ceph, compteurs d’erreurs SMART.
- Arrêter de traiter les sauvegardes comme du travail « gratuit ». Limitez la concurrence et planifiez-les comme de la maintenance — parce que c’en est une.
- Remplacer les périphériques défaillants tôt. Attendre la panne totale n’est pas du courage ; c’est de la paperasserie.
Une dernière petite plaisanterie : la seule chose pire qu’une VM voisine bruyante est une qui est silencieuse — parce qu’elle peut déjà être coincée en état D et vous tenir votre hôte en otage en silence.
Citation (idée paraphrasée) : Gene Kranz : « Be tough and competent. » En termes d’ops : mesurer d’abord, puis agir avec décision.