Vous cliquez sur Start d’une VM et Proxmox répond par l’équivalent numérique d’un haussement d’épaules :
« impossible d’allouer la mémoire ». Ou pire, la VM démarre puis l’hôte commence à tuer des processus au hasard
comme un régisseur stressé dans un théâtre avec une seule sortie.
Les échecs mémoire dans Proxmox ne sont pas mystiques. Ce sont des problèmes de comptabilité : ce que l’hôte pense avoir,
ce que les VM prétendent pouvoir utiliser, ce qu’elles touchent réellement, et ce que le noyau est prêt
à promettre à cet instant. Corrigez la comptabilité, et la plupart du drame disparaît.
Guide de diagnostic rapide
Si vous êtes d’astreinte et que le cluster hurle, vous ne voulez pas une leçon de philosophie. Vous voulez une boucle serrée :
confirmer le mode d’échec, identifier le facteur limitant, faire un changement sûr, répéter.
Premier point : s’agit-il d’une exhaustion mémoire de l’hôte ou d’une limite par VM ?
-
Si la VM échoue au démarrage avec impossible d’allouer la mémoire, suspectez les limites de commit de l’hôte,
les limites de cgroup, les hugepages, ou la fragmentation — souvent visible immédiatement dansdmesg/ journal. -
Si la VM démarre puis est tuée, il s’agit généralement du tueur OOM du guest (à l’intérieur de la VM) ou
du tueur OOM de l’hôte (tuant QEMU), selon les journaux qui montrent la mise à mort.
Deuxième point : vérifiez la marge réelle de l’hôte, pas les jolis graphiques
- Memoire libre et swap de l’hôte :
free -h - Pression mémoire et blocages de reclaim :
vmstat 1 - Preuves d’OOM :
journalctl -ketdmesg -T - Taille de l’ARC ZFS (si vous utilisez ZFS) :
arcstat//proc/spl/kstat/zfs/arcstats
Troisième point : vérifiez la configuration et la politique côté Proxmox
-
Configuration VM : cible ballooning vs max, hugepages, NUMA, etc. :
qm config <vmid> -
Politique de surcommit du nœud :
pvesh get /nodes/<node>/statuset
/etc/pve/datacenter.cfg -
Si c’est un container (LXC), vérifiez la limite mémoire du cgroup et la limite de swap :
pct config <ctid>
Quatrième point : choisissez la mitigation immédiate la moins mauvaise
- Arrêtez une VM non critique pour libérer de la RAM et réduire la pression maintenant.
- Si ZFS mange la machine : limitez l’ARC (de façon persistante) ou redémarrez en dernier recours.
- Si vous êtes en surcommit : réduisez la mémoire max des VM (pas seulement la cible balloon).
- Si le swap est absent et que vous êtes serré : ajoutez du swap (hôte) pour éviter un OOM instantané pendant que vous corrigez le dimensionnement.
Blague #1 : Le surcommit mémoire, c’est comme la comptabilité d’entreprise — tout fonctionne jusqu’à ce que tout le monde essaie de faire passer le déjeuner la même journée.
Ce que signifie réellement « impossible d’allouer la mémoire » dans Proxmox
Proxmox est une couche de gestion. L’allocateur réel est Linux, et pour les VM c’est généralement QEMU/KVM. Lorsque vous voyez
impossible d’allouer la mémoire, l’une de ces situations se produit :
-
QEMU ne peut pas réserver la RAM demandée par la VM au moment du démarrage. Cela peut échouer même si
freesemble correct, car Linux applique des règles de commit et la fragmentation. - Le noyau refuse l’allocation à cause de la logique overcommit/CommitLimit. Linux suit combien de mémoire les processus ont promis de potentiellement utiliser (mémoire virtuelle), et il peut refuser de nouvelles promesses.
-
Des hugepages sont demandées mais non disponibles. Les hugepages sont pré-allouées. Si elles n’existent pas,
l’allocation échoue immédiatement et bruyamment. - Des limites de cgroup bloquent l’allocation. Plus courant avec les conteneurs, mais peut s’appliquer si systemd slices ou cgroups personnalisés sont impliqués.
- La mémoire est disponible mais pas dans la forme demandée. La fragmentation peut empêcher de grosses allocations contiguës, surtout avec les hugepages ou certains besoins DMA.
Pendant ce temps, la « solution » que certains proposent — le ballooning — ne change pas ce que QEMU a demandé si vous avez toujours configuré une grande mémoire
max. Le ballooning ajuste ce que le guest est encouragé à utiliser, pas ce que l’hôte doit être prêt à garantir au pire moment.
Deux nombres importent : cible du guest et max du guest
Dans les options VM de Proxmox, le ballooning vous donne :
- Mémoire (max) : le plafond de la VM. QEMU réserve une comptabilité pour cela.
- Balloon (min/target) : la cible d’exécution de la VM qui peut être réduite sous pression.
Si vous définissez le max à 64 Go « au cas où » et la cible balloon à 8 Go « parce qu’elle est généralement inactive », vous avez dit à l’hôte :
« Veuillez être prêt à financer mon style de vie à 64 Go. » L’hôte, étant raisonnable, peut dire non.
Faits intéressants et un peu d’histoire (pour que vous arrêtiez de le répéter)
-
Le comportement d’overcommit de Linux est ancien et intentionnel : il existe parce que beaucoup d’allocations ne sont jamais entièrement utilisées,
et une comptabilité stricte gaspillerait de la RAM pour des promesses vides. -
Le tueur OOM précède la plupart des piles de virtualisation modernes ; c’était la réponse pragmatique de Linux à « quelqu’un ment sur la mémoire »
bien avant que le marketing cloud transforme le mensonge en fonctionnalité. - Le ballooning est devenu courant avec les hyperviseurs précoces parce que les guests inactifs accaparaient le cache et rendaient la consolidation pire qu’elle n’était.
-
KSM (Kernel Samepage Merging) a été conçu pour dédupliquer des pages mémoire identiques entre VM — particulièrement utile quand
de nombreuses VM exécutent la même image OS. -
Les Transparent Huge Pages (THP) ont été introduites pour améliorer les performances en utilisant automatiquement de plus grandes pages, mais
elles peuvent provoquer des pics de latence sous pression mémoire à cause du travail de compaction. -
L’ARC de ZFS n’est pas « juste un cache ». Il concurrence la mémoire anonyme. Si vous ne le limitez pas, il prendra volontiers la RAM
jusqu’à ce que le noyau le force à en libérer — parfois trop tard. -
Les cgroups ont changé la donne : au lieu que l’hôte soit une grande famille heureuse, les limites mémoire peuvent maintenant faire échouer
une seule VM ou un seul conteneur alors que l’hôte a l’air correct. -
Le swap était autrefois un conseil obligatoire ; puis les gens l’ont abusé ; puis on l’a rejeté ; puis les SSD modernes ont rendu
« un petit swap contrôlé » à nouveau pertinent dans de nombreux cas.
Une citation opérationnelle qui reste douloureusement pertinente (idée paraphrasée) : Werner Vogels a dit que le cœur de la fiabilité est d’attendre les pannes et de concevoir pour elles, pas de prétendre qu’elles n’arriveront pas.
Ballooning : ce que ça fait, ce que ça ne fait pas, et pourquoi il vous trompe
Ce qu’est réellement le ballooning
Le ballooning utilise un pilote à l’intérieur du guest (virtio-balloon typiquement). L’hôte demande au guest d’« gonfler » un ballon,
c’est-à-dire : allouer de la mémoire à l’intérieur du guest et la pinner pour que le guest ne puisse pas l’utiliser. Cette mémoire devient récupérable
du point de vue de l’hôte parce que le guest l’a volontairement cédée.
C’est intelligent. C’est aussi limité par la physique et le comportement du guest :
- Si le guest est sous réelle pression mémoire, il ne peut pas vous céder grand-chose sans swapper ou s’auto-oomer.
- Si le guest n’a pas le pilote balloon, le ballooning est essentiellement une danse interprétative.
- Le ballooning est réactif. Si l’hôte est déjà en difficulté, vous pouvez être trop tard.
Le piège important du ballooning dans Proxmox
La configuration de ballooning dans Proxmox donne souvent un faux sentiment de sécurité. Les gens définissent des cibles balloon basses et des max mémoire élevées,
pensant « n’utiliser que la cible ». Mais la comptabilité de QEMU et la logique de commit du noyau doivent souvent tenir compte du maximum.
Position opérationnelle : le ballooning est un outil d’ajustement, pas une excuse pour éviter le dimensionnement. Utilisez-le pour des charges élastiques
où l’OS invité peut s’adapter. Ne l’utilisez pas comme stratégie principale pour surcharger un hôte jusqu’au grincement.
Quand le ballooning en vaut la peine
- Clusters de dev/test où les guests sont inactifs et les pics sont rares et tolérables.
- Parcs VDI avec beaucoup de VMs similaires, souvent combinés avec KSM.
- Flottes de serveurs génériques où vous pouvez appliquer des max raisonnables, pas des valeurs de fantaisie.
Quand le ballooning est un piège
- Bases de données avec latence stricte et pools de buffers (la pression mémoire du guest devient pression IO).
- Systèmes avec swap désactivé dans les guests (le ballooning peut provoquer un OOM à l’intérieur du guest).
- Hôtes déjà serrés en mémoire où le temps de réaction du ballooning est trop lent.
Surcommit : quand c’est judicieux, quand c’est imprudent
Trois « surcommits » différents que les gens confondent
En pratique, vous jonglez avec trois couches :
-
Surcommit de planification/comptabilité Proxmox : si Proxmox autorise ou non le démarrage d’une VM
selon la mémoire configurée, les cibles balloon et la mémoire du nœud. -
Surcommit de mémoire virtuelle Linux :
vm.overcommit_memoryetCommitLimit. -
Surcommit physique réel : si la somme de la mémoire activement utilisée par les guests dépasse la RAM de l’hôte
(et si vous avez swap, compression, ou un plan).
Comptabilité de commit Linux en un paragraphe opérationnel
Linux décide d’autoriser une allocation en se basant sur combien de mémoire pourrait être utilisée si les processus la touchaient.
Ce chiffre « pourrait être utilisé » est suivi comme Committed_AS. Le plafond autorisé est CommitLimit,
à peu près RAM + swap moins quelques réserves, modifié par les réglages d’overcommit. Si Committed_AS approche
CommitLimit, le noyau commence à refuser les allocations — bonjour, « impossible d’allouer la mémoire ».
Conseils orientés
-
Production : gardez le surcommit modéré et appliquez des max VM réalistes. Si vous ne pouvez pas indiquer votre
ratio de surcommit et votre plan d’éviction, vous ne surcommettez pas — vous jouez. - Lab : surcommettez agressivement si vous acceptez des événements OOM occasionnels. Étiquetez-le honnêtement et cessez de prétendre que c’est de la prod.
-
Charges mixtes : séparez les consommateurs de mémoire bruyants (DB, analytics) sur leurs propres nœuds,
ou imposez-leur des plafonds stricts. « Coexistence » est le mot que l’on utilise juste avant le post-mortem.
ZFS ARC, cache de pages et la mémoire hôte que vous avez oubliée de budgéter
Proxmox tourne souvent sur ZFS car les snapshots et send/receive sont addictifs. Mais ZFS n’est pas timide : il utilisera la RAM
pour l’ARC (Adaptive Replacement Cache). C’est génial jusqu’à ce que ça ne le soit plus.
ARC versus « mémoire libre »
L’ARC est récupérable, mais pas instantanément et pas toujours de la façon dont votre démarrage de VM le souhaite. Sous pression, le noyau
essaie de récupérer le page cache et l’ARC, mais si vous êtes dans une boucle serrée d’allocations (démarrage d’une VM, inflation de mémoire,
fork de processus), vous pouvez rencontrer des échecs transitoires.
Que faire
-
Sur des hôtes ZFS avec beaucoup de VM, fixez un maximum d’ARC sensé (
zfs_arc_max). Ne laissez pas l’ARC « se battre » contre vos guests. -
Traitez la mémoire hôte comme une infrastructure partagée. L’hôte a besoin de mémoire pour :
noyau, slab, réseau, métadonnées ZFS, overhead QEMU, et vos agents de monitoring qui jurent qu’ils sont légers.
Swap : pas un péché, mais pas non plus un plan de vie
Pas de swap signifie que vous avez retiré les amortisseurs. Avec la virtualisation, cela peut être fatal car un pic de pression
se transforme en tueries OOM immédiates au lieu d’une dégradation lente et diagnostiquable.
Mais le swap peut aussi devenir un bourbier de performances. L’objectif est un swap contrôlé : assez pour survivre aux pics, pas assez pour
masquer un surcommit chronique.
Recommandations swap pour l’hôte (pratique, pas dogmatique)
-
Si vous utilisez ZFS et de nombreuses VM : ajoutez du swap. Même une quantité modérée peut empêcher l’hôte de tuer
QEMU lors de pics brefs. -
Si votre stockage est lent : gardez le swap plus petit et priorisez un bon dimensionnement de la RAM. Swapper sur un RAID HDD occupé
n’est pas « stabilité », c’est « souffrance prolongée ». -
Si vous utilisez SSD/NVMe : le swap est beaucoup plus tolérable, mais ce n’est toujours pas gratuit. Surveillez les taux de swap-in/out,
pas seulement l’espace de swap utilisé.
Blague #2 : Le swap, c’est comme une réunion qui aurait pu être un e-mail — parfois ça sauve la journée, mais si vous y vivez, votre carrière est finie.
Tâches pratiques : commandes, sorties et décisions (12+)
Voici les vérifications que j’exécute réellement quand un nœud Proxmox commence à lancer des erreurs d’allocation mémoire. Chaque tâche inclut :
une commande, une sortie d’exemple, ce que cela signifie, et quelle décision cela entraîne.
Task 1: Check host RAM and swap at a glance
cr0x@server:~$ free -h
total used free shared buff/cache available
Mem: 62Gi 54Gi 1.2Gi 2.3Gi 6.9Gi 2.8Gi
Swap: 8Gi 1.6Gi 6.4Gi
Sens : « available » est votre marge à court terme avant que le reclaim ne devienne pénible. 2.8 GiB sur un hôte de 62 GiB
avec de la virtualisation est serré mais pas immédiatement condamné.
Décision : Si available est < 1–2 GiB et que des VM échouent au démarrage, arrêtez des VM non critiques maintenant.
Si le swap est 0, ajoutez du swap comme stabilisateur pendant que vous corrigez le dimensionnement.
Task 2: Identify if the kernel is rejecting allocations due to commit limits
cr0x@server:~$ grep -E 'CommitLimit|Committed_AS' /proc/meminfo
CommitLimit: 71303168 kB
Committed_AS: 70598240 kB
Sens : Vous êtes proche du plafond de commit. Le noyau peut refuser de nouvelles réservations de mémoire même s’il y a du cache récupérable.
Décision : Réduisez les max mémoire des VM, ajoutez du swap (augmente CommitLimit), ou déplacez des charges.
Les changements de cible balloon n’aideront pas si le max est le problème.
Task 3: Confirm overcommit policy
cr0x@server:~$ sysctl vm.overcommit_memory vm.overcommit_ratio
vm.overcommit_memory = 0
vm.overcommit_ratio = 50
Sens : Le mode 0 est un overcommit heuristique. Le ratio importe surtout pour le mode 2. Néanmoins, le comportement de commit est en jeu.
Décision : Ne changez pas ces réglages en panique à moins de comprendre l’impact. Si vous atteignez les limites de commit,
corriger le dimensionnement est préférable à « simplement overcommitter davantage ».
Task 4: Look for OOM killer evidence on the host
cr0x@server:~$ journalctl -k -b | tail -n 30
Dec 26 10:14:03 pve1 kernel: Out of memory: Killed process 21433 (qemu-system-x86) total-vm:28751400kB, anon-rss:23110248kB, file-rss:0kB, shmem-rss:0kB
Dec 26 10:14:03 pve1 kernel: oom_reaper: reaped process 21433 (qemu-system-x86), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB
Sens : L’hôte a tué QEMU. Cette VM n’a pas « crashé », elle a été exécutée.
Décision : Traitez cela comme une exhaustion mémoire/overcommit de l’hôte. Réduisez la consolidation, limitez l’ARC, ajoutez du swap,
et ne comptez plus sur le ballooning comme ceinture de sécurité.
Task 5: Check memory pressure and reclaim behavior live
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
6 1 1677720 312000 8200 5120000 40 120 180 260 900 1800 18 12 55 15 0
5 2 1677800 280000 8100 5010000 10 200 140 320 920 1700 15 10 50 25 0
7 3 1677850 260000 8000 4920000 80 500 220 600 1100 2200 20 15 35 30 0
Sens : Des si/so non nuls indiquent du swapping. Un wa élevé suggère de l’IO wait.
Si b augmente et id s’effondre, l’hôte est en thrash.
Décision : Si le swapping est soutenu et l’IO wait monte en flèche, arrêtez des VM ou migrez la charge. Vous ne pouvez pas « tuner »
votre sortie d’une tempête de thrash en temps réel.
Task 6: Find the biggest memory consumers on the host (RSS, not VIRT fantasies)
cr0x@server:~$ ps -eo pid,comm,rss,vsz --sort=-rss | head -n 10
21433 qemu-system-x86 23110248 28751400
19877 qemu-system-x86 16188012 21045740
1652 pveproxy 312400 824000
1321 pvedaemon 210880 693000
1799 zfs 180200 0
1544 pvestatd 122000 610000
Sens : RSS est la mémoire résidente réelle. Les processus QEMU dominent, comme prévu.
Décision : Si une VM est hors de contrôle, limitez son max mémoire ou investiguez à l’intérieur du guest.
Si ce sont « plusieurs VM moyennes », c’est de la mathématique de consolidation, pas un seul coupable.
Task 7: Inspect a VM’s memory configuration (ballooning vs max)
cr0x@server:~$ qm config 104 | egrep 'memory|balloon|numa|hugepages'
memory: 32768
balloon: 8192
numa: 1
hugepages: 2
Sens : Max est 32 GiB, cible balloon 8 GiB. Les hugepages sont activées (2 = hugepages de 2 Mo).
Décision : Si le nœud échoue aux allocations, le max de 32 GiB de cette VM peut être trop généreux.
Si les hugepages sont activées, confirmez leur disponibilité (Task 8) ou désactivez-les pour plus de flexibilité.
Task 8: Validate hugepages availability (classic cause of start failures)
cr0x@server:~$ grep -i huge /proc/meminfo
AnonHugePages: 1048576 kB
HugePages_Total: 8192
HugePages_Free: 120
HugePages_Rsvd: 50
Hugepagesize: 2048 kB
Sens : Seulement 120 hugepages libres (~240 MiB). Si vous tentez de démarrer une VM nécessitant beaucoup de hugepages, cela échoue.
Décision : Soit provisionnez suffisamment de hugepages au démarrage, soit cessez d’utiliser les hugepages pour cette classe de VM.
Les hugepages sont un outil de performance, pas une valeur par défaut.
Task 9: Check for THP behavior (can cause latency during pressure)
cr0x@server:~$ cat /sys/kernel/mm/transparent_hugepage/enabled
[always] madvise never
Sens : THP est activé en permanence.
Décision : Pour des nœuds sensibles à la latence, envisagez madvise ou never.
Ne changez pas cela en plein incident sauf si vous êtes confiant ; planifiez-le en fenêtre de maintenance et mesurez.
Task 10: If using ZFS, check ARC size quickly
cr0x@server:~$ awk '/^size/ {print}' /proc/spl/kstat/zfs/arcstats
size 4 34359738368
Sens : L’ARC est ~32 GiB. Sur un hôte de 64 GiB avec beaucoup de VM, cela peut être trop.
Décision : Si vous manquez de mémoire et que l’ARC est large, limitez l’ARC de façon persistante (voir section checklist)
et planifiez un redémarrage si nécessaire pour un soulagement immédiat.
Task 11: Confirm KSM status (helps with many similar VMs, can cost CPU)
cr0x@server:~$ systemctl is-active ksmtuned
inactive
Sens : Le service de tuning KSM n’est pas actif. Sur certains déploiements Proxmox, KSM est configuré différemment ;
ceci est juste un signal rapide.
Décision : Si vous exécutez des dizaines de VM Linux similaires, activer KSM peut réduire l’utilisation mémoire. Si le CPU est
déjà chaud, KSM peut se retourner contre vous. Testez sur un nœud d’abord.
Task 12: Check Proxmox node memory info (what Proxmox thinks is happening)
cr0x@server:~$ pvesh get /nodes/pve1/status | egrep '"memory"|"swap"|"loadavg"'
"loadavg": [
"2.61",
"2.45",
"2.31"
],
"memory": {
"free": 1288490188,
"total": 66571993088,
"used": 651834
},
"swap": {
"free": 6871947673,
"total": 8589934592,
"used": 1717986919
}
Sens : L’API de Proxmox fournit une vue qui peut différer de vos attentes immédiates (unités,
cache et timing). Ne la traitez pas comme une vérité absolue ; recoupez avec free et meminfo.
Décision : Utilisez-la pour l’automatisation et les tableaux de bord, mais lors du débogage d’échecs d’allocation, faites confiance
d’abord aux preuves du noyau et aux journaux QEMU.
Task 13: Inspect a VM start failure in task logs
cr0x@server:~$ journalctl -u pvedaemon -b | tail -n 20
Dec 26 10:18:11 pve1 pvedaemon[1321]: start VM 104: UPID:pve1:0000A3F9:00B2B6D1:676D5A13:qmstart:104:root@pam:
Dec 26 10:18:12 pve1 pvedaemon[1321]: VM 104 qmp command failed - unable to execute QMP command 'cont': Cannot allocate memory
Dec 26 10:18:12 pve1 pvedaemon[1321]: start failed: command '/usr/bin/kvm -id 104 ...' failed: exit code 1
Sens : L’échec se situe au stade de démarrage/cont de QEMU, pas à l’intérieur du guest.
Décision : Concentrez-vous sur les limites de commit de l’hôte, les hugepages, et la fragmentation — pas sur le tuning du guest.
Task 14: Validate container (LXC) memory configuration and swap limit
cr0x@server:~$ pct config 210 | egrep 'memory|swap|features'
memory: 4096
swap: 512
features: nesting=1,keyctl=1
Sens : Le conteneur a 4 GiB de RAM et 512 MiB de swap autorisé. S’il dépasse, les allocations échouent à l’intérieur du conteneur.
Décision : Pour les conteneurs, « impossible d’allouer la mémoire » est souvent une limite de cgroup. Augmentez memory/swap
ou corrigez le comportement de l’application. La mémoire libre de l’hôte ne sauvera pas un LXC avec un plafond dur.
Task 15: Check fragmentation risk signals (quick and dirty)
cr0x@server:~$ cat /proc/buddyinfo | head
Node 0, zone DMA 1 1 1 1 0 0 0 0 0 0 0
Node 0, zone DMA32 1024 512 220 12 0 0 0 0 0 0 0
Node 0, zone Normal 2048 1880 940 110 2 0 0 0 0 0 0
Sens : L’allocateur buddy montre combien de blocs libres existent à différents ordres. Si les ordres supérieurs sont
majoritairement à zéro, les grosses allocations contiguës (y compris certains besoins de hugepage) peuvent échouer même s’il y a « assez » de libre au total.
Décision : Si les hugepages/THP et la compaction sont dans votre configuration, envisagez de réduire la dépendance aux allocations contiguës
ou de planifier des redémarrages de maintenance périodiques pour les nœuds devant satisfaire ces allocations.
Trois mini-récits d’entreprise issus du terrain
Incident : une mauvaise hypothèse (« ballooning signifie qu’il ne réserve pas le max »)
Une entreprise de taille moyenne exploitait un cluster Proxmox interne pour des applications métiers et quelques gros jobs batch.
L’équipe avait pour habitude : mettre la mémoire max des VM élevée « pour que personne n’ait à ouvrir un ticket », puis fixer une cible balloon basse
pour « garder l’utilisation efficace ».
Ça marchait — jusqu’à ce qu’ils mettent à jour quelques VM et lancent un run de reporting trimestriel. De nouveaux processus ont été lancés, des maps mémoire
se sont étendues, et plusieurs VM ont été redémarrées pour des patchs. Soudain : impossible d’allouer la mémoire au démarrage des VM.
Le tableau de bord montrait encore de la « mémoire libre » parce que le cache semblait récupérable.
La cause racine n’était pas une fuite. C’était de la comptabilité. Le Committed_AS de l’hôte avait approché le CommitLimit.
Chaque VM avec un max généreux contribuait au total de mémoire promise, même si elle « restait » habituellement faible. Quand plusieurs redémarrages
ont eu lieu en même temps, QEMU a essayé de réserver ce qu’on lui avait dit qu’il pourrait avoir besoin. Le noyau a refusé. L’erreur était exacte ; leur modèle mental non.
La correction fut ennuyeuse : ils ont réduit le max mémoire des VM à ce que chaque service pouvait justifier, ont gardé le ballooning pour l’élasticité,
et ont ajouté du swap sur les hôtes où il manquait. Surtout, ils ont arrêté de traiter le « max » comme un souhait.
Le run du trimestre suivant a encore provoqué des pics, mais n’a plus cassé les redémarrages.
Optimisation qui s’est retournée contre eux (hugepages partout)
Une autre organisation recherchait la latence. Un ingénieur orienté perf a activé les hugepages pour toute une classe de VM car un blog disait que ça améliorait le comportement du TLB.
Et ça peut le faire. Ils ont aussi laissé les Transparent Huge Pages sur « always », parce que plus de hugepages semblait synonyme de plus de performance.
Voilà comment l’optimisme devient configuration.
Pendant des semaines, tout avait l’air normal. Puis un nœud a commencé à échouer aux démarrages de VM après des migrations routinières. Même VM démarrait sur d’autres nœuds.
Sur ce nœud : impossible d’allouer la mémoire. La mémoire libre n’était pas catastrophique, mais les hugepages libres étaient proches de zéro.
Buddyinfo montrait de la fragmentation : la mémoire était là, juste pas dans les bons morceaux.
Ils ont essayé de « réparer » en augmentant dynamiquement les hugepages. Ça a empiré : le noyau a dû compacter la mémoire pour satisfaire la demande, provoquant des
pics CPU et bloquant le reclaim. La latence a grimpé pendant les heures de pointe. Le rapport d’incident a appelé ça « intermittent ». C’était intermittent comme la gravité l’est quand vous êtes à l’intérieur d’un bâtiment.
Le plan de reprise : désactiver les hugepages pour les VM générales, réserver des hugepages seulement pour un petit ensemble d’instances critiques avec des tailles prévisibles,
et régler THP sur madvise. Les performances ont globalement amélioré parce que le système a arrêté de se battre lui-même.
Pratique ennuyeuse mais correcte qui a sauvé la journée (réserve hôte et caps)
Une troisième équipe exploitait Proxmox pour des charges mixtes : applis web, quelques VM Windows, et quelques appliances gourmandes en stockage.
Ils avaient une règle ennuyeuse : chaque nœud garde une « réserve hôte » fixe de RAM qui n’est jamais allouée aux guests sur le papier.
Ils limitaient aussi l’ARC ZFS dès le premier jour.
Ce n’était pas sophistiqué. Cela signifiait qu’ils pouvaient faire tourner moins de VM par nœud que ce que le tableur exigeait. Mais lors d’un incident où un guest bruyant a soudainement commencé
à consommer de la mémoire (un service Java mal configuré), l’hôte avait suffisamment de marge pour garder les processus QEMU vivants et éviter l’OOM de l’hôte.
Le guest a quand même souffert (comme il se doit), mais le rayon d’explosion est resté confiné à cette VM. Le cluster n’a pas commencé à tuer des charges non liées.
Ils ont drainé le nœud, corrigé la config du guest, et ont repris. Pas de redémarrage à minuit, pas d’échecs en cascade, pas de « pourquoi notre VM pare-feu est morte ? »
La pratique qui les a sauvés n’était pas un réglage noyau secret. C’était de la budgétisation et le refus d’épuiser le fonds d’urgence.
Erreurs fréquentes : symptôme → cause racine → correctif
La VM ne démarre pas : « Impossible d’allouer la mémoire » immédiatement
- Symptôme : Échec instantané au démarrage ; QEMU sort avec une erreur d’allocation.
- Cause racine : Limite de commit de l’hôte atteinte, hugepages manquantes, ou fragmentation mémoire pour l’allocation demandée.
- Correctif : Baissez le max mémoire de la VM ; ajoutez du swap sur l’hôte ; désactivez les hugepages pour cette classe de VM ; provisionnez les hugepages au démarrage si nécessaire.
La VM démarre, puis s’arrête ou se réinitialise de façon aléatoire
- Symptôme : La VM semble « crasher », les journaux ne montrent pas d’arrêt propre.
- Cause racine : Le tueur OOM de l’hôte a tué QEMU, souvent après un pic mémoire ou un reclaim intense.
- Correctif : Trouvez les logs OOM ; réduisez le surcommit de l’hôte ; réservez de la mémoire hôte ; limitez l’ARC ZFS ; assurez-vous que le swap existe et surveillez l’activité de swap.
Les guests ralentissent, puis l’hôte ralentit, puis tout devient philosophique
- Symptôme : IO wait augmente ; taux swap-in/out montent ; latence VM en pic.
- Cause racine : Thrashing : pas assez de RAM pour les working sets, et le swap/reclaim dominent.
- Correctif : Arrêtez ou migrez des VM ; réduisez les limites mémoire ; ajoutez de la RAM ; redesign de consolidation. Aucun sysctl ne vous sauvera ici.
Ballooning activé mais la mémoire ne « revient » jamais
- Symptôme : L’hôte reste plein ; les guests ne libèrent pas la mémoire comme prévu.
- Cause racine : Pilote balloon non installé/en cours d’exécution, le guest ne peut pas récupérer, ou le « max » force toujours l’engagement de l’hôte.
- Correctif : Installez le pilote virtio-balloon ; vérifiez dans le guest ; fixez des max réalistes ; utilisez le ballooning pour l’élasticité, pas comme substitut au dimensionnement.
Tout allait bien jusqu’à ce que les snapshots et la réplication ZFS augmentent
- Symptôme : La pression mémoire de l’hôte augmente pendant une activité de stockage intensive ; les démarrages de VM échouent.
- Cause racine : Croissance de l’ARC, pression sur les métadonnées, croissance du slab, et utilisation mémoire pilotée par l’IO.
- Correctif : Limitez l’ARC ; surveillez le slab ; gardez une marge ; évitez d’exploiter le nœud à 95% « utilisé » en l’appelant efficace.
Les conteneurs affichent « impossible d’allouer la mémoire » alors que l’hôte a l’air bien
- Symptôme : Les applications LXC échouent les allocations ; l’hôte a l’air OK.
- Cause racine : La limite de mémoire du cgroup est atteinte (plafond memory/swap du conteneur).
- Correctif : Augmentez les limites du conteneur ; ajustez l’application ; assurez-vous que le swap du conteneur est autorisé si vous attendez des pointes.
Listes de vérification / plan étape par étape
Étape par étape : réparer un nœud qui lance des erreurs d’allocation
-
Confirmer OOM hôte vs échec au démarrage.
Vérifiezjournalctl -kpour les kills OOM et les journauxpvedaemonpour le contexte d’échec de démarrage. -
Mesurer la pression de commit.
SiCommitted_ASest proche deCommitLimit, vous êtes en territoire « promesses > réalité ». -
Lister les VM avec des max mémoire élevés.
Réduisez le max mémoire des coupables. Ne vous contentez pas d’ajuster les cibles balloon. -
Vérifier les hugepages et les réglages THP.
Si les hugepages sont activées pour des VM, assurez-vous d’une préallocation adéquate ou désactivez-les pour les charges générales. -
Vérifier l’ARC ZFS si applicable.
Si l’ARC est volumineuse et que vous êtes avant tout un hôte VM, limitez-la. -
S’assurer que le swap existe et est sain.
Ajoutez du swap si nécessaire ; surveillezsi/so. Le swap est pour les pics, pas pour payer le loyer. -
Réserver de la mémoire pour l’hôte.
Gardez une réserve fixe pour l’hôte + ZFS + overhead QEMU. Votre futur vous remerciera en silence. -
Re-tester les démarrages de VM dans une séquence contrôlée.
Ne relancez pas tout d’un coup après le tuning. Démarrez d’abord les services critiques.
Réglage persistant : cap de l’ARC ZFS (exemple)
Si le nœud est un hôte VM et que ZFS est un moyen, fixez un maximum d’ARC. Une méthode courante :
créez un fichier de configuration modprobe et mettez à jour l’initramfs pour qu’il s’applique au démarrage.
cr0x@server:~$ echo "options zfs zfs_arc_max=17179869184" | sudo tee /etc/modprobe.d/zfs.conf
options zfs zfs_arc_max=17179869184
cr0x@server:~$ sudo update-initramfs -u
update-initramfs: Generating /boot/initrd.img-6.8.12-4-pve
Sens : ARC limité à 16 GiB (valeur en octets). Vous venez de dire à ZFS qu’il ne peut pas manger toute la machine.
Décision : Choisissez un cap qui laisse assez de RAM pour les guests plus la réserve hôte. Validez après redémarrage en relisant arcstats.
Réglage persistant : ajouter du swap hôte (exemple fichier)
cr0x@server:~$ sudo fallocate -l 8G /swapfile
cr0x@server:~$ sudo chmod 600 /swapfile
cr0x@server:~$ sudo mkswap /swapfile
Setting up swapspace version 1, size = 8 GiB (8589930496 bytes)
no label, UUID=0a3b1e4c-2f1e-4f65-a3da-b8c6e3f3a8d7
cr0x@server:~$ sudo swapon /swapfile
cr0x@server:~$ swapon --show
NAME TYPE SIZE USED PRIO
/swapfile file 8G 0B -2
Sens : Le swap est actif. CommitLimit augmente, et vous avez un tampon contre des pics d’allocations soudains.
Décision : Si l’utilisation du swap devient soutenue avec un si/so élevé, ce n’est pas « fonctionner comme prévu ».
C’est un signe pour réduire la consolidation ou ajouter de la RAM.
Politique : réserver de la RAM pour l’hôte (règle simple qui fonctionne)
-
Réservez au moins 10–20% de la RAM hôte pour l’hôte sur des nœuds mixtes.
Plus si vous exécutez ZFS, Ceph, du réseau lourd, ou beaucoup de petites VM. -
Gardez un objectif « somme des max des guests » que vous pouvez défendre. Si la somme des max VM dépasse un multiple défini de la RAM hôte,
ne le faites qu’intentionnellement et seulement si le comportement des charges le permet.
Checklist ballooning (utilisez-le correctement)
FAQ
1) Pourquoi Proxmox dit « impossible d’allouer la mémoire » alors que free montre des Go libres ?
Parce que free montre un instantané de la mémoire physique, tandis que la comptabilité de commit du noyau et les règles de fragmentation
peuvent refuser une nouvelle allocation. De plus, « libre » ignore si la mémoire est disponible sous la forme demandée (par ex. hugepages).
2) Le ballooning réduit-il ce que l’hôte doit réserver ?
Il réduit ce que le guest utilise à l’exécution, mais si votre VM a un max élevé, l’hôte peut rester engagé par la promesse.
Le ballooning n’est pas une carte « pas besoin de dimensionner ».
3) Dois-je mettre vm.overcommit_memory=1 pour arrêter les erreurs d’allocation ?
C’est un instrument brutal. Cela peut réduire les échecs au démarrage, mais augmente le risque d’OOM catastrophique plus tard.
En production, préférez corriger le dimensionnement des VM et ajouter du swap plutôt que d’assouplir les garde-fous du noyau.
4) Combien de swap un hôte Proxmox devrait-il avoir ?
Assez pour survivre aux pics et améliorer le CommitLimit, pas assez pour masquer un surcommit chronique. Communément : quelques Go à
quelques dizaines de Go selon la RAM de l’hôte et la volatilité des charges. Mesurez l’activité de swap ; si elle est constamment élevée, vous êtes sous-dimensionné.
5) L’ARC ZFS est-il la raison pour laquelle mon nœud « manque de mémoire » ?
Parfois. L’ARC peut grossir et concurrencer les VM. Si les démarrages de VM échouent ou que l’hôte OOM alors que l’ARC est massif,
limitez l’ARC. Si l’ARC est modeste, cherchez ailleurs (limites de commit, hugepages, VM runaway).
6) Dois-je activer KSM sur Proxmox ?
Si vous exécutez beaucoup de VM similaires (même OS, pages mémoire similaires), KSM peut économiser de la RAM. Cela coûte du CPU et peut ajouter de la latence.
Activez-le délibérément, mesurez l’overhead CPU, et ne le traitez pas comme de la mémoire gratuite.
7) Pourquoi les conteneurs atteignent « impossible d’allouer la mémoire » alors que l’hôte va bien ?
LXC est gouverné par les cgroups. Un conteneur peut manquer de mémoire à l’intérieur de sa limite même si l’hôte a de la marge.
Ajustez les limites pct memory/swap ou corrigez la charge du conteneur.
8) Les hugepages valent-elles le coup ?
Pour certaines charges à haut débit et sensibles à la latence : oui. Pour la consolidation générale : souvent non.
Les hugepages augmentent la prévisibilité du comportement du TLB mais réduisent la flexibilité et peuvent créer des échecs de démarrage si mal provisionnées.
9) Quelle est la différence entre OOM guest et OOM hôte ?
L’OOM guest se produit à l’intérieur de la VM : le noyau du guest tue des processus, mais la VM reste en ligne. L’OOM hôte tue des processus sur
l’hyperviseur, y compris QEMU — votre VM disparaît. L’OOM hôte est celui qui vous gâche l’après-midi.
10) Puis-je « réparer » ça définitivement sans ajouter de RAM ?
Souvent oui : fixez des max mémoire réalistes pour les VM, réservez de la RAM pour l’hôte, limitez l’ARC si besoin, et évitez des ratios de surcommit qui supposent des miracles.
Si les working sets dépassent réellement la RAM physique, la solution permanente est : plus de RAM ou moins de charges par nœud.
Étapes suivantes (la voie sensée)
« Impossible d’allouer la mémoire » dans Proxmox n’est pas une malédiction. C’est le noyau qui applique une frontière que vous avez déjà franchie en
politique, configuration ou attentes.
- Cessez de traiter le max mémoire des VM comme une suggestion. Faites-en un contrat.
- Utilisez le ballooning pour l’élasticité, pas pour le déni. Ciblez bas, plafonnez de façon réaliste.
- Donnez à l’hôte un fonds d’urgence. Réservez de la RAM ; ajoutez du swap ; maintenez l’ARC ZFS dans sa voie.
- Privilégiez des nœuds prévisibles plutôt que des réglages héroïques. Séparez les charges quand leurs modes d’échec diffèrent.
- Opérationnalisez cela. Ajoutez des alertes pour la proximité de CommitLimit, le taux swap-in/out, les logs OOM, et la taille de l’ARC.
Faites cela, et la prochaine fois que Proxmox se plaindra de mémoire, ce sera parce que vous êtes vraiment à court — pas parce que votre
configuration a raconté une histoire charmante que le noyau a refusé de croire.