Поиск по сайту:

Как установить ограничение памяти для контейнеров Docker


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

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

Как работают ограничения памяти Docker

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

  • Жесткие ограничения памяти устанавливают абсолютный предел памяти, предоставляемой контейнеру. Превышение этого ограничения обычно приводит к тому, что средство устранения нехватки памяти ядра завершает процесс контейнера.
  • Мягкие ограничения памяти указывают объем памяти, который, как ожидается, будет использовать контейнер. Контейнеру разрешено использовать больше памяти, когда емкость доступна. Он может быть прерван, если он превышает мягкое ограничение в условиях нехватки памяти.

Docker также предоставляет элементы управления для установки ограничений памяти подкачки и изменения того, что происходит при достижении предела памяти. В следующих разделах вы увидите, как их использовать.

Установка жестких и мягких ограничений памяти

Жесткий лимит памяти устанавливается флагом -m команды docker run или --memory. Он принимает такое значение, как 512m (для мегабайт) или 2g (для гигабайт):

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

Минимальные требования к памяти для контейнеров составляют 6 МБ. Попытка использовать значения --memory менее 6m вызовет ошибку.

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

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

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

Управление памятью подкачки

Контейнерам может быть выделена память подкачки для обеспечения интенсивного использования, не влияя на потребление физической памяти. Подкачка позволяет записывать содержимое памяти на диск после того, как доступная оперативная память будет исчерпана.

Флаг --memory-swap управляет объемом доступного пространства подкачки. Он работает только в сочетании с --memory. Когда вы устанавливаете для --memory и --memory-swap разные значения, значение подкачки управляет общим объемом памяти, доступной для контейнера, включая пространство подкачки. Значение --memory определяет часть объема физической памяти.

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

Этот контейнер имеет доступ к 762 МБ памяти, из которых 512 МБ приходится на физическую память. Остальные 250 МБ — это пространство подкачки, хранящееся на диске.

Установка --memory без --memory-swap дает контейнеру доступ к тому же объему пространства подкачки, что и физическая память:

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

Этот контейнер имеет в общей сложности 1024 МБ памяти, включая 512 МБ ОЗУ и 512 МБ подкачки.

Подкачку можно отключить для контейнера, установив для флага --memory-swap то же значение, что и для --memory. Поскольку --memory-swap устанавливает общий объем памяти, а --memory выделяет пропорцию физической памяти, вы указываете Docker, что 100% доступной памяти должно быть ОЗУ.

Во всех случаях своп работает только тогда, когда он включен на вашем хосте. Отчеты о свопе внутри контейнеров ненадежны и не должны использоваться. Такие команды, как free, выполняемые внутри контейнера, будут отображать общий объем пространства подкачки на вашем хосте Docker, а не доступный для контейнера подкачок.

Отключение процессов уничтожения из-за нехватки памяти

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

Включение необязательного флага --oom-kill-disable в команду docker run отключает это поведение. Вместо остановки процесса ядро просто заблокирует новые выделения памяти. Процесс будет зависать до тех пор, пока вы не уменьшите использование памяти, не отмените новые выделения памяти или не перезапустите контейнер вручную.

Этот флаг не следует использовать, если вы не реализовали механизмы для разрешения условий нехватки памяти самостоятельно. Обычно лучше позволить ядру убить процесс, вызывая перезапуск контейнера, который восстанавливает нормальное потребление памяти.

Краткое содержание

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

В этой статье вы узнали, как установить жесткие и мягкие ограничения памяти контейнера, чтобы уменьшить вероятность того, что вы столкнетесь с ситуацией нехватки памяти. Установка этих ограничений для всех ваших контейнеров уменьшит конкуренцию за ресурсы и поможет вам оставаться в пределах объема физической памяти вашего хоста. Вам следует рассмотреть возможность использования ограничений ЦП вместе с ограничениями памяти — это предотвратит негативное влияние отдельных контейнеров с высокой нагрузкой на ЦП на своих соседей.