Proxmox: налаштування «балонування», що створює штучний тиск пам’яті

Було корисно?

Усе здається «в порядку», поки не починає ломитися: ВМ має достатньо конфігурованої оперативної пам’яті, CPU мало завантажений, диск швидкий, але затримки повзають угору. Ваша база даних починає поводитися так, ніби працює з флешкою USB. Гість повідомляє про тиск пам’яті, swap зростає, кеші зникають, а графіки нагадують кардіограму.

Потім ви помічаєте це: балонування увімкнено. Хтось вирішив, що це «безкоштовна оптимізація». Насправді ви отримали штучний дефіцит — тиск пам’яті, створений гіпервізором, про який гостьова ОС не може знати, вона лише реагує.

Балонування в двох словах (і чому варто насторожитися)

Балонування пам’яті дозволяє хосту забирати RAM від запущеної ВМ, змушуючи гостя «використовувати» пам’ять внутрішньо, через що гість сам звільняє свої сторінки.

Звучить пристойно — ніби позичити стілець на вечірці. Насправді хост так, ніби вириває подушки з-під вас, поки ви ще сидите на дивані, а гість не здатний розрізнити, чи були ці подушки «вільним» кешем чи критичним робочим набором.

Моя принципова порада: якщо ви запускаєте щось станкове або чутливе до затримок (бази даних, пошук, брокери, CI-ранери з «гарячими» кешами, ZFS у гостьовій ОС, файлові сервери Windows), балонування зазвичай — це податок, який вам не потрібен. Купіть RAM. Або навмисно зменшіть ВМ. Не дозволяйте гіпервізору влаштовувати «дієту» під час робочого навантаження.

Кілька фактів і історичний контекст (6–10 швидких тез)

  • Балонування існувало до ери хмар. VMware популяризував балонування в ранніх ESX як практичний інструмент для overcommit пам’яті, коли RAM була дорогою, а консолідація — продажною перевагою.
  • KVM реалізує балонування переважно через virtio-balloon. Гість запускає драйвер, який виділяє сторінки й «закріплює» їх, щоб хост міг звільнити фізичну пам’ять.
  • Балонування цілиться в «невикористану» пам’ять… за визначенням гостя. Але те, що гість називає «невикористаним», включає файловий кеш, який може бути критично важливим для продуктивності.
  • Linux з часом став кращим у евристиках звільнення, але це все одно здогадки. Рішення про reclaim, свопінг і очищення кешу залежать від робочого навантаження й політики ядра, а не від ваших SLO.
  • Windows теж підтримує балонування, але видимість відрізняється. Поведінка драйвера й лічильники продуктивності не завжди збігаються з тим, що думає гіпервізор.
  • Балонування — не те саме, що memory hotplug. Hotplug змінює уявлення гостя про «встановлену» пам’ять; балонування залишає встановлену пам’ять такою ж і створює внутрішній тиск.
  • Transparent Huge Pages може ускладнити ситуацію. Якщо гість широко використовує THP, звільнення може фрагментувати пам’ять, збільшити роботу зкомпактації й викликати піки CPU під тиском.
  • Гіпервізори мають і більш жорсткий інструмент: swap хоста. Якщо хост занадто overcommit-лений і балонування не справляється, хост може свопити сторінки гостьових ОС — часто гірше, ніж гостьовий swap, бо гість не може цього оптимізувати.
  • Proxmox робить увімкнення балонування простим — зручно й небезпечно одночасно. Це чекбокс, який виглядає як економія, поки ви не заплатите хвостовою латентністю.

Що насправді робить балонування в Proxmox + KVM

Proxmox VE — це рівень управління над KVM/QEMU. Коли ви задаєте пам’ять ВМ, на практиці важливі два числа:

  • Memory (max): скільки QEMU може надати ВМ (і скільки гість вважає встановленим).
  • Balloon (min/target): наскільки низько Proxmox може притиснути ВМ під час тиску або згідно політики.

При увімкненому балонуванні QEMU використовує пристрій virtio-balloon. Драйвер гостя «надувається», виділяючи сторінки й повідомляючи хосту, що «ці сторінки не потрібні». Хост потім може повторно використати фізичну RAM для інших ВМ або для себе.

Є дві ключові практичні наслідки:

  1. Гість усе ще вірить, що має ту саму кількість встановленої пам’яті. ОС не отримує ввічливого повідомлення «у вас тепер 12 ГБ замість 16 ГБ». Вона просто бачить тиск пам’яті й реагує.
  2. Гіпервізор ухвалює рішення про продуктивність, маючи неповну інформацію. Він не бачить, які сторінки важливі з точки зору застосунку; він бачить лише сторінки. Тому він створює тиск, а гість сам має з цим розбиратися.

Балонування може бути прийнятним для мало навантажених загальних ВМ — уявіть утилітарні сервери, що більшість часу простають. Але для будь-чого з кешами або стійким робочим набором — це лотерея. А це більшість production-навантажень.

Є стара ідея операцій (парафраз): від Gene Kranz: дисципліна й відповідальна поведінка кращі за імпровізацію, коли системи поводяться дивно. Балонування — це імпровізація, прикрита політикою.

Як «штучний» тиск пам’яті перетворюється на реальну проблему

Щоб було ясно: походження тиску може бути «штучним», але біль реальний.

1) Гість спочатку звільняє page cache (а ви помічаєте це пізніше)

Linux охоче вилучає файловий кеш під тиском. Це нормально і часто правильне. Але якщо ваша продуктивність залежить від теплого кешу — індекси баз даних, вузли пошуку, CI, що тягне залежності — балонування викликає хаотичне оновлення кешів, що виглядає як випадкове погіршення дискової продуктивності.

Що робить це підступним: ви можете не бачити насичення диска. Ви бачите лише затримку. Більше IOPS, менші читання, більше метаданих. ZFS на хості теж стає більш зайнятим, бо гість просить дані, які раніше тримав гарячими.

2) Потім гість починає свопити (і ви звинувачуєте не ту частину)

Коли кеші зникають, reclaim доходить до анонімних сторінок: heap, стеки, пам’ять JVM, буфери бази даних. Якщо в гості ввімкнено swap (зазвичай так), ядро свопить. Затримки застосунків різко зростають, і ви починаєте звинувачувати масив зберігання, мережу або «того гучного сусіда». Іноді гучним сусідом є ваша власна політика гіпервізора.

Жарт #1: Балонування — це як «гаряче місце» для RAM — класно, поки ви не повернетесь з обіду й ваш стілець не сидить у swap.

3) Тиск на хості призводить до swap хоста (і це гірше)

Якщо хост перепакований і балонування не може швидко звільнити достатньо пам’яті, хост може свопити. Своп хоста жорстокий, бо гість не знає, які саме його сторінки були витіснені. Гість думає, що пам’ять усе ще в пам’яті; він постійно натикається на приховані мажорні помилки на рівні гіпервізора. Усунення несправностей стає грою в тіні.

4) Часування reclaim гіпервізора — не час вашого навантаження

Балонування не синхронізоване з вашими піками навантаження. Воно може надутись прямо перед запуском вашого пакетного завдання, у момент зростання черги або під час фаз з інтенсивною компактацією. У вас немає голосу. Ваш застосунок дізнається про нову реальність по одному page fault за раз.

5) Воно може перетворити «безпечний» оверпропертив на хаотичне перевантаження

Є законне використання overcommit: у великому парку не всі ВМ пікнуть одночасно. Але балонування дозволяє системі опинитися в області, де корельований пік (день деплою, щомісячні задачі, відкат при інциденті) створює раптову конкуренцію. Ця конкуренція не розділяється рівномірно — вона базується на balloon-цілях і на тому, кого натиснули першим.

Кому варто використовувати балонування (рідко) і кому не варто (більшість з вас)

Балонування може бути прийнятним, коли:

  • ВМ переважно простають і безстанні (jump box, внутрішні інструменти з низьким трафіком).
  • У вас є сильне, тривіальне управління ємністю і балонування — лише страховка.
  • Гостьова ОС та застосунки толерантні до reclaim без SLO по хвостовій латентності.
  • У вас є запас RAM на хості і ви використовуєте балонування переважно для зменшення марнотратства, а не для агресивної консолідації.

Балонування зазвичай погана ідея, коли:

  • Ви запускаєте бази даних (PostgreSQL, MySQL, MSSQL), пошук (Elasticsearch/OpenSearch), брокери повідомлень (Kafka/RabbitMQ), кеші (Redis) або сервіси з великим навантаженням JVM.
  • Ви покладаєтеся на файловий кеш як на функцію продуктивності (більшість Linux-сервісів так роблять, навіть якщо ви це заперечуєте).
  • У вас ZFS на хості, і ви вже покладаєтесь на RAM для ARC. Тепер ви жонглюєте двома голодними кеш- шарами.
  • Вам потрібна передбачувана продуктивність більше, ніж «висока завантаженість».

Моя стандартна рекомендація: вимикайте балонування для критичних ВМ, розміщуйте пам’ять навмисно, тримайте запас на хості й ставтеся до overcommit як до контрольованої речовини.

Швидкий план діагностики

Якщо продуктивність падає й ви підозрюєте балонування, не робіть зайвого. Тріажуйте у такому порядку:

Спочатку: чи справді хост під тиском пам’яті?

  • Перевірте вільну пам’ять хоста, використання swap і чи активний kswapd.
  • Якщо хост свопить — усуньте це перш ніж звинувачувати гостей.

Друге: чи гості відновлюють/своплять тому, що їх звузило балонування?

  • Перевірте статус балонування по кожній ВМ і різницю між макс-пам’яттю й поточним balloon.
  • Усередині гостя перевірте major faults, swap in/out та активність reclaim.

Третє: чи латентність зберігання — симптом колапсу кешу?

  • Перевірте непрямі ознаки гостьового кешу: збільшені read IOPS, метадані IO, випадкові читання та підвищену латентність без насичення пропускної здатності.
  • На ZFS-хостах перевірте поведінку ARC і події тиску пам’яті.

Четверте: вирішіть найменш ризикований негайний крок

  • Якщо балонування тисне критичну ВМ: підніміть її balloon target (або вимкніть балонування) і переконайтеся в запасі пам’яті на хості.
  • Якщо хост переповнений: мігруйте навантаження, додайте RAM, зменшіть алокації або зупиніть некритичні ВМ.

Практичні завдання: команди, виводи та рішення (12+)

Ось перевірки, які я реально запускаю на Proxmox-хостах та всередині гостей. Кожне завдання містить: команду, що означає вивід, і яке рішення ухвалюється.

Завдання 1: Швидка перевірка пам’яті хоста + swap

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

Значення: «available» — це те, що має значення для комфорту Linux-хоста. Використання swap на хості вже нетривіальне.

Рішення: Якщо swap хоста зростає під час інциденту — розглядайте це як P0. Зменшіть навантаження або додайте RAM перед тонкою налаштуванням гостей.

Завдання 2: Визначити, чи хост активно звільняє пам’ять

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

Значення: so (swap out) активний, а wa (IO wait) росте. Це означає, що хост витісняє сторінки.

Рішення: Зупиніть кровотечу: мігруйте ВМ, зупиніть некритичні робочі навантаження або додайте пам’ять. Балонування не врятує вас, якщо ви вже перейшли межу.

Завдання 3: Побачити топ-споживачів пам’яті на хості

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

Значення: Процеси QEMU домінують. Це очікувано; тепер треба знати, чи вони стиснені або «прикріплені».

Рішення: Перейдіть від «на хості є тиск» до «які ВМ це спричиняють і чи їх стискають».

Завдання 4: Перелік Proxmox ВМ і визначення кандидатів

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

Значення: Тепер у вас є VMID для запитів. Стовпець «MEM(MB)» — це налаштований максимум, а не обов’язково поточне balloon-використання.

Рішення: Спочатку інспектуйте ті ВМ, які потребують стабільної продуктивності (db-prod-1).

Завдання 5: Перевірити, чи налаштовано балонування для ВМ

cr0x@server:~$ qm config 101 | egrep -i 'memory|balloon'
balloon: 8192
memory: 16384

Значення: Цю ВМ можна опустити до 8 ГБ з максимуму 16 ГБ. Це не страховка; це інша особистість ВМ.

Рішення: Для критичних сервісів встановіть balloon: 0 (вимкнути) або підніміть його близько до максимуму, якщо ви справді потребуєте мінімального reclaim.

Завдання 6: Переглянути статистику balloon у runtime з хоста

cr0x@server:~$ qm monitor 101 --cmd 'info balloon'
balloon: actual=8704

Значення: ВМ наразі здута до ~8.5 ГБ. Якщо навантаження очікувало поведінки 16 ГБ — ви знайшли винуватця.

Рішення: Для негайного полегшення: підвищте balloon target або вимкніть балонування й підтвердіть запас пам’яті на хості.

Завдання 7: Підтвердити існування пристрою virtio balloon (гостьова ОС)

cr0x@server:~$ lsmod | grep balloon
virtio_balloon         24576  0

Значення: Гість здатен до балонування. Якщо модуль завантажено, він виконуватиме запити хоста щодо balloon.

Рішення: Для деяких appliance або чутливих навантажень можна видалити/заблокувати модуль — але краще виправляти це на рівні конфігурації Proxmox, щоб уникнути несподіванок пізніше.

Завдання 8: Перевірити індикатори тиску пам’яті в гості

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

Значення: PSI показує, що система часто гальмує під час reclaim (some) і інколи повністю блокується (full), що вбиває латентність.

Рішення: Якщо PSI підвищений під час інциденту й балонування активно — вважайте балонування ймовірною причиною, а не лише кореляцією.

Завдання 9: Швидко перевірити свопінг і поведінку reclaim в гості

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

Значення: so — постійний. Гість активно свопить. Кеш теж скорочується.

Рішення: Зупиніть своп-шторм: дайте ВМ реальну пам’ять (вимкніть балонування або збільшіть пам’ять), а потім розгляньте налаштування swappiness після відновлення стабільності.

Завдання 10: Перевірити major faults (гостьова ОС) для виявлення проблем із paging

cr0x@server:~$ grep -E 'pgmajfault|pgfault' /proc/vmstat
pgfault 348778901
pgmajfault 129988

Значення: Major faults вимагають IO. Зростання pgmajfault під час інциденту відповідає свопінгу або пропускам кешу.

Рішення: Якщо major faults ростуть, коли balloon зменшується — це не «повільність застосунку». Це голод пам’яті.

Завдання 11: Перевірити тиск ARC ZFS на хості (якщо використовується 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

Значення: Розмір ARC (arcsz) скорочується, у той час як miss% зростає. Тиск пам’яті на хості примушує ARC викидати дані, підвищуючи backend IO.

Рішення: Якщо одночасно ARC хоста колабсує й гості стиснуті, у вас двошаровий кеш-катастрофа. Додайте RAM або зменшіть тиск від ВМ; не намагайтесь «налаштувати» фізику.

Завдання 12: Перевірити пам’ять по QEMU з хоста, щоб помітити дивні речі

cr0x@server:~$ pmap -x 4121 | tail -n 5
total kB         17123456  8901232  120000  8200000

Значення: RSS високий; балонування не завжди відображається як нижчий RSS відразу через спосіб обліку й повторного використання пам’яті.

Рішення: Використовуйте статистику balloon і індикатори тиску хоста, а не лише RSS. Один лише RSS може ввести в оману.

Завдання 13: Перевірити журнали ядра на OOM або попередження reclaim (хост або гість)

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

Значення: Якщо тиск сильний, гість або хост можуть вбивати процеси. Балонування може бути співвиноювачем, звужуючи ефективну пам’ять.

Рішення: Якщо бачите OOM-kill-и — припиніть оптимізації й почніть виділяти. Виправте бюджет пам’яті спочатку.

Завдання 14: Вимкнути балонування для ВМ (контрольована зміна)

cr0x@server:~$ qm set 101 --balloon 0
update VM 101: -balloon 0

Значення: Балонування вимкнено. ВМ тепер має тримати свою сконфігуровану пам’ять без примусового reclaim від гіпервізора.

Рішення: Робіть це лише якщо на хості достатньо RAM. Якщо хост і так щільний, ви просто перемістите біль кудись ще (хост-своп).

Завдання 15: Підняти мінімальну ціль balloon замість вимкнення (компроміс)

cr0x@server:~$ qm set 102 --balloon 7168
update VM 102: -balloon 7168

Значення: ВМ 102 можна стиснути, але не нижче ніж до 7 ГБ. Це контрольований обмежувач «не моріть її голодом».

Рішення: Використовуйте це для середньокритичних сервісів, де деякий reclaim допустимий, але своп-шторм неприпустимий.

Завдання 16: Швидко перевірити позицію хоста щодо overcommit

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

Значення: Ви швидко бачите, кого можна стиснути і наскільки.

Рішення: Узгодьте політику balloon з рівнями сервісів. Якщо критична ВМ має великий діапазон balloon — виправте це зараз, а не під час наступного інциденту.

Три корпоративні міні-історії з практики

Міні-історія 1: Інцидент, спричинений хибним припущенням

Середня SaaS компанія мігрувала набір внутрішніх сервісів зі старого заліза на чистий кластер Proxmox. Вони зробили все правильно: резервні джерела живлення, пристойні SSD, подвійні NIC, і бекапи, що відновлювалися. Але зробили одну помилку: припустили, що «балонування означає, що ВМ віддає справді невикористану пам’ять».

Їхня PostgreSQL ВМ мала 32 ГБ максимум і 16 ГБ balloon. На папері — досить. Насправді навантаження залежало від файлового кешу Linux і shared buffers PostgreSQL, налаштованих під більший обсяг пам’яті. Під час робочого дня кластер трохи завантажився, Proxmox надуло balloon, і гість почав агресивно звільняти пам’ять.

Симптоми були спочатку непомітні: поодинокі стрибки запитів, збільшення часу чекпойнтів, більше IO jitter. Команда гналася за латентністю зберігання і навіть міняла прошивку NVMe. Тим часом гість тихенько нарощував використання swap, бо звик вважати, що «володіє» 32 ГБ, поки balloon тягнув його вниз.

Аутейдж стався у вівторок під час деплою, коли трафік і фонова міграція наклалися. Tail latency перетнув поріг тривоги і швидко перевищив його. Автоматичне масштабування не допомогло, бо масштабувались репліки застосунків, а не ВМ бази даних. База не була CPU-завантаженою; вона тонула в major faults.

Виправлення було нудним і миттєвим: вимкнули балонування для БД ВМ, правильно виставили пам’ять згідно того, що хост міг реально дозволити, і зберегли запас на хості. Продуктивність стабілізувалась за хвилини. Найболючіша рядок постмортему була чесною: «Ми вважали кеш безкоштовним». Кеш ніколи не безкоштовний; ви платите за нього в RAM або в латентності.

Міні-історія 2: Оптимізація, що обернулася проти

Великий ІТ-підрозділ мав завдання: підвищити щільність віртуалізації. Кластер Proxmox працював десятки Windows та Linux ВМ, багато з яких були «низького пріоритету». Хтось запропонував увімкнути балонування скрізь з агресивними мінімумами. Ідея — відібрати idle пам’ять і засунути більше ВМ на кожен вузол.

Спрацювало — спочатку. Графіки пам’яті хоста виглядали чудово. Завантаженість зросла. Щотижневий звіт мав цифри, що задовольняли менеджмент. Але потім прийшло щомісячне вікно патчів, і «низький пріоритет» перестав бути низьким. Усі оновлювали, перезавантажували, компілювали, сканували і логували одночасно.

Балонування почало надуватись по всьому флоту. Windows-гості почали сторінити. Linux-гості скидали кеші й переходили в reclaim. Контролер домену — налаштований як «не критичний», бо не клієнтський — теж стиснули. Затримки аутентифікації зросли. Багато сервісів не могли залогінитись, що спричинило повторні спроби, збільшення навантаження і ще більший reclaim. Класичний зворотний зв’язок, тепер із бюрократією.

Операції робили звичний танок: звинувачували SAN, мережу, патч. Але справжня помилка була в політиці: вони побудували систему, що залежить від того, що навантаження ніколи не корелюються. Підприємства — фабрики кореляцій. Вікна патчів, кінцеві звіти кварталу та сканування вразливостей синхронізують біль за визначенням.

Вони відкотили балонування на інфраструктурних ВМ, виставили розумні мінімальні значення для решти і створили бюджет ємності, що передбачав корельовані піки. Щільність трохи впала. Інциденти — значно. Єдина «оптимізація», що залишилась — правильна: купуйте достатньо RAM для реально працюючих навантажень.

Міні-історія 3: Нудна, але правильна практика, що врятувала день

Невелика fintech-команда використовувала Proxmox для суміші сервісів: API, брокер повідомлень, кілька баз даних і спостереження. У них було одне непопулярне правило: жодного балонування на tier-0 сервісах і жорстка вимога 25–30% запасу пам’яті на хості.

Це не подобалося під час закупівель. RAM — недешева, і «не використаний» запас виглядає як марнотратство у звіті. Але команда дотримувалась правила і задокументувала його як вимогу надійності, а не як уподобання.

Одного дня розробник випадково запустив runaway batch у не критичній аналітичній ВМ. CPU ріс, використання пам’яті зростало, і ВМ почала жадібно «їсти» файловий кеш. На щільно заповненому хості це могло примусити балонування інших ВМ або штовхнути хост у swap.

Але нічого не здригнулося. Шумна ВМ стала повільнішою — як і належить. База даних залишилась стабільною. Брокер повідомлень тримав хвостову латентність. Вони обмежили пакетну роботу і продовжили день.

Ось як виглядає хороша інфраструктура: радіус ураження передбачуваний. Це не захоплююче. Не створює історій героїв. Тихенько їх запобігає.

Поширені помилки: симптом → корінь → виправлення

1) Симптом: ВМ «має RAM», але все одно свопить

Корінь: Балонування звузило ефективну пам’ять ВМ; гість усе ще бачить встановлену пам’ять, але зазнає внутрішнього тиску reclaim.

Виправлення: Вимкніть балонування (qm set <vmid> --balloon 0) для цієї ВМ або підніміть мінімум balloon близько до максимуму. Переконайтеся, що на хості є запас.

2) Симптом: Випадкові стрибки латентності, особливо після періодів низької активності

Корінь: Колапс кешу. Балонування звільнило пам’ять, що використовувалась як файловий кеш; навантаження стає чутливим до IO, поки кеш не зігріється.

Виправлення: Не балонуйте робочі навантаження, що залежать від кешу. Правильно розмірюйте пам’ять. За потреби ізолюйте такі ВМ на вузлах з більшим запасом RAM і менше орендарями.

3) Симптом: IO wait на хості росте, але диски не «насичені»

Корінь: Свопінг або сторінкові штормі спричиняють багато дрібного випадкового IO з високою латентністю, а не обов’язково велику пропускну здатність.

Виправлення: Підтвердіть через vmstat і major faults у гості. Усуньте тиск swap на хості; зменшіть overcommit; припиніть балонування критичних ВМ.

4) Симптом: ZFS ARC скорочується і hit rate падає під час «навантажених» періодів

Корінь: Тиск пам’яті на хості — часто від overcommit плюс динаміки балонування — змушує ARC викидати дані, що посилює пропуски кешу гостей.

Виправлення: Збільшіть запас RAM на хості. Розгляньте налаштування zfs_arc_max лише після виправлення overcommit; обмеження ARC, щоб «зберегти пам’ять», часто просто переносить біль на IO.

5) Симптом: Ви вимкнули балонування, але стало гірше

Корінь: Хост вже був переповнений; балонування маскувало дефіцит ємності. Вимкнення перемістило біль на хост (swap або OOM).

Виправлення: Сприймайте це як питання ємності: мігруйте ВМ, зменшіть налаштовану пам’ять, додайте RAM або розподіліть навантаження по вузлах. Балонування — не заміна планування ємності.

6) Симптом: «Тільки CI-ранери повільні»

Корінь: CI-ранери залежать від кешів (пакетні кеші, кеші Docker-слоїв). Балонування порушує їх; часи збірки стають непередбачуваними.

Виправлення: Дайте CI-ранерам фіксовану пам’ять або перемістіть кеш у зовнішнє сховище, призначене для цього. Якщо потрібно ущільнити ранери, робіть це навмисно з нижчим max memory, а не динамічним балонуванням.

7) Симптом: Windows-гості відчуваються повільними, але метрики не кричать

Корінь: Балонування плюс механізм управління пам’яттю Windows може приховати реальну причину за високорівневими лічильниками; першим ви помічаєте «лаг» для користувача.

Виправлення: Корелюйте з хост-статистикою balloon (qm monitor ... info balloon) і тиском пам’яті хоста. Якщо хост тисне ВМ — припиніть це робити.

8) Симптом: Часті OOM-kill-и всередині контейнеризованого навантаження у ВМ

Корінь: Балонування зменшує доступну пам’ять ВМ; всередині неї cgroups застосовують ліміти; навантаження досягає свого cgroup OOM швидше.

Виправлення: Узгодьте бюджети: пам’ять ВМ має покривати резерв контейнерів. Вимкніть балонування або встановіть високий мінімум. Потім перегляньте контейнерні ліміти.

Жарт #2: Балонування — це єдина дієта, де вага спочатку бреше, а потім плаче ваша база даних.

Чеклісти / поетапний план

Чекліст A: Вирішіть, чи підходить балонування для вашого середовища

  1. Інвентаризуйте типи навантажень: бази даних, пошук, брокери, кеші, CI, файлові сервери, «інше».
  2. Позначте tier-0 і tier-1 сервіси: усе з жорсткими SLO або від чого залежать інші системи (DNS, auth, бази даних).
  3. Для tier-0/tier-1: вимкніть балонування (balloon: 0), якщо немає дуже вагомої причини.
  4. Для tier-2/tier-3: якщо увімкнюєте балонування, встановіть консервативний мінімум (не 50%, якщо ви не хочете 50% продуктивності).
  5. Встановіть політику хоста: підтримуйте запас пам’яті (я люблю 25–30% для змішаних навантажень; більше для інтенсивного ZFS-caching).
  6. Задокументуйте виключення з власниками і тригерами відкату.

Чекліст B: Безпечне для продакшну усунення неполадок, коли ви підозрюєте балонування

  1. Підтвердіть, що хост не сильно свопить (free -h, vmstat).
  2. Підтвердіть, що ВМ стиснута нижче свого максимуму (qm config + qm monitor ... info balloon).
  3. Перевірте PSI і активність swap у гості (/proc/pressure/memory, vmstat).
  4. Якщо ВМ tier-0: негайно підніміть balloon target (або вимкніть) і спостерігайте за пам’яттю хоста.
  5. Якщо хост на межі: спочатку мігруйте ВМ з вузла, потім вимикайте балонування.
  6. Після стабілізації: підкоригуйте max memory до правдивого числа і тримайте балонування вимкненим для цього сервісу.

Чекліст C: Побудуйте розумну модель пам’яті для Proxmox-вузлів

  1. Почніть з фізичної RAM.
  2. Відніміть фіксований резерв для хоста (OS + Proxmox-сервіси + буфер безпеки).
  3. Відніміть резерв для кешу зберігання (очікування ZFS ARC, метадані, IO-буфери).
  4. Розплануйте решту RAM як фіксовані алокації для tier-0/1 ВМ.
  5. Лише після цього розглядайте балонування для низькокритичних ВМ і обмежуйте, скільки можна звільнити.
  6. Плануйте корельовані події: вікна патчів, пакетні роботи, відкат, режим інциденту.

Поширені питання

1) Чи «погане» балонування Proxmox або воно просто зловживане?

Це інструмент, яким легко зловживати. У продакшні він часто стає заміною планування ємності. Обережно використаний для низькокритичних ВМ — може бути прийнятним. Широко застосований — виробляє латентність.

2) У чому різниця між балонуванням і memory hotplug?

Hotplug змінює уявлення гостя про встановлену RAM (він отримує або втрачає пристрої пам’яті). Балонування залишає встановлену пам’ять незмінною і створює внутрішній тиск через reclaim.

3) Чому балонування викликає своп у гості?

Тому що гість намагається задовольнити виділення пам’яті під тиском. Спочатку він скидає кеші, потім звільняє анонімні сторінки; якщо цього недостатньо — свопить, особливо якщо хост продовжує тиснути balloon вниз.

4) Якщо балонування відбирає «невикористану» пам’ять, чому продуктивність падає?

Бо «невикористана» включає кеш. Кеш може не бути активно захопленим застосунком, але він запобігає IO і підтримує передбачувану латентність. Видалення кешу — це як викинути інструменти, бо ви зараз їх не тримаєте в руках.

5) Чи варто вимкнути swap у гостях, щоб уникнути болю від балонування?

Не як перший крок. Вимкнення swap може перетворити тиск пам’яті на OOM-kill-и, що часто гірше. Виправте причину (балонування/overcommit). Потім вирішіть політику swap під конкретне навантаження.

6) Чи може балонування допомогти запобігти OOM на хості?

Іноді — так. Це один зі способів звільнити пам’ять перед тим, як хост дістанеться стіни. Але якщо ви регулярно на ньому покладаєтесь — ви працюєте занадто близько до краю. Правильне рішення — мати запас.

7) Чому я бачу swap на хості, хоча балонування увімкнено?

Бо балонування має обмеження (мінімальні цілі, швидкість reclaim, поведінка гостя). Якщо хост overcommit-лений або кілька ВМ пікнуть одночасно, балонування не встигає звільнити достатньо, і хост свопить.

8) Який мінімум balloon встановити, якщо я залишаю балонування увімкненим?

Почніть високо. Для сервісів, які вам важливі, встановіть мінімум близько до максимуму — думайте «можна забрати трохи вільного запасу», а не «можна скоротити ВМ удвічі». Для робочих ВМ можна бути агресивнішим, але тестуйте під навантаженням.

9) Чи погано балонування взаємодіє з ZFS на хості?

Може. ZFS любить RAM для ARC. Якщо ви overcommit-ите ВМ, а потім балонуєте їх, коли хост тисне ARC, ви ризикуєте подвійного колапсу кешів: гості скидуть кеш, хост скидатиме ARC, а диски отримають удар.

10) Як зрозуміти, що балонування є вузьким місцем, а не CPU або сховище?

Корелюйте: actual balloon зменшується, гостевий PSI і swap зростають, major faults підвищуються, а продуктивність падає без пропорційного завантаження CPU. Ця картина дуже характерна.

Висновок: практичні наступні кроки

Балонування не зле саме по собі. Воно просто надто охоче перетворює ваше продакшн навантаження на експеримент з управлінням пам’яттю, не питаючи дозволу.

Зробіть наступне:

  1. Виберіть свої tier-0 ВМ і вимкніть балонування на них сьогодні.
  2. Перевірте запас на хості: якщо ви регулярно близькі до межі, виправте ємність перш ніж налаштовувати опції.
  3. Використовуйте балонування лише як контрольовану політику для низькокритичних ВМ з консервативними мінімумами.
  4. Інструментуйте тиск пам’яті: активність swap хоста, PSI гостей та actual balloon vs max. Зробіть це видимим, щоб «таємна повільність» стала графіком, а не суперечкою.
  5. Запишіть правило: передбачувана продуктивність краща за хитру консолідацію. Ваш майбутній канал інцидентів скаже вам дякую.
← Попередня
Встановлення Ubuntu Server 24.04 LTS: мінімальна конфігурація, яка справді безпечна
Наступна →
Двовантаження Windows + Linux: налаштування, що переживе оновлення

Залишити коментар