Налаштування Linux OOM Killer для VPS: практичний посібник

12 хв читання - 8 червня 2026 р.

hero section cover
Зміст
  • Налаштування Linux OOM killer для VPS
  • Як OOM-кілер вибирає жертву
  • Виявлення навантаження на пам'ять до зупинки системи
  • Захист критичних процесів за допомогою oom_score_adj
  • Обмеження пам'яті за допомогою cgroups та systemd
  • Перегляд логів після події OOM
  • Підсумок
Поділитися

Налаштуйте Linux OOM killer на своєму VPS, щоб захистити бази даних і SSH, обмежити запущені процеси за допомогою cgroups і запобігти знищенню неправильних служб.

Налаштування Linux OOM killer для VPS

Linux OOM killer — це крайній захід ядра, коли закінчується пам'ять: він вибирає процес і припиняє його, щоб система продовжувала працювати. На VPS, де оперативної пам'яті мало і немає куди відступити, вибір за замовчуванням часто виявляється неправильним. Ваша база даних припиняється, довготривалий робочий процес виживає, і вам залишається з’ясовувати, чому. Цей посібник описує, як OOM killer оцінює процеси, як налаштувати цю оцінку на користь ваших критично важливих служб та як використовувати cgroups, щоб один неконтрольований процес не міг вивести з ладу решту системи.


 

Як OOM-кілер вибирає жертву

Коли ядро не може звільнити достатньо пам'яті за допомогою витіснення з кешу сторінок або підкачки, воно запускає OOM-кілер. Кожен процес має oom_score від 0 до 1000, що в основному виводиться з його розміру набору резидентних процесів (RSS) та використання свопу. Процес із найвищим балом отримує SIGKILL.

RSS домінує в розрахунку, тому вбивство майже завжди припадає на найбільшого споживача пам'яті. Це часто ваша база даних, сервер додатків або будь-який довготривалий процес, який виконує найкориснішу роботу. Процес, який фактично ініціював виділення пам'яті, «викликач», рідко є тим, що припиняється.

Існує два типи подій OOM, які потрібно розрізняти:

  • Глобальний OOM: хосту (або вашому VPS в цілому) не вистачає оперативної пам'яті та обміну. Ядро сканує кожен процес і вбиває той, що має найвищий бал.
  • Cgroup OOM: конкретна cgroup досягла свого ліміту пам'яті. Ядро завершує лише процеси всередині цієї cgroup, навіть якщо решта системи має вільну пам'ять.

Якщо ви налаштували обмеження модулів systemd або використовуєте контейнери, більшість ваших подій OOM будуть OOM cgroup. Це добре: радіус ураження обмежений.

Виявлення навантаження на пам'ять до зупинки системи

Події OOM майже ніколи не відбуваються раптово. Зазвичай спочатку спостерігається період наростання навантаження, і мета моніторингу полягає в тому, щоб виявити його саме в цей період.

free -h надає огляд системи. Колонка, що має значення, — це available, а не free: вона враховує кеш сторінок, який можна звільнити, і відображає те, що ви насправді можете виділити без підкачки. Тримайте MemAvailable на рівні приблизно 10–15 відсотків MemTotal під час пікового навантаження.

Для розподілу за процесами сортуйте за RSS:

ps aux --sort=-%mem | head -10

Або використовуйте htop і сортуйте за RES. Значення, які ви бачите тут, безпосередньо впливають на оцінку ядра, тому верхні записи є найбільш ймовірними об’єктами OOM.

У ядрах 4.20 та новіших «Інформація про затримку під тиском» (Pressure Stall Information) є системою раннього попередження, яку варто підключити до моніторингу:

cat /proc/pressure/memory

Цифра some avg10 цифра — це відсоток часу, протягом якого хоча б одне завдання застрягло в очікуванні пам'яті протягом останніх десяти секунд. Показник нижче 5 відсотків є нормальним. Тривалі значення вище 10 відсотків означають, що система витрачає реальний час, заблокована на звільненні пам'яті, і ймовірним є завершення процесу через OOM.

Переповнення підкачки відображається в vmstat 1 як ненульове si та so , що зберігаються протягом тривалого часу. Невелика кількість постійного обміну пам'яті є нешкідливою. Постійні операції завантаження та вивантаження з обміну — ні.

Захист критичних процесів за допомогою oom_score_adj

Оцінка, яку обчислює ядро, може бути скоригована для кожного процесу за допомогою oom_score_adjза шкалою від -1000 (імунітет) до +1000 (вбити мене першим). Коригування додається безпосередньо до кінцевого балу.

Для одноразової зміни щодо запущеного процесу:

echo -500 | sudo tee /proc/$(pidof sshd)/oom_score_adj

Для всього, що ви хочете зберегти після перезапуску, налаштуйте це в модулі systemd. Це правильне місце для sshd, вашої бази даних та всього іншого, що ви не можете собі дозволити втратити:

[Service]
OOMScoreAdjust=-900

Розумні значення за замовчуванням для початку:

  • sshd: -1000. Якщо ви втратите віддалений доступ під час кризи пам'яті, відновлення стане набагато складнішим.
  • MySQL, PostgreSQL, Redis: від -800 до -900. Надійний захист, який не робить їх повністю недоторканними в справді катастрофічній ситуації.
  • Робочі процеси додатків, пакетні завдання, завдання cron: від +100 до +500. Це процеси, які ви волієте бачити вбитими, ніж вашу базу даних.

Не встановлюйте для всіх -1000. Якщо нічого не можна завершити, ядро зрештою перейде в режим паніки або зависне, що ще гірше.

Обмеження пам'яті за допомогою cgroups та systemd

Регулювання балів впливає на те, що саме буде завершено. Cgroups впливають на те, чи відбудеться глобальне завершення взагалі. Встановивши для кожної служби жорстку верхню межу, ви переносите проблеми з пам'яттю в одну cgroup, замість того, щоб дозволити одному процесу вичерпати весь VPS.

У файлі модуля systemd:

[Service]
MemoryHigh=400M
MemoryMax=512M
OOMPolicy=stop
Restart=on-failure
RestartSec=5s

MemoryHigh є м'яким обмеженням: ядро агресивно відбирає сторінки з cgroup вище цієї точки, але нічого не завершує. MemoryMax є жорсткою межею. Якщо cgroup намагається виділити більше, ядро завершує процес всередині cgroup. З Restart=on-failure сервіс відразу ж відновлюється.

У cgroup v2 (Ubuntu 22.04 і пізніші версії, останні версії Debian, RHEL 9), memory.oom.group вбиває всі процеси в cgroup разом, замість того, щоб залишати сиріт. Корисно для багатопроцесорних служб, таких як пули PHP-FPM, де наполовину вбита група буде поводитися некоректно.

Кілька приміток щодо конкретних додатків, які варто врахувати:

  • PHP-FPM: налаштуйте pm = ondemand на невеликих екземплярах VPS і розмір pm.max_children відповідно до середнього RSS на одного працівника, а не за замовчуванням. Пул розміром 4 ГБ на VPS з 2 ГБ пам'яті викличе OOM при першому заповненні.
  • Node.js: обмежте купку V8 за допомогою --max-old-space-size=512 (у МБ). Без цього Node буде безперешкодно розширюватися, доки не втрутиться ядро.
  • MySQL та PostgreSQL: innodb_buffer_pool_size та shared_buffers повинні залишати достатній запас для кешу сторінок ОС, пам'яті з'єднання та будь-яких інших користувачів на сервері. Значення за замовчуванням передбачають використання виділеного сервера.

Перегляд логів після події OOM

Коли спрацьовує OOM-кілер, ядро записує детальний звіт у кільцевий буфер. Витягніть його за допомогою:

dmesg -T | grep -iE 'killed process|out of memory'
journalctl -k --grep='Out of memory'

Блок, який слід уважно прочитати, починається з викликувача і закінчується жертвою. Ядро виводить повний список завдань із RSS кожного процесу, використанням свопу та кінцевим oom_score_adj. Варто перевірити три речі:

  • Обмеження. CONSTRAINT_NONE означає глобальний OOM, CONSTRAINT_MEMCG означає, що cgroup досяг свого ліміту. Виправлення в кожному випадку різне
  • Free swap. Якщо це 0kB, то вичерпалися як оперативна пам'ять, так і обмінний простір. Додайте обмінний простір, збільште MemoryMax на порушнику, або зменшіть паралельність.
  • Оцінка жертви порівняно з усім іншим. Якщо оцінка жертви не набагато вища за наступні кілька процесів, ваші oom_score_adj значення не виконують достатньої роботи. Збільште розрив.

Що стосується конкретно OOM у cgroup, лічильник kill знаходиться memory.events всередині cgroup:

cat /sys/fs/cgroup/system.slice/mysql.service/memory.events

Зростаючий oom_kill значить, що служба постійно досягає свого ліміту. Це сигнал до підвищення MemoryMax, проаналізувати навантаження або перевести службу на більший тарифний план, а не продовжувати перезапускати її у циклі.

Підсумок

Налаштування OOM-кілера не полягає в тому, щоб його усунути. Воно полягає в тому, щоб контролювати, який процес поплатиться, коли закінчиться пам'ять, і зменшити радіус ураження, коли це станеться. Схема, яка працює в виробничому середовищі:

  • Захистіть ті сервіси, втрати яких ви не можете собі дозволити, особливо sshd та ваші бази даних.
  • Обмежте все інше за допомогою MemoryMax в модулі systemd, щоб один збій призвів лише до перезапуску, а не до відключення.
  • Слідкуйте за PSI та MemAvailable замість того, щоб чекати dmesg до того, як вони повідомлять вам про це згодом.
  • Залиште 15–20 відсотків оперативної пам'яті як запас. Налаштування не можуть компенсувати VPS, який просто замалий для робочого навантаження.

Якщо навантаження на пам'ять є структурним, а не пов'язаним з конфігурацією, вам потрібно більше оперативної пам'яті або швидше сховище з підтримкою свопу. Тарифи VPS від FDC Servers працюють на процесорах AMD EPYC із сховищем NVMe, що забезпечує достатню швидкість читання з підтримкою свопу, завдяки чому короткочасні сплески навантаження на пам'ять не переростають у завершення процесів.

Блог

На цьому тижні

Більше статей
Налаштування Linux OOM Killer для VPS: практичний посібник

Налаштування Linux OOM Killer для VPS: практичний посібник

Налаштуйте Linux OOM killer на своєму VPS, щоб захистити бази даних і SSH, обмежити запущені процеси за допомогою cgroups і запобігти знищенню неправильних служб.

12 хв читання - 8 червня 2026 р.

Керування трафіком у Linux: практичний посібник

12 хв читання - 5 червня 2026 р.

Більше статей
background image

Маєте запитання або потребуєте індивідуального рішення?

icon

Гнучкі варіанти

icon

Глобальне охоплення

icon

Миттєве розгортання

icon

Гнучкі варіанти

icon

Глобальне охоплення

icon

Миттєве розгортання