Tout paraît « normal » jusqu’à ce que ça ne le soit plus : la VM a beaucoup de RAM configurée, le CPU s’ennuie, le disque est rapide, et pourtant la latence grimpe. Votre base de données commence à se comporter comme si elle tournait sur une clé USB. L’invité signale une pression mémoire, le swap augmente, les caches disparaissent et vos graphiques ressemblent à un électrocardiogramme.
Puis vous remarquez : le ballooning est activé. Quelqu’un a cru que c’était une « efficacité gratuite ». Ce que cela a réellement apporté, c’est une rareté synthétique — une pression mémoire fabriquée par l’hyperviseur que le système invité ne peut pas comprendre, seulement subir.
Ballooning en une phrase (et pourquoi il faut se montrer méfiant)
Le ballooning permet à l’hôte de récupérer de la RAM depuis une VM en forçant l’invité à « utiliser » de la mémoire en interne, ce qui pousse le système invité à libérer ses propres pages.
Cela paraît civilisé — comme emprunter une chaise à une fête. En pratique, l’hôte arrache les coussins du canapé pendant que vous êtes assis, et l’invité ne sait pas si les coussins étaient du cache « gratuit » ou une partie critique de son jeu de travail.
Règle d’opinion : si vous exécutez quelque chose d’état ou sensible à la latence (bases de données, moteurs de recherche, brokers, runners CI avec caches chauds, ZFS dans les invités, serveurs de fichiers Windows), le ballooning est généralement une taxe inutile. Achetez de la RAM. Ou réduisez volontairement les VM. Ne laissez pas l’hyperviseur appliquer des « régimes surprises » en plein traitement.
Quelques faits et contexte historique (6–10 points rapides)
- Le ballooning précède la mode du cloud. VMware a popularisé le ballooning dans les premiers jours d’ESX comme outil pratique pour l’overcommit mémoire quand la RAM coûtait cher et la consolidation était le principal argument.
- Le ballooning KVM est généralement implémenté via virtio-balloon. L’invité exécute un pilote qui alloue des pages et les « fixe » afin que l’hôte puisse récupérer la mémoire physique sous-jacente.
- Le ballooning cible la mémoire « inutilisée »… telle que définie par l’invité. Mais ce que l’invité appelle « inutilisé » inclut le cache de fichiers qui peut être extrêmement précieux pour la performance.
- Linux a amélioré ses heuristiques de reclaim au fil du temps, mais c’est toujours une estimation. Les décisions de reclaim, de swap et de purge du cache dépendent de la charge et de la politique du noyau, pas de vos SLO.
- Windows supporte aussi le ballooning, mais la visibilité est différente. Le comportement du pilote et les compteurs de performance ne coïncident pas toujours avec ce que l’hyperviseur pense avoir récupéré.
- Le ballooning n’est pas la même chose que le memory hotplug. Le hotplug change la vue de la mémoire « installée » dans l’invité ; le ballooning garde la mémoire installée identique et crée une pression à l’intérieur.
- Transparent Huge Pages peut amplifier le désordre. Si l’invité utilise massivement THP, le reclaim peut fragmenter la mémoire, augmenter le travail de compactage et générer des pics CPU durant la pression.
- Les hyperviseurs ont aussi un outil plus brutal : le swapping hôte. Si l’hôte overcommit au-delà de ce que le ballooning peut récupérer, l’hôte peut swapper des pages de VM — souvent pire que le swap invité car l’invité ne peut pas l’optimiser.
- Proxmox rend le ballooning facile à activer, ce qui est à la fois pratique et dangereux. C’est une case à cocher qui ressemble à des économies jusqu’à ce que vous payiez en latence tail.
Ce que fait réellement le ballooning dans Proxmox + KVM
Proxmox VE est une couche de gestion sur KVM/QEMU. Quand vous définissez la mémoire d’une VM, deux chiffres importent en pratique :
- Memory (max) : ce que QEMU peut fournir à la VM (et ce que l’invité pense avoir d’installé).
- Balloon (min/target) : jusqu’où Proxmox est autorisé à pousser la VM en dessous sous pression ou selon la politique.
Avec le ballooning activé, QEMU utilise le périphérique virtio-balloon. Le pilote invité se gonfle en allouant des pages et en les signalant à l’hôte comme « je n’en ai pas besoin ». L’hôte peut alors réutiliser la RAM physique sous-jacente pour d’autres VMs ou pour lui-même.
Il y a deux conséquences pratiques clés :
- L’invité croit toujours avoir la même quantité de RAM installée. L’OS ne reçoit pas une notification polie du type « vous avez maintenant 12 Go au lieu de 16 Go ». Il voit juste une pression mémoire et réagit.
- L’hyperviseur prend une décision de performance avec des informations incomplètes. Il ne peut pas voir quelles pages invitées sont « chaudes » au sens applicatif ; il ne voit que des pages. Il crée donc de la pression et laisse l’invité paniquer en conséquence.
Le ballooning peut convenir pour des VMs à usage léger — pensez aux serveurs utilitaires qui sont inactifs la plupart du temps. C’est un pari pour tout ce qui a des caches ou des jeux de travail en régime permanent. Donc pour la plupart des charges de production.
Il existe une vieille idée opérationnelle (paraphrasée) de Gene Kranz : la discipline et le comportement responsable surpassent l’improvisation quand les systèmes deviennent étranges
. Le ballooning est de l’improvisation déguisée en politique.
Comment la « pression » mémoire factice devient une vraie douleur
Précisons : la pression mémoire est « factice » seulement par son origine. La douleur, elle, est complètement réelle.
1) L’invité libère d’abord le cache de pages (et vous le remarquez plus tard)
Linux acceptera volontiers de récupérer le cache de fichiers sous pression. C’est normal et souvent correct. Mais si vos performances dépendent de caches chauds — bases de données lisant des index, nœuds de recherche scannant des segments, CI téléchargeant des dépendances — le ballooning provoque une instabilité des caches qui ressemble à une régression aléatoire des performances disque.
Ce qui rend cela désagréable : vous ne verrez peut-être pas une saturation disque. Vous verrez de la latence. Plus d’IOPS, des lectures plus petites, plus de travail métadonnées. ZFS sur l’hôte devient aussi plus occupé parce que l’invité demande des données qu’il gardait chaudes.
2) Ensuite l’invité commence à swapper (et vous incriminez le mauvais niveau)
Une fois les caches partis, le reclaim atteint les pages anonymes : heap, stacks, mémoire JVM, tampons de base de données. Si l’invité a le swap activé (ce qui est généralement le cas), le noyau swappera. La latence applicative monte et vous commencez à accuser le stockage, le réseau ou « ce voisin bruyant ». Parfois, le voisin bruyant, c’est votre propre politique d’hyperviseur.
Blague #1 : Le ballooning, c’est comme le « hot desking » pour la RAM — c’est super jusqu’à ce que vous reveniez de déjeuner et que votre chaise soit en train de swapper.
3) La pression hôte conduit au swap hôte (qui est pire)
Si l’hôte est en surabonnement et que le ballooning ne récupère pas assez vite, l’hôte peut swapper. Le swap hôte est brutal car l’invité ne sait pas quelles de ses pages ont été évincées. L’invité pense que la mémoire est résidente ; il rencontre des défauts majeurs cachés au niveau de l’hyperviseur. Le dépannage devient un jeu d’ombres.
4) Le timing de reclaim de l’hyperviseur n’est pas synchronisé avec votre charge
Le ballooning n’est pas synchronisé avec vos modèles de charge. Il peut se gonfler juste avant le démarrage d’un job batch, au moment d’un pic de file d’attente, ou durant des phases intensives de compactage. Vous n’avez pas voix au chapitre. Votre application découvre la nouvelle réalité une page faute à la fois.
5) Il peut transformer un overprovision « sûr » en surcharge chaotique
Il y a un cas d’usage légitime pour l’overcommit : sur une flotte importante, toutes les VMs ne culminent pas en même temps. Mais le ballooning vous pousse parfois dans une région où un pic corrélé (jour de déploiement, jobs mensuels, basculement d’incident) crée une contention soudaine. Cette contention n’est pas partagée équitablement. Elle se répartit selon les cibles de balloon et qui se fait presser en premier.
Qui devrait utiliser le ballooning (rarement) et qui ne devrait pas (la plupart d’entre vous)
Le ballooning peut être acceptable quand :
- Les VMs sont principalement inactives et sans état (jump boxes, outils internes à faible trafic).
- Vous avez une gestion de capacité stricte et ennuyeuse et le ballooning est uniquement un filet de sécurité.
- L’OS invité et les applications tolèrent le reclaim sans SLOs de latence tail.
- Vous avez une marge de mémoire sur l’hôte et vous utilisez le ballooning principalement pour réduire le gaspillage, pas pour permettre une consolidation agressive.
Le ballooning est généralement une mauvaise idée quand :
- Vous exécutez des bases de données (PostgreSQL, MySQL, MSSQL), des moteurs de recherche (Elasticsearch/OpenSearch), des brokers (Kafka/RabbitMQ), des caches (Redis) ou des services lourds en JVM.
- Vous comptez sur le cache du système de fichiers comme fonctionnalité de performance (la plupart des services Linux le font, que vous l’admettiez ou non).
- Vous exécutez ZFS sur l’hôte et dépendez déjà de la RAM pour l’ARC. Vous jonglez désormais entre deux couches de cache affamées.
- Vous avez besoin d’une performance prévisible plus que d’une « haute utilisation ».
Ma recommandation par défaut : désactivez le ballooning pour les VMs critiques, dimensionnez la mémoire intentionnellement, gardez de la marge mémoire sur l’hôte et traitez l’overcommit comme une substance contrôlée.
Mode d’emploi rapide pour le diagnostic
Si la performance chute et que vous suspectez le ballooning, n’essayez pas de résoudre tout en même temps. Triagez dans cet ordre :
Première étape : l’hôte est-il réellement sous pression mémoire ?
- Vérifiez la mémoire libre de l’hôte, l’utilisation du swap et si
kswapdest actif. - Si l’hôte swappe, corrigez cela avant d’accuser les invités.
Deuxième étape : les invités réclament-ils/ swappent-ils parce que le ballooning les a réduits ?
- Vérifiez l’état du balloon par VM et l’écart entre la mémoire max et la mémoire actuelle ballonée.
- Dans l’invité, vérifiez les défauts majeurs, le swap entrant/sortant et l’activité de reclaim.
Troisième étape : la latence de stockage est-elle un symptôme d’effondrement du cache ?
- Vérifiez indirectement les motifs de cache de l’invité : augmentation des read IOPS, IO métadonnées, lectures aléatoires et latence élevée sans saturation du débit.
- Sur les hôtes ZFS, vérifiez le comportement de l’ARC et les événements de pression mémoire.
Quatrième étape : décidez de l’action immédiate la moins risquée
- Si le ballooning étrangle une VM critique : augmentez sa cible balloon (ou désactivez le ballooning) et assurez-vous que l’hôte a de la marge.
- Si l’hôte est surchargé : migrez des charges, ajoutez de la RAM, réduisez les allocations ou arrêtez des VMs non critiques.
Tâches pratiques : commandes, sorties et décisions (12+)
Voici les vérifications que j’exécute réellement sur les hôtes Proxmox et dans les invités. Chaque tâche inclut : la commande, ce que signifie la sortie et la décision à prendre.
Task 1: Check host memory + swap at a glance
cr0x@server:~$ free -h
total used free shared buff/cache available
Mem: 62Gi 41Gi 1.8Gi 1.2Gi 20Gi 18Gi
Swap: 16Gi 6.5Gi 9.5Gi
Signification : « available » est ce qui compte pour le confort du noyau Linux hôte. L’utilisation du swap sur l’hôte est déjà non triviale.
Décision : Si le swap hôte augmente pendant l’incident, traitez-le comme un P0. Réduisez la charge ou augmentez la RAM avant d’ajuster les invités.
Task 2: Identify whether the host is actively reclaiming
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 0 6815744 1887340 9120 16720256 12 210 320 410 980 2100 12 6 77 5 0
1 1 6817780 1750020 9152 16611020 0 540 410 920 1020 2400 10 7 73 10 0
3 0 6820100 1628800 9152 16500100 0 820 390 800 1100 2600 14 9 67 10 0
2 0 6821100 1522100 9152 16388900 0 600 420 700 1050 2500 13 8 69 10 0
1 0 6822100 1489000 9152 16299000 0 480 380 650 1000 2300 11 7 72 10 0
Signification : so (swap out) est actif et wa (IO wait) augmente. L’hôte pousse des pages dehors.
Décision : Arrêtez l’hémorragie : migrez une VM, arrêtez des charges non critiques ou ajoutez de la mémoire. Le ballooning ne vous sauvera pas si vous avez déjà franchi la ligne.
Task 3: See top memory consumers on the host
cr0x@server:~$ ps -eo pid,comm,rss,vsz --sort=-rss | head
PID COMMAND RSS VSZ
4121 qemu-system-x86 8234500 17000000
3988 qemu-system-x86 8012200 16500000
4550 qemu-system-x86 6123000 13000000
1872 pveproxy 320000 550000
1601 pvestatd 210000 420000
1023 zfs 180000 300000
950 pvedaemon 120000 300000
811 systemd-journal 95000 160000
621 corosync 82000 210000
Signification : Les processus QEMU dominent. C’est attendu ; maintenant il faut savoir s’ils sont balloonés ou fixés.
Décision : Passez de « l’hôte est sous pression » à « quelles VMs le provoquent et sont-elles compressées ».
Task 4: List Proxmox VMs and identify candidates
cr0x@server:~$ qm list
VMID NAME STATUS MEM(MB) BOOTDISK(GB) PID
101 db-prod-1 running 16384 200.00 4121
102 api-prod-1 running 8192 60.00 3988
103 ci-runner-1 running 4096 80.00 4550
120 jumpbox-1 running 2048 20.00 4801
Signification : Vous avez maintenant des VMID à interroger. La colonne « MEM(MB) » est le max configuré, pas nécessairement l’usage actuel balloné.
Décision : Inspectez en priorité ceux avec des besoins de performance serrés (db-prod-1).
Task 5: Check whether ballooning is configured for a VM
cr0x@server:~$ qm config 101 | egrep -i 'memory|balloon'
balloon: 8192
memory: 16384
Signification : Cette VM peut être poussée jusqu’à 8 Go alors que son max est 16 Go. Ce n’est pas un filet de sécurité ; c’est une seconde personnalité.
Décision : Pour les services critiques, définissez balloon: 0 (désactiver) ou remontez-le proche du max si vous avez vraiment besoin d’un reclaim minimal.
Task 6: Inspect runtime balloon stats from the host
cr0x@server:~$ qm monitor 101 --cmd 'info balloon'
balloon: actual=8704
Signification : La VM est actuellement balloonée à ~8,5 Go. Si la charge attend un comportement 16 Go, vous avez trouvé le coupable.
Décision : Pour un soulagement immédiat : augmentez la cible balloon ou désactivez le ballooning et confirmez la marge de l’hôte.
Task 7: Confirm the virtio balloon device exists (guest)
cr0x@server:~$ lsmod | grep balloon
virtio_balloon 24576 0
Signification : L’invité est capable de ballooning. S’il est chargé, il obéira aux requêtes de l’hôte.
Décision : Pour certains appliances ou charges sensibles, vous pouvez le retirer/blacklister — mais préférez corriger au niveau de la configuration Proxmox pour éviter des surprises.
Task 8: Check guest memory pressure indicators
cr0x@server:~$ cat /proc/pressure/memory
some avg10=42.31 avg60=28.10 avg300=12.90 total=987654321
full avg10=8.22 avg60=4.10 avg300=1.20 total=12345678
Signification : PSI montre que le système est fréquemment bloqué sur le reclaim mémoire (some) et parfois totalement bloqué (full), ce qui tue la latence.
Décision : Si PSI est élevé pendant l’incident et que le ballooning est actif, considérez-le comme une cause probable — pas seulement une corrélation.
Task 9: Check guest swapping and reclaim behavior quickly
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
1 2 1843200 12000 20000 340000 80 220 900 700 1200 2500 18 9 50 23 0
2 1 1845500 9000 19000 320000 20 480 1200 900 1300 2700 20 10 44 26 0
1 1 1849000 8000 17000 300000 0 520 1100 1000 1250 2600 17 8 48 27 0
2 1 1852000 7000 16000 280000 0 600 1000 1100 1400 2900 22 11 40 27 0
1 1 1856000 6000 15000 260000 0 430 950 980 1320 2800 19 9 45 27 0
Signification : so est persistant. L’invité swappe activement. Le cache diminue aussi.
Décision : Stoppez la tempête de swap : donnez de la RAM réelle à la VM (désactiver le ballooning ou augmenter la mémoire) puis envisagez d’ajuster le swappiness seulement après stabilisation.
Task 10: Check major faults (guest) to detect paging pain
cr0x@server:~$ grep -E 'pgmajfault|pgfault' /proc/vmstat
pgfault 348778901
pgmajfault 129988
Signification : Les défauts majeurs nécessitent de l’IO. Une hausse de pgmajfault pendant l’incident est compatible avec du swap ou des défauts de cache.
Décision : Si les défauts majeurs augmentent lorsque le balloon se réduit, ce n’est pas une « lenteur applicative ». C’est une famine mémoire.
Task 11: Check the host’s ZFS ARC pressure (if using ZFS)
cr0x@server:~$ arcstat 1 3
time read miss miss% dmis dm% pmis pm% mmis mm% arcsz c
12:01:01 512 88 14 40 45 20 23 28 32 22.1G 24.0G
12:01:02 680 210 30 140 67 30 14 40 19 18.4G 24.0G
12:01:03 700 260 37 190 73 35 13 35 13 16.2G 24.0G
Signification : La taille de l’ARC (arcsz) diminue tandis que le miss% augmente. La pression mémoire hôte force l’éviction de l’ARC, augmentant l’IO backend.
Décision : Si l’ARC hôte s’effondre et que les invités sont balloonés, vous avez un désastre à deux couches de cache. Ajoutez de la RAM ou réduisez la pression des VMs ; ne « tunez » pas la physique.
Task 12: Check per-QEMU memory from the host to spot weirdness
cr0x@server:~$ pmap -x 4121 | tail -n 5
total kB 17123456 8901232 120000 8200000
Signification : Le RSS est élevé ; le ballooning ne se reflète pas toujours immédiatement en RSS en raison de la façon dont la mémoire est comptée et réutilisée.
Décision : Utilisez les stats balloon et les indicateurs de pression hôte, pas seulement le RSS, pour raisonner sur le reclaim. Le RSS seul peut vous induire en erreur.
Task 13: Check kernel logs for OOM or reclaim warnings (host or guest)
cr0x@server:~$ journalctl -k -S -30min | egrep -i 'oom|out of memory|kswapd|memory pressure' | tail
Feb 04 12:00:12 server kernel: Memory cgroup out of memory: Killed process 2881 (java) total-vm:8123456kB, anon-rss:3456789kB, file-rss:12345kB, shmem-rss:0kB
Signification : L’invité ou l’hôte peut tuer des processus si la pression est sévère. Le ballooning peut contribuer en réduisant la mémoire effective.
Décision : Si vous voyez des OOM kills, cessez d’optimiser et commencez à allouer. Corrigez le budget mémoire d’abord.
Task 14: Disable ballooning for a VM (controlled change)
cr0x@server:~$ qm set 101 --balloon 0
update VM 101: -balloon 0
Signification : Ballooning désactivé. La VM devrait maintenant conserver sa mémoire configurée sans reclaim piloté par l’hyperviseur.
Décision : Ne faites cela que si l’hôte dispose de suffisamment de RAM. Si l’hôte est déjà à l’étroit, vous déplacerez simplement la douleur ailleurs (swap hôte).
Task 15: Raise minimum balloon target instead of disabling (compromise)
cr0x@server:~$ qm set 102 --balloon 7168
update VM 102: -balloon 7168
Signification : La VM 102 peut être comprimée, mais pas en dessous de 7 Go. C’est une garde-fou contrôlée « ne la laissez pas mourir de faim ».
Décision : Utilisez ceci pour des services de criticité moyenne où un peu de reclaim est acceptable, mais pas des tempêtes de swap.
Task 16: Validate host overcommit posture quickly
cr0x@server:~$ pvesh get /nodes/server/qemu --output-format yaml | egrep 'vmid|name|memory|balloon' -n | head -n 30
1:vmid: 101
2:name: db-prod-1
3:memory: 16384
4:balloon: 0
5:vmid: 102
6:name: api-prod-1
7:memory: 8192
8:balloon: 7168
9:vmid: 103
10:name: ci-runner-1
11:memory: 4096
12:balloon: 2048
Signification : Vous voyez rapidement qui peut être compressé et jusqu’à quel point.
Décision : Alignez la politique de ballooning avec les niveaux de service. Si une VM critique a une large plage balloon, corrigez cela maintenant, pas pendant le prochain incident.
Trois mini-récits d’entreprise du terrain
Mini-récit 1 : L’incident causé par une mauvaise hypothèse
Une entreprise SaaS de taille moyenne a migré un ensemble de services internes vers un cluster Proxmox propre. Ils ont fait les bonnes choses : alimentation redondante, SSD décents, NICs duales, et des sauvegardes qui restaurent vraiment. Puis ils ont fait une erreur : ils ont supposé que « ballooning signifie que la VM rend vraiment de la mémoire inutilisée ».
Leur VM PostgreSQL était configurée avec 32 Go max et 16 Go en balloon. Sur le papier, largement suffisant. En réalité, la charge dépendait du cache de pages Linux et des shared buffers PostgreSQL réglés pour la mémoire supérieure. Pendant les heures de travail, le cluster s’est un peu chargé, Proxmox a gonflé le balloon, et l’invité a commencé à fortement récupérer.
Les symptômes étaient subtils au début : pics de requêtes occasionnels, temps de checkpoint accrus, plus de jitter IO. L’équipe a couru après la latence du stockage et a même changé des firmwares NVMe. Pendant ce temps, l’invité augmentait silencieusement son usage de swap car il avait été « entraîné » à croire qu’il possédait 32 Go alors que le balloon le réduisait constamment.
L’incident est survenu un mardi de déploiement quand le trafic et des migrations de fond se sont chevauchés. La latence tail a franchi le seuil d’alerte, puis l’a largement dépassé. L’autoscaling n’a pas aidé car il a monté des réplicas applicatifs, pas la VM de base de données. La base n’était pas limitée par le CPU ; elle se noyait dans les défauts majeurs.
La correction a été ennuyeuse et immédiate : désactiver le ballooning pour la VM de base de données, redimensionner la mémoire à ce que l’hôte pouvait réellement supporter, et garder de la marge hôte. Les performances se sont stabilisées en quelques minutes. La ligne la plus pénible du postmortem était aussi la plus honnête : « Nous avons traité le cache comme gratuit. » Le cache n’est jamais gratuit ; vous le payez en RAM ou en latence.
Mini-récit 2 : L’optimisation qui a mal tourné
Un grand service informatique avait pour mandat d’augmenter la densité de virtualisation. Le cluster Proxmox hébergeait des dizaines de VMs Windows et Linux, beaucoup classées « basse priorité ». Quelqu’un a proposé d’activer le ballooning partout avec des minimums agressifs. L’idée : récupérer la mémoire inoccupée et loger plus de VMs par nœud.
Ça a marché — au début. Les graphiques de mémoire hôte étaient beaux. L’utilisation montait. Le rapport hebdomadaire affichait des chiffres qui faisaient hocher la tête à la direction. Puis est venu le créneau de patch mensuel, et la « basse priorité » a cessé de l’être. Tout le monde a patché, rebooté, compilé, scanné et loggué en même temps.
Le ballooning s’est gonflé sur toute la flotte. Les invités Windows ont commencé à pager. Les invités Linux ont vidé les caches et sont entrés en reclaim. Le contrôleur de domaine — configuré « pas critique » parce qu’il n’était pas orienté client — s’est fait presser aussi. La latence d’authentification a monté. Beaucoup de services n’ont plus pu se connecter, ce qui les a fait réessayer, augmentant la charge, aggravant le reclaim. Boucle de rétroaction classique, maintenant avec une bureaucratie en prime.
Les opérations ont dansé la danse habituelle : blâmer le SAN, le réseau, le patch. Mais l’échec réel était la politique : ils avaient construit un système qui supposait que les charges ne se corrélaient jamais. Les entreprises sont des usines à corrélations. Fenêtres de patch, jobs de fin de trimestre et scans de vulnérabilités sont des douleurs synchronisées par conception.
Ils ont annulé le ballooning sur les VMs d’infrastructure, fixé des minimums raisonnables pour les autres, et créé un budget de capacité qui supposait des pics corrélés. La densité a un peu diminué. Les incidents ont beaucoup diminué. L’unique « optimisation » restante était la bonne : acheter suffisamment de RAM pour les charges réelles.
Mini-récit 3 : La pratique ennuyeuse mais correcte qui a sauvé la mise
Une petite équipe fintech utilisait Proxmox pour un mélange de services : API, un broker de messages, quelques bases de données et de l’observabilité. Ils avaient une règle peu glamour : pas de ballooning sur les services de niveau 0, et une exigence stricte de 25–30% de marge mémoire hôte.
Ce n’était pas populaire lors des achats. La RAM coûte, et la marge « inutilisée » ressemble à du gaspillage dans un tableur. Mais l’équipe s’y est tenue et l’a documentée comme exigence de fiabilité, pas comme préférence.
Un jour, un développeur a déclenché par erreur un job batch incontrôlé dans une VM d’analytics non critique. Le CPU a grimpé, la mémoire a monté, et la VM a commencé à dévorer le cache de pages. Sur un hôte fortement rempli, cela aurait pu forcer le ballooning ailleurs ou pousser l’hôte dans le swap.
Au lieu de cela, rien d’autre n’a bronché. La VM bruyante est devenue plus lente, comme il se doit. La base de données est restée stable. Le broker de messages a conservé sa latence tail. Ils ont limité le job batch et ont continué leur journée.
C’est à cela que ressemble une bonne infrastructure : le rayon d’impact est prévisible. Ce n’est pas excitant. Ça ne crée pas d’histoires de héros. Ça empêche silencieusement ces histoires.
Erreurs courantes : symptôme → cause racine → correction
1) Symptom: VM « a de la RAM » mais swappe quand même
Cause racine : Le ballooning a réduit la mémoire effective de la VM ; l’invité voit toujours la RAM installée mais subit une pression de reclaim interne.
Correction : Désactivez le ballooning (qm set <vmid> --balloon 0) pour cette VM ou remontez le minimum balloon proche du max. Vérifiez que l’hôte a de la marge.
2) Symptom: Pics de latence aléatoires, surtout après des périodes d’inactivité
Cause racine : Effondrement du cache. Le ballooning a récupéré de la mémoire utilisée comme cache de fichiers ; la charge devient sensible à la latence IO jusqu’à ce que le cache se réchauffe.
Correction : Ne balloonnez pas les charges dépendantes du cache. Dimensionnez correctement la mémoire. Si nécessaire, isolez ces VMs sur des nœuds avec plus de RAM et moins de locataires.
3) Symptom: L’IO wait de l’hôte augmente, mais les disques ne sont pas « saturés »
Cause racine : Swap ou tempêtes de page-in produisent beaucoup de petites IO aléatoires à haute latence, pas forcément à haut débit.
Correction : Confirmez avec vmstat et les défauts majeurs invités. Supprimez la pression de swap hôte ; réduisez l’overcommit ; arrêtez de balloonner les VMs critiques.
4) Symptom: L’ARC ZFS diminue et le taux de hit chute pendant les périodes « chargées »
Cause racine : Pression mémoire hôte — souvent due à l’overcommit et aux dynamiques de ballooning — force l’éviction de l’ARC, aggravant les défauts de cache invités.
Correction : Augmentez la marge mémoire hôte. Envisagez de régler zfs_arc_max seulement après avoir corrigé l’overcommit ; limiter l’ARC pour « sauver de la mémoire » ne fait souvent que transférer la douleur vers l’IO.
5) Symptom: Vous avez désactivé le ballooning mais les choses ont empiré
Cause racine : L’hôte était déjà en overcommit ; le ballooning masquait un déficit de capacité. Le désactiver a poussé l’hôte vers le swap ou l’OOM.
Correction : Traitez cela comme un problème de capacité : migrez des VMs, réduisez la mémoire configurée, ajoutez de la RAM ou répartissez les charges sur d’autres nœuds. Le ballooning ne remplace pas la planification de capacité.
6) Symptom: « Ce sont seulement les runners CI qui sont lents »
Cause racine : Les runners CI dépendent des caches (cache de paquets, caches de couches Docker). Le ballooning les perturbe ; les temps de build deviennent imprévisibles.
Correction : Donnez aux runners CI une RAM fixe ou déplacez le cache vers un stockage externe conçu pour cela. Si vous devez compresser les runners, faites-le intentionnellement avec un max réduit, pas via un ballooning dynamique.
7) Symptom: Les invités Windows semblent lents mais les métriques ne crient pas
Cause racine : Le ballooning combiné à la gestion mémoire Windows peut cacher la vraie raison derrière des compteurs de haut niveau ; vous voyez d’abord la lenteur perçue par l’utilisateur.
Correction : Corrélez avec les stats balloon hôte (qm monitor ... info balloon) et la pression mémoire hôte. Si l’hôte étrangle la VM, arrêtez cela.
8) Symptom: OOM kills fréquents dans une charge conteneurisée dans une VM
Cause racine : Le ballooning réduit la mémoire disponible de la VM ; à l’intérieur, les cgroups appliquent des limites ; la charge atteint son OOM de cgroup plus vite.
Correction : Alignez les budgets : la mémoire VM doit couvrir la marge pour les conteneurs. Désactivez le ballooning ou définissez un minimum élevé. Puis revoyez les limites des conteneurs.
Blague #2 : Le ballooning est le seul régime où la balance ment d’abord et votre base de données pleure ensuite.
Listes de contrôle / plan étape par étape
Checklist A: Décider si le ballooning a sa place dans votre environnement
- Inventoriez les types de charges : bases de données, recherche, brokers, caches, CI, serveurs fichiers, « divers ».
- Identifiez les services tier-0 et tier-1 : tout ce qui a des SLOs de latence stricts ou dont dépendent d’autres systèmes (DNS, auth, bases de données).
- Pour tiers 0/1 : désactivez le ballooning (
balloon: 0) sauf si vous avez une très bonne raison. - Pour tiers 2/3 : si vous activez le ballooning, définissez un minimum conservateur (pas 50% sauf si vous voulez 50% de performance).
- Définissez une politique hôte : maintenez une marge mémoire (j’aime 25–30% pour des charges mixtes ; plus si vous faites beaucoup de cache ZFS).
- Documentez les exceptions avec propriétaires et triggers de rollback.
Checklist B: Remédiation sûre en production quand vous suspectez le ballooning
- Confirmez que l’hôte ne swappe pas lourdement (
free -h,vmstat). - Confirmez que la VM est balloonée en dessous de son max (
qm config+qm monitor ... info balloon). - Vérifiez PSI et l’activité de swap dans l’invité (
/proc/pressure/memory,vmstat). - Si la VM est tier-0 : remontez la cible balloon immédiatement (ou désactivez) et surveillez la mémoire hôte.
- Si l’hôte est à la limite : migrez une VM hors du nœud d’abord, puis désactivez le ballooning.
- Après stabilisation : ajustez la mémoire max à un chiffre réaliste et laissez le ballooning désactivé pour ce service.
Checklist C: Construire un modèle mémoire sensé pour les nœuds Proxmox
- Commencez par la RAM physique.
- Soustrayez une réserve fixe pour l’hôte (OS + services Proxmox + marge de sécurité).
- Soustrayez une réserve pour le cache de stockage (attentes ARC ZFS, métadonnées, buffers IO).
- Budgetez la RAM restante aux VMs comme des allocations fixes pour les tiers 0/1.
- Ensuite seulement, envisagez le ballooning pour les VMs peu critiques, et plafonnez ce qui peut être récupéré.
- Planifiez les événements corrélés : fenêtres de patch, jobs batch, basculements, mode incident.
FAQ
1) Le ballooning Proxmox est-il « mauvais » ou simplement mal utilisé ?
C’est un outil facile à mal utiliser. En production, il devient souvent un substitut à la planification de capacité. Utilisé de manière conservatrice pour des VMs peu critiques, il peut convenir. Utilisé largement, il manufacture de la latence.
2) Quelle est la différence entre ballooning et memory hotplug ?
Le hotplug change la vue de la RAM installée dans l’invité (il gagne ou perd des composantes mémoire). Le ballooning garde la RAM installée constante et crée une pression interne en forçant le reclaim.
3) Pourquoi le ballooning provoque-t-il du swap dans l’invité ?
Parce que l’invité tente de satisfaire des allocations mémoire sous pression. Il libère d’abord le cache, puis récupère des pages anonymes ; si cela ne suffit pas, il swappe — surtout si l’hôte continue de pousser le balloon plus bas.
4) Si le ballooning récupère de la mémoire « inutilisée », pourquoi la performance chute-t-elle ?
Parce que « inutilisée » inclut le cache. Le cache peut ne pas être activement réservé par les applications, mais il évite l’IO et maintient la latence prévisible. Le récupérer, c’est jeter vos outils parce que vous ne les tenez pas sur le moment.
5) Dois-je désactiver le swap dans les invités pour éviter les effets du ballooning ?
Pas comme première mesure. Désactiver le swap peut convertir la pression mémoire en OOM kills, souvent pires. Corrigez la cause (ballooning/overcommit). Ensuite, décidez de la politique de swap par charge.
6) Le ballooning peut-il aider à prévenir un OOM hôte ?
Oui, parfois. C’est un moyen de récupérer de la mémoire avant que l’hôte n’atteigne la limite. Mais si vous vous y fiez régulièrement, vous opérez trop près du mur. La solution correcte est d’avoir de la marge.
7) Pourquoi je vois du swap hôte même si le ballooning est activé ?
Parce que le ballooning a des limites (cibles minimales, vitesse de reclaim, comportement invité). Si l’hôte est surcommité ou que plusieurs VMs picquent ensemble, le ballooning ne récupérera pas assez vite, et l’hôte swappe quand même.
8) Quelle valeur donner au minimum balloon si je le garde activé ?
Commencez haut. Pour les services importants, mettez le minimum proche du max — pensez « récupérer un peu de marge inoccupée », pas « réduire la VM de moitié ». Pour les VMs poubelle, vous pouvez être plus agressif, mais testez sous charge.
9) Le ballooning interagit-il mal avec ZFS sur l’hôte ?
Oui, potentiellement. ZFS adore la RAM pour l’ARC. Si vous overcommittez les VMs puis balloonez pendant que l’hôte met la pression sur l’ARC, vous risquez un double effondrement du cache : les invités perdent leur cache, l’hôte perd son ARC, et les disques trinquent.
10) Comment savoir que le ballooning est le goulot d’étranglement et pas le CPU ou le stockage ?
Corrélez : la valeur balloon réelle diminue, la PSI et le swap invité augmentent, les défauts majeurs montent, et la performance chute sans saturation CPU correspondante. Ce pattern est très caractéristique.
Conclusion : étapes pratiques suivantes
Le ballooning n’est pas diabolique. Il est simplement très prêt à transformer votre charge de production en une expérience de gestion mémoire sans demander l’autorisation.
Faites ceci ensuite :
- Choisissez vos VMs tier-0 et désactivez le ballooning pour elles dès aujourd’hui.
- Vérifiez la marge hôte : si vous êtes régulièrement proche de la limite, corrigez la capacité avant d’ajuster les réglages.
- N’utilisez le ballooning qu’en politique contrôlée pour les VMs peu critiques, avec des minimums conservateurs.
- Instrumentez la pression mémoire : activité swap hôte, PSI invité et balloon actual vs max. Rendez cela visible pour que la « lenteur mystère » devienne un graphique, pas un débat.
- Consignez la règle : performance prévisible > consolidation futée. Votre canal d’incidents futur vous remerciera.