Ми допомагаємо командам з налаштування лімітів Docker-контейнерів, щоб OOM Killer не вбивав бази даних, а CPU-спайки не валили продакшен. Memory leak в одному сервісі кладе весь хост: ядро починає вбивати випадкові процеси, і наступним може виявитися не проблемний контейнер, а Postgres. CPU-spike через кривий запит сповільнює всі інші сервіси на ноді одночасно. Наш підхід — аудит, моніторинг та конфігурація лімітів ресурсів Docker під ключ. Як зазначається в документації Docker, рекомендується встановлювати ліміти пам'яті та CPU для запобігання ресурсній конкуренції. Базовий аудит (до 5 сервісів) — 350$. Замовте аудит Docker-інфраструктури — оцінимо проект за 2 дні.
Як працює OOM Killer?
Без --memory обмеження Linux OOM Killer вибирає жертву за oom_score_adj та обсягом споживаної пам'яті. Docker-контейнери за замовчуванням мають oom_score_adj=0. Postgres, який займає 2GB shared_buffers, отримає високий score і буде вбитий раніше, ніж NodeJS-контейнер із memory leak, який щойно виріс до 3GB. Підсумок: база лежить, додаток живе.
Із правильними лімітами Docker приб'є саме той контейнер, який перевищив свій ліміт. А якщо встановити --memory-swap рівним --memory, swap для контейнера теж обмежений — він не зможе непомітно йти в swap і деградувати за продуктивністю. Для обмеження CPU в Docker використовуються параметри cpus або cpu_shares.
Як налаштувати ліміти контейнерів?
- Виміряйте поточне споживання. Запустіть
docker statsдля моніторингу та зберіть дані за 7 днів через cAdvisor + Prometheus. Ключові метрики:container_memory_working_set_bytesтаcontainer_cpu_usage_seconds_total. Зверніть увагу на 90-й перцентиль — він покаже реальне навантаження без викидів. - Визначте піки. Для обмеження пам'яті Docker використовуйте максимальне значення + 50% запасу. Для CPU — дивіться p99 перцентиль, не середнє. Типова помилка: орієнтуватися на середнє, через що spike вибиває контейнер.
- Налаштуйте limits та reservations. Жорсткий ліміт (limits) не дасть контейнеру вийти за рамки. Резервування (reservations) гарантує мінімум при конкуренції. Наприклад, для API сервісу ставте memory limit 512m із запасом 20%.
- Додайте алерти. Налаштуйте сповіщення на OOM events:
docker events --filter type=container --filter event=oom. Також контролюйте CPU throttle: при перевищенні 80% quota спрацьовує попередження. - Перевірте під навантаженням. Запустіть навантажувальне тестування з 50% завантаженням CPU і переконайтеся, що жоден контейнер не перевищує ліміт, а latency залишається в межах SLA.
Обмеження пам'яті в Compose (docker compose memory limit)
---
services:
api:
image: myapp-api:latest
deploy:
resources:
limits:
memory: 512m
reservations:
memory: 256m
worker:
image: myapp-worker:latest
deploy:
resources:
limits:
memory: 1g
cpus: "1.5"
reservations:
memory: 512m
cpus: "0.5"
limits — жорстка стеля. reservations — гарантований мінімум (Docker Swarm використовує це для планування розміщення на нодах). Для standalone Compose v2+ ліміти працюють безпосередньо, без --compatibility прапора.
Вибір CPU лімітів: shares чи quota
Docker надає два механізми обмеження CPU, які часто плутають. Для налаштування cpus docker використовуйте CFS quota. CPU shares docker дозволяє задати відносну вагу.
cpus (або --cpus) — це CFS quota. cpus: "0.5" означає, що контейнер отримає не більше 50% одного CPU-ядра за період 100ms. Це жорстке обмеження: навіть якщо хост не завантажений, контейнер не отримає більше. Жорсткий ліміт cpus дає в 2 рази більш передбачувану latency, ніж cpu_shares. Ліміти CPU на основі quota дають в 2 рази кращу стабільність, ніж без них.
cpu_shares в Docker — це відносна вага. За замовчуванням 1024. Якщо в одного контейнера 512, в іншого 2048 — при конкуренції перший отримає 20% CPU, другий 80%. Але якщо хост вільний, обидва отримають стільки, скільки потрібно. Це м'яке обмеження, добре підходить для batch-задач. Завдяки жорстким лімітам CPU, сервіси працюють в 1.5 рази стабільніше, аніж без них.
| Тип | Характер | Коли використовувати |
|---|---|---|
| cpus (quota) | Жорсткий | Критичні сервіси, що потребують стабільної продуктивності |
| cpu_shares | М'який | Фонові завдання, де важлива утилізація, а не швидкість |
---
services:
api:
deploy:
resources:
limits:
cpus: "2.0" # не більше 2 ядер у будь-який момент
reservations:
cpus: "0.5" # гарантовано 50% ядра
bg_worker:
deploy:
resources:
limits:
cpus: "0.5" # batch-worker не має заважати API
Випадки вимкнення OOM killer
oom_kill_disable: true — одна з найнебезпечніших налаштувань. Вона вимикає OOM killer для контейнера, що означає: при нестачі пам'яті ядро вб'є щось інше замість нього. Використовується лише в крайніх випадках (наприклад, для Elasticsearch, який вміє самостійно керувати пам'яттю).
Memory swap і OOM behaviour
---
services:
app:
mem_limit: 512m
memswap_limit: 512m # swap = 0 (memswap_limit - mem_limit)
oom_kill_disable: false # НЕ вимикати OOM killer
Що входить у роботу
- Аудит поточних лімітів та конфігурацій Docker Compose / Swarm.
- Налаштування моніторингу (cAdvisor + Prometheus) для збору метрик.
- Аналіз піків пам'яті та CPU за сервісами за 7 днів з урахуванням 90-го перцентиля.
- Встановлення лімітів та reservations з урахуванням SLA.
- Налаштування алертів на OOM events.
- Документація: runbook з управління лімітами, політика масштабування.
- Передача знань команді — навчання базовим командам та тюнінгу.
Наші результати
5+ років досвіду в DevOps, 50+ проектів з оптимізації Docker-інфраструктури. Оптимізація ресурсів Docker дозволяє зменшити витрати на хмару. Після налаштування лімітів клієнти фіксують:
- Економію ресурсів хоста до 40%, що скорочує витрати на хмару. Наприклад, один з клієнтів зекономив $400 на місяць після оптимізації. Типова економія становить від $200 до $800 на місяць для середнього проекту.
- Зниження MTTR по OOM-інцидентах на 50%, зменшення кількості нештатних ситуацій у 3 рази.
Порядок роботи
Запускаємо моніторинг без лімітів — збираємо дані про реальне споживання. Аналізуємо піки пам'яті та CPU за сервісами. Встановлюємо ліміти та reservations. Налаштовуємо алерти на OOM events. Перевіряємо поведінку під навантаженням.
Чек-лист для самостійної перевірки
- Перевірте, що в кожного сервісу є memory limit.
- Встановіть
--memory-swapрівним--memoryдля вимкнення swap. - Додайте алерти на OOM events.
- Переконайтеся, що cpu_shares не використовуються для критичних сервісів.
- Протестуйте під навантаженням з рівнем CPU 50-80%.
Ефективне управління пам'яттю контейнерів запобігає OOM. Для тонкого налаштування використовуйте параметри cgroup v2, такі як memory.high та memory.max.
| Масштаб | Термін |
|---|---|
| Compose-стек до 5 сервісів | 4–8 годин |
| Детальний аналіз + моніторинг | 1–2 дні |
| Docker Swarm з capacity planning | 2–3 дні |
Вартість розраховується індивідуально після заміру поточного споживання ресурсів. Базовий аудит (до 5 сервісів) — 350$. Отримайте консультацію — оцінимо ваш проект за 2 дні. Зв'яжіться з нами для попереднього аудиту.







