Гид по технологиям

Ограничение памяти в Docker: как и почему

• 6 min read • DevOps • Обновлено 28 Nov 2025
Ограничение памяти в Docker — руководство
Ограничение памяти в Docker — руководство

Логотип Docker (синий кит)

Быстрые ссылки

  • Как работают лимиты памяти в Docker

  • Установка жёстких и мягких лимитов памяти

  • Управление swap

  • Отключение убийц процессов при недостатке памяти

  • Краткое резюме

Docker-контейнеры по умолчанию работают без ограничений ресурсов. Процессы внутри контейнеров могут потреблять любую память, что потенциально влияет на соседние контейнеры и другие рабочие нагрузки на хосте.

Это опасно в продакшене. Каждый контейнер должен иметь разумный лимит памяти, чтобы предотвратить «бегство» потребления ресурсов. Правильные лимиты уменьшают конкуренцию за память и повышают общую стабильность системы.

Как работают лимиты памяти в Docker

Docker позволяет задать два типа лимитов: жёсткие и мягкие. Они по-разному влияют на доступность памяти и поведение при превышении лимита.

  • Жёсткие лимиты ограничивают объём памяти, доступный контейнеру. При превышении ядро обычно завершает процесс (OOM-killer).
  • Мягкие лимиты указывают ожидаемый объём использования. Контейнер может использовать больше памяти, если есть свободная физическая память. Но при дефиците памяти ОС может принудительно завершить процесс, если он превышает мягкий лимит.

Кроме того, Docker предоставляет настройки swap и поведение при ошибках OOM. Ниже — практические примеры и рекомендации.

Установка жёстких и мягких лимитов памяти

Жёсткий лимит задаётся флагом -m или --memory команды docker run.

-m

Например, значения:

512m

(мегабайты) или

2g

(гигабайты):

$ docker run --memory=512m my-app:latest

Контейнеры имеют минимальное требование памяти 6MB. Попытка указать значение меньше 6m вызовет ошибку.

Мягкий лимит задаётся через --memory-reservation. Он должен быть меньше чем --memory. Этот лимит действует только при конкуренции за память или при низком уровне свободной ОЗУ на хосте.

$ docker run --memory=512m --memory-reservation=256m my-app:latest

В этом примере контейнер резервирует 256MB памяти. Если процесс использует 300MB и на хосте идёт дефицит, процесс может быть завершён. При превышении 512MB контейнер всегда остановится.

Важные примечания

  • Указывайте --memory-reservation только для рабочих нагрузок, которые способны адаптироваться к уменьшению памяти.
  • Для JVM-приложений учитывайте –Xmx и поведение сборщика мусора. Мягкий лимит может вызвать непредсказуемое задержание GC.

Управление swap

Swap позволяет дописать содержимое памяти на диск после исчерпания RAM. Флаг --memory-swap контролирует общий объём доступной памяти вместе со swap. Работает только вместе с --memory.

$ docker run --memory=512m --memory-swap=762m my-app:latest

В этом примере контейнер видит 762MB общей памяти: 512MB RAM и 250MB swap на диске.

Если задать только --memory без --memory-swap, контейнер получает такой же объём swap, как и RAM:

$ docker run --memory=512m my-app:latest

Здесь всего 1024MB: 512MB RAM + 512MB swap.

Чтобы отключить swap, установите --memory-swap равным --memory. Тогда весь доступный объём будет только RAM.

Замечание: swap действует только если он включён на хосте. Отчёты о swap внутри контейнера ненадёжны — утилиты вроде free покажут swap хоста, а не то, что реально доступно контейнеру.

Отключение убийцы процессов при OOM

При ошибке OOM ядро обычно завершает процесс в контейнере, и контейнер выходит с кодом 137.

Флаг --oom-kill-disable отключает это поведение. Вместо завершения процессам будет блокироваться выделение новой памяти — они «зависнут», пока не освободят память или контейнер не перезапустят вручную.

$ docker run --memory=512m --oom-kill-disable my-app:latest

Используйте этот флаг только если у вас есть механизмы для наблюдения и восстановления при OOM. Часто лучше позволить ядру завершить процесс, чтобы orchestrator (например, systemd или Kubernetes) мог перезапустить контейнер.

Практическая методология: как выбрать лимиты

Мини-методика для настройки лимитов на сервис:

  1. Измерьте пиковое и среднее потребление памяти в тестовой среде при рабочей нагрузке.
  2. Установите --memory чуть выше пиков (например, +10–20%).
  3. Установите --memory-reservation равным среднему плюс буфер (например, среднее +10%).
  4. Тестируйте при искусственной нехватке памяти: смоделируйте наагрузйку и проверьте рестарты.
  5. Внедрите в staging, далее — в production по фазам.

Критерии приёмки

  • Контейнер не должен регулярно завершаться с кодом 137 при нормальной нагрузке.
  • При искусственной нехватке памяти процесс корректно рестартует и возвращается в работоспособное состояние.
  • Метрики использования памяти стабильны и предсказуемы в течение 7 дней нагрузки.

Альтернативные подходы и совместимость

  • Kubernetes: используйте limits.memory и requests.memory. Kubernetes переводит эти поля в cgroups и управляет OOM соответственно.
  • cgroups v2: в современных ядрах поведение меняется; проверьте поддержку cgroup v2 на хосте и особенности ограничений.
  • Systemd + docker: если вы запускаете контейнеры через systemd, дополнительно проверьте настройки slice и MemoryAccounting.

Когда этот подход не подходит

  • Реaltime-приложения с жёстким временем отклика могут страдать при использовании swap.
  • Приложения, которые само-оптимизируются под доступную память (например, базы данных), требуют специфичных внутренних конфигураций помимо внешних лимитов.

Хаки и эвристики для установки лимитов

  • Если приложение быстро растёт по памяти — начните с мягкого лимита, чтобы дать системе гибкость.
  • Для краткоживущих процессов выставляйте низкие --memory, чтобы быстрее обнаруживать утечки.
  • Для JVM учитывайте не только heap (-Xmx), но и native memory и metaspace.

Факто-бокс

  • Минимальная память контейнера: 6MB
  • Пример команд: --memory=512m, --memory-reservation=256m, --memory-swap=762m
  • Код выхода при OOM-kill: 137

Руководство по развёртыванию лимитов в кластере (Playbook)

  1. Соберите метрики по памяти по всем сервисам в течение 7–14 дней.
  2. Подготовьте список сервисов с текущим пиком, средним и 95-й перцентиль.
  3. Предложите --memory = 95-й перцентиль + 10%. Предложите --memory-reservation = медиана + 10%.
  4. Разверните в тестовой группе (10% контейнеров). Наблюдайте 72 часа.
  5. Если сервисы стабильны — расширьте до 50%, затем до 100%.
  6. Документируйте политику лимитов для новых сервисов.

Роль‑ориентированные чек‑листы

  • Для разработчика:

    • Измерьте использование памяти локально и в staging.
    • Установите JVM-параметры (если применимо).
    • Обновите Dockerfile и docker run/Compose конфигурацию с рекомендуемыми лимитами.
  • Для инженера DevOps:

    • Соберите метрики по сервисам.
    • Протестируйте поведение OOM и swap в staging.
    • Автоматизируйте внедрение лимитов через CI/CD.
  • Для инженера по наблюдаемости:

    • Настройте алерты по использованию памяти и по перезапускам с кодом 137.
    • Ведите дашборд по средней и пиковй памяти на контейнер.

Тесты и критерии приёмки

Тестовые сценарии:

  • Нормальная нагрузка: контейнер не превышает --memory и не рестартует.
  • Пиковая нагрузка выше --memory-reservation но ниже --memory: контейнер продолжает работу, но генерирует предупреждения алерта.
  • Искусственный OOM: при превышении --memory контейнер завершается кодом 137, orchestrator перезапускает контейнер.
  • Поведение с --oom-kill-disable: при исчерпании памяти процесс блокируется, контейнер не завершён, наблюдается зависание.

Критерии приёмки описаны выше в разделе «Критерии приёмки».

Отладка и распространённые проблемы

  • Команда docker stats показывает использование памяти контейнера в реальном времени.
  • Если внутри контейнера free показывает необычные значения — помните, что они отражают состояние хоста.
  • Логи с кодом выхода 137 указывают на OOM-killer. Проверьте dmesg и syslog на события OOM.
  • Если swap не действует — убедитесь, что swap включён на хосте и что Docker запущен с нужными правами.

Decision tree (Как выбрать конфигурацию памяти)

flowchart TD
  A[Начало: нет лимитов] --> B{Нагрузка стабильна?}
  B -- Да --> C[Установить --memory = пиковое + 10%]
  B -- Нет --> D{Есть ли автоскейлинг?}
  D -- Да --> E[Установить --memory-reservation = медиана + 10%]\
  D -- Нет --> F[Установить --memory и включить мониторинг]
  C --> G[Тестировать 72 часа]
  E --> G
  F --> G
  G --> H{Появляются OOM?}
  H -- Да --> I[Увеличить --memory или оптимизировать приложение]
  H -- Нет --> J[Применить на проде постепенно]

Сравнение с Kubernetes

Kubernetes предоставляет поля requests и limits. Requests влияют на планирование, а limits — на поведение OOM. Карта соответствия:

  • Docker --memory ~= Kubernetes limits.memory
  • Docker --memory-reservation ~= Kubernetes requests.memory

Если вы используете Kubernetes, применяйте те же методики измерения и тестирования.

Краткое резюме

Docker-контейнеры по умолчанию не ограничены по памяти. Используйте --memory для жёсткого контроля и --memory-reservation для гибкости. Настройте swap осознанно и тестируйте поведение при OOM. Автоматизируйте внедрение лимитов и мониторьте их эффект.

Важно: корректные лимиты повышают надёжность системы и делают поведение приложений предсказуемым.

Последние шаги

  • Соберите метрики и составьте план внедрения.
  • Тестируйте на staging и применяйте поэтапно.
  • Настройте алерты на перезапуски и высокое использование памяти.

Обратите внимание

  • Не используйте --oom-kill-disable без зрелых процедур восстановления.
  • Swap может скрыть проблемы с утечками памяти и ухудшить производительность.

Ограничения и дальнейшие шаги

Если вы управляете кластером, рассмотрите перенос управления ресурсами на оркестратор (Kubernetes) и централизованное управление метриками и алертами.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Несколько аккаунтов Skype: Multi Skype Launcher
Программное обеспечение

Несколько аккаунтов Skype: Multi Skype Launcher

Журнал для работы: повысить продуктивность
Productivity

Журнал для работы: повысить продуктивность

Персональные звуки уведомлений на Android
Android.

Персональные звуки уведомлений на Android

Скачивание шоу Hulu для офлайн‑просмотра
Стриминг

Скачивание шоу Hulu для офлайн‑просмотра

Microsoft Start: персонализированная новостная лента
Новости

Microsoft Start: персонализированная новостная лента

Как изменить имя в Epic Games быстро
Гайды

Как изменить имя в Epic Games быстро