Haces clic en Start en una VM y Proxmox responde con el equivalente digital de un encogimiento de hombros:
«no se puede asignar memoria». O peor, la VM arranca y luego el host empieza a matar procesos al azar
como un encargado estresado en un teatro con una sola salida.
Las fallas de memoria en Proxmox no son místicas. Son problemas de contabilidad: lo que el host cree que tiene,
lo que las VMs afirman que podrían usar, lo que realmente tocan y lo que el kernel está dispuesto a
prometer en ese momento. Arregla la contabilidad y la mayoría del drama desaparece.
Guía rápida de diagnóstico
Si estás de guardia y el cluster está gritando, no quieres una clase de filosofía. Quieres un bucle cerrado:
confirma el modo de fallo, identifica el limitador, haz un cambio seguro, repite.
Primero: ¿es esto agotamiento de memoria del host o un límite por VM?
-
Si la VM falla al iniciar con no se puede asignar memoria, sospecha límites de compromiso del host,
límites de cgroup, hugepages o fragmentación—a menudo visible inmediatamente endmesg/ journal. -
Si la VM arranca y luego es asesinada, suele ser el OOM killer del invitado (dentro de la VM) o
el OOM killer del host (matando QEMU), dependiendo de qué registros muestren el golpe.
Segundo: comprueba la «capacidad real» del host, no los gráficos bonitos
- Memoria libre del host y swap:
free -h - Presión de memoria del host y stalls de reclaim:
vmstat 1 - Evidencia de OOM:
journalctl -kydmesg -T - Tamaño de ZFS ARC (si usas ZFS):
arcstat//proc/spl/kstat/zfs/arcstats
Tercero: verifica la asignación y la política en el lado de Proxmox
-
Configuración de la VM: objetivo de ballooning vs máximo, hugepages, NUMA, etc.:
qm config <vmid> -
Política de sobreasignación del nodo:
pvesh get /nodes/<node>/statusy
/etc/pve/datacenter.cfg -
Si es un contenedor (LXC), comprueba el límite de memoria del cgroup y el límite de swap:
pct config <ctid>
Cuarto: elige la mitigación inmediata menos mala
- Para liberar RAM y reducir la presión ahora: detén una VM no crítica.
- Si ZFS está comiéndose la máquina: limita ARC (persistente) o reinicia como último recurso.
- Si estás sobreasignado: reduce la memoria máxima de las VMs (no solo el objetivo del balloon).
- Si no hay swap y estás justo: añade swap (host) para evitar OOM instantáneos mientras arreglas el dimensionamiento.
Chiste #1: La sobreasignación de memoria es como el presupuesto corporativo—todo funciona hasta que todos tratan de justificar el almuerzo el mismo día.
Qué significa realmente «no se puede asignar memoria» en Proxmox
Proxmox es una capa de gestión. El asignador real es Linux, y para VMs suele ser QEMU/KVM. Cuando ves
no se puede asignar memoria, está ocurriendo una de estas cosas:
-
QEMU no puede reservar la RAM solicitada por la VM en el momento de inicio. Eso puede fallar incluso si
freeparece correcto, porque a Linux le importan las reglas de compromiso y la fragmentación. -
El kernel rechaza la asignación debido a la lógica de overcommit/CommitLimit. Linux rastrea cuánto
memoria han prometido potencialmente usar los procesos (memoria virtual), y puede negar nuevas promesas. -
Se piden hugepages pero no están disponibles. Las hugepages están pre-reservadas. Si no existen,
la asignación falla de forma inmediata y ruidosa. -
Los límites de cgroup bloquean la asignación. Más común con contenedores, pero puede aplicarse si systemd
slices o cgroups personalizados están en juego. -
La memoria está disponible pero no en la forma que pediste. La fragmentación puede impedir asignaciones
contiguas grandes, especialmente con hugepages o ciertas necesidades DMA.
Mientras tanto, la «solución» a la que recurren la gente—ballooning—no cambia lo que QEMU pidió si aún configuraste una gran
memoria máxima. Ballooning ajusta lo que el invitado se anima a usar, no lo que el host debe estar preparado
para respaldar en el peor momento posible.
Dos números importan: objetivo del invitado y máximo del invitado
En las opciones de VM de Proxmox, el ballooning te da:
- Memory (max): el techo de la VM. QEMU contabiliza reservas por ello.
- Balloon (min/target): el objetivo en tiempo de ejecución que puede reducirse bajo presión.
Si estableces max en 64 GB «por si acaso» y objetivo del balloon en 8 GB «porque normalmente está inactiva», le has dicho al host:
«Por favor, prepárate para cubrir mis 64 GB de estilo de vida». El host, siendo adulto, puede decir que no.
Hechos interesantes y un poco de historia (para que no lo repitas)
-
El comportamiento de overcommit de Linux es antiguo e intencional: existe porque muchas asignaciones nunca se usan por completo,
y una contabilidad estricta desperdiciaría RAM en promesas vacías. -
El OOM killer precede a la mayoría de las pilas modernas de virtualización; fue la respuesta pragmática de Linux a «alguien está mintiendo
sobre la memoria» mucho antes de que el marketing de la nube convirtiera mentir en una característica. -
El ballooning se volvió común con los primeros hipervisores porque los invitados ociosos acaparaban caché y hacían que la consolidación
pareciera peor de lo que era. -
KSM (Kernel Samepage Merging) fue diseñado para desduplicar páginas de memoria idénticas entre VMs—especialmente común cuando
muchas VMs ejecutan la misma imagen del SO. -
Transparent Huge Pages (THP) se introdujeron para mejorar el rendimiento usando páginas mayores automáticamente, pero
pueden crear picos de latencia bajo presión de memoria debido al trabajo de compactación. -
ZFS ARC no es «solo caché». Compite con la memoria anónima. Si no lo limitas, consumirá RAM hasta que el kernel lo obligue
a ceder—a veces demasiado tarde. -
Los cgroups cambiaron la situación: en lugar de que todo el host sea una familia feliz, ahora los límites de memoria pueden
hacer que una sola VM o contenedor falle aun cuando el host parece bien. -
Antes se recomendaba swap obligatoriamente; luego la gente lo abusó; luego la gente lo rechazó; luego los SSD modernos hicieron
que «un swap pequeño y controlado» vuelva a tener sentido en muchos casos.
Una cita operativa que sigue siendo dolorosamente relevante (idea parafraseada): Werner Vogels ha dicho que el núcleo de la
fiabilidad es esperar fallos y diseñar para ello, no fingir que no ocurrirán.
Ballooning: qué hace, qué no hace y por qué te confunde
Qué es realmente el ballooning
El ballooning usa un driver dentro del invitado (típicamente virtio-balloon). El host le pide al invitado «inflar» un globo,
es decir: asignar memoria dentro del invitado y fijarla para que el invitado no pueda usarla. Desde la perspectiva del host,
esa memoria pasa a ser reclamable porque el invitado la cedió voluntariamente.
Es ingenioso. También está limitado por la física y el comportamiento del invitado:
- Si el invitado está bajo presión real de memoria, no puede darte mucho sin hacer swap o sufrir OOM él mismo.
- Si el invitado no tiene el driver del balloon, el ballooning es básicamente danza interpretativa.
- El ballooning es reactivo. Si el host ya está en problemas, puede que llegues demasiado tarde.
Ballooning en Proxmox: la trampa importante
La configuración de ballooning en Proxmox a menudo da una falsa sensación de seguridad. La gente pone objetivos de balloon bajos y
memoria máxima alta, pensando que «solo usan el objetivo». Pero la contabilidad de QEMU y la lógica de compromiso del kernel
a menudo deben considerar la máxima.
Postura operativa: el ballooning es una herramienta de ajuste, no una excusa para evitar dimensionar. Úsalo para
cargas elásticas donde el SO invitado pueda manejarlo. No lo uses como estrategia principal para meter VMs en un host hasta que
este se queje.
Cuándo vale la pena el ballooning
- Clusters de desarrollo/pruebas donde los invitados están inactivos y los picos son raros y tolerables.
- Flotas tipo VDI con muchas VMs similares, a menudo combinadas con KSM.
- Servidores de propósito general donde puedes imponer valores máximos sensatos, no fantasiosos.
Cuándo el ballooning es una trampa
- Bases de datos con latencia estricta y pools de búfer (la presión de memoria en el invitado se convierte en presión IO).
- Sistemas con swap deshabilitado en los invitados (el ballooning puede forzar OOM dentro del invitado).
- Hosts ya ajustados en memoria donde el tiempo de respuesta del ballooning es demasiado lento.
Sobreasignación: cuándo es sensata y cuándo es temeraria
Tres «sobreasignaciones» diferentes que la gente confunde
En la práctica, estás manejando tres capas:
-
Sobreasignación del scheduler/contabilidad de Proxmox: si Proxmox cree que está bien iniciar otra VM
según la RAM configurada, objetivos de balloon y la memoria del nodo. -
Sobreasignación de memoria virtual de Linux:
vm.overcommit_memoryyCommitLimit. -
Sobreasignación física real: si la suma de la memoria activamente usada por los invitados excede la RAM del host
(y si tienes swap, compresión o un plan).
Contabilidad de commit de Linux en un párrafo operativo
Linux decide si permitir una asignación basada en cuánto podría usarse si los procesos lo tocan. Ese número «podría usarse» se
rastrea como Committed_AS. El techo permitido es CommitLimit, aproximadamente RAM + swap menos algunas reservas,
modificado por las configuraciones de overcommit. Si Committed_AS se acerca al CommitLimit, el kernel empieza
a rechazar asignaciones—hola, «no se puede asignar memoria».
Guía con opinión
-
Producción: mantén la sobreasignación moderada y aplica máximos de VM realistas. Si no puedes declarar tu
ratio de sobreasignación y tu plan de expulsión, no estás sobreasignando—estás apostando. - Laboratorio: sobreasigna agresivamente si aceptas eventos OOM ocasionales. Solo etiquétalo honestamente y deja de fingir que es prod.
-
Cargas mixtas: separa usuarios ruidosos de memoria (BD, analítica) en sus propios nodos o capéalos fuertemente.
«Coexistencia» es como la gente llama a la situación justo antes de la revisión del incidente.
ZFS ARC, caché de páginas y la memoria del host que olvidaste presupuestar
Proxmox a menudo se ejecuta sobre ZFS porque los snapshots y send/receive son adictivos. Pero ZFS no tiene vergüenza: usará RAM
para ARC (Adaptive Replacement Cache). Eso es genial hasta que no lo es.
ARC frente a «memoria libre»
ARC es reclamable, pero no instantáneamente y no siempre de la forma que quiere el inicio de una VM. Bajo presión, el kernel
intenta reclamar page cache y ARC, pero si estás en un bucle ajustado de asignaciones (iniciar una VM, inflar memoria,
forkear procesos), puedes sufrir fallos transitorios.
Qué hacer
-
En hosts ZFS con muchas VMs, fija un máximo sensato para ARC (
zfs_arc_max). No dejes que ARC «compita» con tus invitados. -
Trata la memoria del host como infraestructura compartida. El host necesita memoria para:
kernel, slab, red, metadatos ZFS, overhead de QEMU y tus agentes de monitorización que juran ser ligeros.
Swap: no es un pecado, pero tampoco un plan de vida
No tener swap significa que has quitado los amortiguadores. Con virtualización, eso puede ser fatal porque un pico repentino
de presión se convierte en kills OOM inmediatos en lugar de una degradación lenta y diagnosticable.
Pero el swap también puede convertirse en un lodazal de rendimiento. El objetivo es un swap controlado: suficiente para
sobrevivir a ráfagas, no suficiente para ocultar una sobreasignación crónica.
Recomendaciones de swap para el host (prácticas, no dogmáticas)
-
Si ejecutas ZFS y muchas VMs: añade swap. Incluso una cantidad moderada puede evitar que el host mate
QEMU durante picos breves. -
Si tu almacenamiento es lento: mantén el swap más pequeño y prioriza un dimensionamiento correcto de RAM.
Hacer swap a un RAID HDD ocupado no es «estabilidad», es «sufrimiento prolongado». -
Si usas SSD/NVMe: el swap es mucho más tolerable, pero sigue sin ser gratuito. Monitoriza la tasa de swap-in/out,
no solo el swap usado.
Chiste #2: El swap es como una reunión que pudo haber sido un correo—a veces salva el día, pero si vives allí, tu carrera se acaba.
Tareas prácticas: comandos, salidas y decisiones (12+)
Estas son las comprobaciones que realmente ejecuto cuando un nodo Proxmox empieza a lanzar errores de asignación de memoria. Cada tarea incluye:
un comando, salida de ejemplo, qué significa y qué decisión impulsa.
Tarea 1: Comprobar RAM y swap del host de un vistazo
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
Significado: «available» es tu margen a corto plazo antes de que el reclaim se ponga feo. 2.8 GiB en un host de 62 GiB
con virtualización es ajustado pero no instantáneamente catastrófico.
Decisión: Si available es < 1–2 GiB y las VMs están fallando al iniciar, detén VMs no críticas ahora.
Si swap es 0, añade swap como estabilizador mientras corriges el dimensionado.
Tarea 2: Identificar si el kernel está rechazando asignaciones por límites de commit
cr0x@server:~$ grep -E 'CommitLimit|Committed_AS' /proc/meminfo
CommitLimit: 71303168 kB
Committed_AS: 70598240 kB
Significado: Estás cerca del techo de commit. El kernel puede rechazar nuevas reservas de memoria incluso si
hay caché que podría reclamarse.
Decisión: Reduce las memorias máximas de las VMs, añade swap (aumenta CommitLimit) o mueve cargas.
Cambios en el objetivo del balloon no ayudarán si el problema es el máximo.
Tarea 3: Confirmar la política de sobreasignación
cr0x@server:~$ sysctl vm.overcommit_memory vm.overcommit_ratio
vm.overcommit_memory = 0
vm.overcommit_ratio = 50
Significado: El modo 0 es overcommit heurístico. Ratio importa sobre todo para el modo 2. Aún así, la conducta de commit está en juego.
Decisión: No cambies esto en pánico a menos que entiendas el impacto. Si estás tocando los límites de commit,
arreglar el dimensionado es mejor que «simplemente sobreasignar más».
Tarea 4: Buscar evidencia del OOM killer en el 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
Significado: El host mató a QEMU. Esa VM no «falló», fue ejecutada.
Decisión: Trátalo como agotamiento de memoria del host/sobreasignación. Reduce consolidación, capea ARC, añade swap
y deja de confiar en el ballooning como cinturón de seguridad.
Tarea 5: Comprobar la presión de memoria y el comportamiento de reclaim en vivo
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
Significado: Valores no nulos en si/so indican swapping. Alto wa sugiere IO wait.
Si b crece y id se desploma, el host está thrashing.
Decisión: Si el swapping es sostenido y el IO wait sube, detén VMs o mueve carga. No puedes «afinar» para salir de una tormenta de thrash en tiempo real.
Tarea 6: Encontrar los mayores consumidores de memoria en el host (RSS, no fantasías VIRT)
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
Significado: RSS es memoria residente real. Los procesos QEMU dominan, como era de esperar.
Decisión: Si una VM se descontrola, capea su memoria máxima o investiga dentro del invitado.
Si son «muchas VMs medianas», es matemática de consolidación, no un villano único.
Tarea 7: Inspeccionar la configuración de memoria de una VM (ballooning vs max)
cr0x@server:~$ qm config 104 | egrep 'memory|balloon|numa|hugepages'
memory: 32768
balloon: 8192
numa: 1
hugepages: 2
Significado: Max es 32 GiB, objetivo del balloon 8 GiB. Hugepages están habilitadas (2 = hugepages de 2MB).
Decisión: Si el nodo falla al asignar, el max de 32 GiB de esta VM podría ser demasiado generoso.
Si hugepages están habilitadas, confirma disponibilidad de hugepages (Tarea 8) o deshabilítalas para más flexibilidad.
Tarea 8: Validar disponibilidad de hugepages (causa clásica de fallos al iniciar)
cr0x@server:~$ grep -i huge /proc/meminfo
AnonHugePages: 1048576 kB
HugePages_Total: 8192
HugePages_Free: 120
HugePages_Rsvd: 50
Hugepagesize: 2048 kB
Significado: Solo 120 hugepages libres (~240 MiB). Si intentas iniciar una VM que necesita muchas hugepages, falla.
Decisión: O provisiona suficientes hugepages en el arranque, o deja de usar hugepages para esa clase de VMs.
Las hugepages son una herramienta de rendimiento, no un defecto por defecto.
Tarea 9: Comprobar el comportamiento de THP (puede causar latencia bajo presión)
cr0x@server:~$ cat /sys/kernel/mm/transparent_hugepage/enabled
[always] madvise never
Significado: THP está habilitado siempre.
Decisión: Para nodos sensibles a la latencia, considera madvise o never.
No cambies esto en medio de un incidente a menos que estés seguro; planea un mantenimiento y mide.
Tarea 10: Si usas ZFS, verifica rápidamente el tamaño del ARC
cr0x@server:~$ awk '/^size/ {print}' /proc/spl/kstat/zfs/arcstats
size 4 34359738368
Significado: ARC es ~32 GiB. En un host de 64 GiB con muchas VMs, eso puede ser demasiado.
Decisión: Si te falta memoria y ARC es grande, limita ARC de forma persistente (ver sección de checklist)
y planifica un reinicio si necesitas alivio inmediato.
Tarea 11: Confirmar estado de KSM (ayuda con muchas VMs similares, pero puede costar CPU)
cr0x@server:~$ systemctl is-active ksmtuned
inactive
Significado: El servicio de tuning de KSM no está activo. En algunas configuraciones Proxmox, KSM se configura diferente;
esto es solo una señal rápida.
Decisión: Si ejecutas docenas de VMs similares, habilitar KSM puede reducir uso de memoria. Si la CPU ya está caliente,
KSM puede ser contraproducente. Prueba en un nodo primero.
Tarea 12: Comprobar info de memoria en el nodo Proxmox (qué cree Proxmox que está pasando)
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
}
Significado: La API de Proxmox da una vista que puede diferir de tus expectativas inmediatas (unidades,
caching y tiempo). No la trates como verdad absoluta; coteja con free y meminfo.
Decisión: Usa esto para automatización y dashboards, pero al depurar fallos de asignación, confía primero
en la evidencia del kernel y los logs de QEMU.
Tarea 13: Inspeccionar un fallo de inicio de VM en los logs de tareas
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
Significado: El fallo está en la etapa de arranque/cont de QEMU, no dentro del invitado.
Decisión: Concéntrate en límites de commit del host, hugepages y fragmentación—no en ajustes dentro del invitado.
Tarea 14: Validar la configuración de memoria de un contenedor (LXC) y el límite de swap
cr0x@server:~$ pct config 210 | egrep 'memory|swap|features'
memory: 4096
swap: 512
features: nesting=1,keyctl=1
Significado: El contenedor tiene 4 GiB RAM y 512 MiB de swap permitido. Si hace picos por encima, las asignaciones fallan dentro del contenedor.
Decisión: Para contenedores, «no se puede asignar memoria» suele ser un límite de cgroup. Aumenta memory/swap
o arregla el comportamiento de la aplicación. La memoria libre del host no salvará a un LXC con un techo rígido.
Tarea 15: Comprobar señales de riesgo de fragmentación (rápido y tocho)
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
Significado: El buddy allocator muestra cuántos bloques libres existen en diferentes órdenes. Si los órdenes altos están
mayormente en cero, las asignaciones contiguas grandes (incluyendo algunas necesidades de hugepage) pueden fallar aun con «suficiente total libre».
Decisión: Si las hugepages/THP/compactación son parte de tu configuración, considera reducir la dependencia de asignaciones
contiguas o programar reinicios de mantenimiento periódicos para nodos que deben satisfacer esas asignaciones.
Tres microhistorias corporativas desde el frente
Incidente: una suposición errónea («ballooning significa que no reservará el máximo»)
Una compañía mediana ejecutaba un cluster Proxmox interno para apps de línea de negocio y algunos trabajos batch pesados.
El equipo tenía la costumbre: poner la memoria máxima de la VM alta «para que nadie tenga que abrir un ticket», y luego poner
el objetivo del balloon bajo para «mantener la utilización eficiente».
Funcionó—hasta que actualizaron algunas VMs y lanzaron una corrida de reportes trimestrales. Nuevos procesos se generaron, los mapas de memoria
se expandieron y varias VMs se reiniciaron para parcheo. De repente: no se puede asignar memoria al iniciar VMs.
El dashboard aún mostraba «free» porque la caché parecía reclamable.
La causa raíz no fue una fuga. Fue contabilidad. El Committed_AS del host se acercó al CommitLimit.
Cada VM con un máximo generoso contribuyó al total de memoria prometida, aunque «normalmente» estuviera baja. Cuando varios
reinicios ocurrieron juntos, QEMU intentó reservar lo que se le había dicho que podía necesitar. El kernel se negó. El error
fue correcto; su modelo mental no.
La solución fue aburrida: redujeron la memoria máxima de las VMs a lo que cada servicio podía justificar, mantuvieron el ballooning
para elasticidad y añadieron swap en hosts donde faltaba. Lo más importante: dejaron de tratar el «max» como un deseo.
La siguiente corrida trimestral aún hizo picos, pero dejó de romper los reinicios.
Optimización que salió mal (hugepages por todas partes)
Otra organización persiguió la latencia. Un ingeniero orientado al rendimiento habilitó hugepages para toda una clase de VMs porque un blog
decía que mejoraba el comportamiento del TLB. Y puede hacerlo. También dejaron Transparent Huge Pages en «always», porque más hugepages
sonaban a más rendimiento. Así es como el optimismo se vuelve configuración.
Durante semanas, todo parecía bien. Luego un nodo empezó a fallar al iniciar VMs tras migraciones rutinarias. La misma VM arrancaba en
otros nodos. En este nodo: no se puede asignar memoria. La memoria libre no estaba mal, pero las hugepages libres estaban casi a cero.
Buddyinfo mostró fragmentación: la memoria existía, solo que no en los trozos adecuados.
Intentaron «arreglarlo» aumentando hugepages dinámicamente. Eso lo empeoró: el kernel tuvo que compactar memoria para satisfacer la petición,
generando picos de CPU y bloqueando reclaim. La latencia se disparó durante las horas punta. Lo mejor es que el informe de incidente lo llamó
«intermitente». Fue intermitente como la gravedad lo es cuando estás dentro de una habitación.
El plan de recuperación fue: deshabilitar hugepages para VMs generales, reservar hugepages solo para un pequeño conjunto de instancias
críticas y previsibles, y poner THP en madvise. El rendimiento mejoró en general porque el sistema dejó de pelear consigo mismo.
Práctica aburrida pero correcta que salvó el día (reserva y límites en el host)
Un tercer equipo usaba Proxmox para cargas mixtas: apps web, algunas VMs Windows y un par de appliances intensivos en almacenamiento.
Tenían una regla sosa: cada nodo mantiene una «reserva del host» fija de RAM que nunca se asigna a invitados en papel.
También limitaron ZFS ARC desde el primer día.
No era sofisticado. Significaba que podían ejecutar menos VMs por nodo de lo que la hoja de cálculo quería. Pero durante un incidente
donde un invitado ruidoso empezó a consumir memoria (un servicio Java mal configurado), el host tuvo suficiente margen para mantener
vivos los procesos QEMU y evitar un OOM del host.
El invitado aún sufrió (como debía), pero el radio de impacto se quedó dentro de esa VM. El cluster no empezó a matar cargas no relacionadas.
Dranearon el nodo, arreglaron la configuración del invitado y reanudaron. Sin reinicio a medianoche, sin fallos en cascada, sin «¿por qué murió nuestra VM de firewall?»
La práctica que los salvó no fue un ajuste secreto del kernel. Fue presupuestar y negarse a gastar el fondo de emergencia.
Errores comunes: síntoma → causa raíz → solución
La VM no arranca: «No se puede asignar memoria» inmediatamente
- Síntoma: El inicio falla al instante; QEMU sale con error de asignación.
- Causa raíz: Límite de commit del host alcanzado, hugepages faltantes o fragmentación para la asignación solicitada.
- Solución: Baja la memoria máxima de la VM; añade swap en el host; deshabilita hugepages para esa VM; provisiona hugepages en el arranque si es necesario.
La VM arranca y luego se apaga o reinicia aleatoriamente
- Síntoma: La VM parece «caerse», los logs no muestran un apagado limpio.
- Causa raíz: El OOM killer del host mató a QEMU, a menudo tras un pico de memoria o un reclaim intenso.
- Solución: Encuentra logs de OOM; reduce la sobreasignación del host; reserva memoria del host; capea ZFS ARC; asegúrate de que exista swap y monitoriza su actividad.
Los invitados se vuelven lentos, luego el host se vuelve lento y todo se vuelve filosófico
- Síntoma: IO wait sube; tasas de swap-in/out aumentan; la latencia de las VMs se dispara.
- Causa raíz: Thrashing: no hay suficiente RAM para los working sets, y swap/reclaim domina.
- Solución: Detén o migra VMs; reduce límites de memoria; añade RAM; rediseña la consolidación. Ningún sysctl te salvará aquí.
Ballooning habilitado pero la memoria nunca «vuelve»
- Síntoma: El host sigue lleno; los invitados no liberan memoria como se esperaba.
- Causa raíz: Driver de balloon no instalado/activo, el invitado no puede reclamar o el «max» aún obliga al compromiso del host.
- Solución: Instala el driver virtio-balloon; verifica dentro del invitado; fija un max realista; usa ballooning como elasticidad, no como sustituto del dimensionado.
Todo iba bien hasta que aumentaron los snapshots y la replicación de ZFS
- Síntoma: La presión de memoria del host aumenta durante actividad intensiva de almacenamiento; se fallan inicios de VM.
- Causa raíz: Crecimiento del ARC, presión de metadatos, crecimiento de slab y uso de memoria dependiente de IO.
- Solución: Capa ARC; monitoriza slab; mantén margen; evita correr el nodo al 95% de «usado» y llamarlo eficiente.
Los contenedores muestran «no se puede asignar memoria» mientras el host tiene bastante
- Síntoma: Apps dentro de LXC fallan asignaciones; el host parece bien.
- Causa raíz: Límite de memoria del cgroup alcanzado (cupo memory/swap del contenedor).
- Solución: Eleva límites del contenedor; ajusta la aplicación; asegúrate de que el swap del contenedor esté permitido si esperas picos.
Listas de comprobación / plan paso a paso
Paso a paso: arreglar un nodo que lanza errores de asignación
-
Confirma OOM del host vs fallo en tiempo de inicio.
Revisajournalctl -kpor kills OOM y logs depvedaemonpara el contexto del fallo de inicio. -
Mide la presión de commit.
SiCommitted_ASestá cerca deCommitLimit, estás en territorio de «promesas exceden la realidad». -
Lista VMs con memoria máxima grande.
Reduce la memoria máxima de las culpables. No te limites a ajustar objetivos de balloon. -
Comprueba hugepages y ajustes de THP.
Si hugepages están habilitadas para VMs, asegúrate de preasignación adecuada o apágalas para cargas generales. -
Comprueba ZFS ARC si aplica.
Si ARC es grande y eres primero un host de VMs, capéalo. -
Asegúrate de que exista swap y sea sensato.
Añade swap si no hay; monitorizasi/so. El swap es para picos, no para pagar la renta. -
Reserva memoria para el host.
Mantén un buffer fijo para host + ZFS + overhead de QEMU. Tu yo futuro te lo agradecerá en silencio. -
Vuelve a probar inicios de VM en secuencia controlada.
No inicies todo de golpe tras ajustar. Inicia servicios críticos primero.
Ajuste persistente: tope de ZFS ARC (ejemplo)
Si el nodo es un host de VMs y ZFS es un medio, establece un máximo para ARC. Un método común:
crea un archivo de configuración de modprobe y actualiza initramfs para que se aplique al arranque.
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
Significado: ARC capado a 16 GiB (el valor está en bytes). Le acabas de decir a ZFS que no se coma toda la máquina.
Decisión: Elige un tope que deje suficiente RAM para invitados más la reserva del host. Valida tras reiniciar leyendo arcstats de nuevo.
Ajuste persistente: añadir swap al host (ejemplo con archivo)
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
Significado: El swap está activo. CommitLimit aumenta y tienes un colchón contra ráfagas de asignación.
Decisión: Si el uso de swap se vuelve sostenido con alto si/so, eso no está «funcionando como diseñado».
Es señal de reducir consolidación o añadir RAM.
Política: reservar RAM para el host (una regla simple que funciona)
-
Reserva al menos 10–20% de la RAM del host para el host en nodos mixtos.
Más si ejecutas ZFS, Ceph, redes pesadas o muchas VMs pequeñas. -
Mantén un objetivo de «suma máxima de memoria de invitados» que puedas defender. Si la suma de los valores máximos de VM excede un múltiplo fijo
de la RAM del host, hazlo intencionalmente y solo donde el comportamiento de cargas lo soporte.
Checklist de ballooning (úsalo correctamente)
Preguntas frecuentes
1) ¿Por qué Proxmox dice «no se puede asignar memoria» cuando free muestra GB libres?
Porque free muestra una instantánea de la memoria física, mientras que la contabilidad de commit del kernel y las reglas de fragmentación
pueden negar una nueva asignación. Además, «free» ignora si la memoria está disponible en la forma necesaria (p. ej., hugepages).
2) ¿El ballooning reduce lo que el host debe reservar?
Reduce lo que el invitado usa en tiempo de ejecución, pero si tu VM tiene un máximo alto, el host todavía puede estar obligado por la promesa.
Ballooning no es un salvoconducto para evitar dimensionar.
3) ¿Debería poner vm.overcommit_memory=1 para evitar fallos de asignación?
Eso es una herramienta brusca. Puede reducir fallos en el inicio, pero aumenta la posibilidad de un OOM catastrófico después.
En producción, es preferible arreglar el dimensionado de VMs y añadir swap antes que aflojar las barreras de seguridad del kernel.
4) ¿Cuánto swap debería tener un host Proxmox?
Suficiente para sobrevivir ráfagas y mejorar CommitLimit, no tanto como para ocultar una sobreasignación crónica. Comúnmente: unos pocos GB hasta decenas bajas de GB
dependiendo de la RAM del host y la volatilidad de las cargas. Mide la actividad de swap; si está constantemente ocupada, estás subdimensionado.
5) ¿Es ZFS ARC la razón por la que mi nodo «se queda sin memoria»?
A veces. ARC puede crecer y competir con las VMs. Si los inicios de VM fallan o el host OOM mientras ARC es masivo,
limita ARC. Si ARC es moderado, busca en otro lado (límites de commit, hugepages, invitados descontrolados).
6) ¿Debería habilitar KSM en Proxmox?
Si ejecutas muchas VMs similares (mismo SO, páginas de memoria parecidas), KSM puede ahorrar RAM. Cuesta CPU y puede añadir latencia.
Habilítalo deliberadamente, mide la sobrecarga de CPU y no lo trates como memoria gratis.
7) ¿Por qué los contenedores reciben «no se puede asignar memoria» cuando el host está bien?
LXC está gobernado por cgroups. Un contenedor puede quedarse sin memoria dentro de su límite aunque el host tenga bastante.
Ajusta límites con pct o arregla la carga del contenedor.
8) ¿Merecen la pena las hugepages?
Para ciertas cargas de alto rendimiento y baja latencia: sí. Para consolidación general: a menudo no.
Las hugepages aumentan la predictibilidad del comportamiento del TLB pero reducen la flexibilidad y pueden crear fallos de inicio si no se provisioning con cuidado.
9) ¿Cuál es la diferencia entre OOM del invitado y OOM del host?
OOM del invitado ocurre dentro de la VM: el kernel del invitado mata procesos, pero la VM sigue en pie. OOM del host mata procesos en
el hipervisor, incluyendo QEMU—tu VM desaparece. El OOM del host es el que arruina la tarde.
10) ¿Puedo «arreglar» esto permanentemente sin añadir RAM?
A menudo sí: fija memorias máximas realistas para las VMs, reserva RAM para el host, limita ARC si hace falta y evita ratios de sobreasignación
que asumen milagros. Si los working sets exceden genuinamente la RAM física, la solución permanente es: más RAM o menos cargas por nodo.
Próximos pasos (los sensatos)
«No se puede asignar memoria» en Proxmox no es una maldición. Es el kernel aplicando un límite que ya cruzaste en
política, configuración o expectativas.
- Deja de tratar la memoria máxima de la VM como sugerencia. Hazla un contrato.
- Usa ballooning para elasticidad, no para negación. Objetivo bajo, tope realista.
- Da al host un fondo de emergencia. Reserva RAM; añade swap; mantén ZFS ARC en su carril.
- Prefiere nodos predecibles sobre ajustes heroicos. Separa cargas cuando sus modos de fallo difieran.
- Operationaliza esto. Añade alertas para proximidad a CommitLimit, tasa de swap-in/out, logs OOM y tamaño de ARC.
Haz eso, y la próxima vez que Proxmox se queje de memoria, será porque realmente te quedaste sin ella—no porque tu
configuración contó una historia encantadora que el kernel se negó a creer.