Docker Error: cgroups: cannot set memory limit: invalid argument
Подсистема контрольных групп ядра Linux (cgroups v1 vs v2)
Ошибка OCI runtime create failed: container_linux.go: cannot set memory limit: invalid argument или memory.memsw.limit_in_bytes must be greater than or equal to memory.limit_in_bytes генерируется рантаймом runc при попытке применить лимиты оперативной памяти и swap-пространства. Причиной является несовместимость версий cgroups, попытка задать лимит памяти без предварительно включенного учета swap в ядре (swapaccount=0), либо логическая ошибка конфигурации, когда лимит --memory-swap меньше основного лимита --memory.
Бизнес-риски:
Неконтролируемое потребление RAM контейнерами (OOM), зависание всего хоста из-за исчерпания ресурсов, невозможность изолировать шумных соседей (Noisy Neighbors).
Таблица параметров cgroups для управления памятью
| Параметр CLI | Файл cgroups v1 | Файл cgroups v2 | Назначение |
|---|---|---|---|
-m / --memory | memory.limit_in_bytes | memory.max | Жесткий лимит физической оперативной памяти контейнера. |
--memory-swap | memory.memsw.limit_in_bytes | memory.swap.max | Суммарный лимит памяти и swap (v1) или чистый swap (v2). |
--memory-reservation | memory.soft_limit_in_bytes | memory.low / memory.high | Мягкий лимит памяти при дефиците ресурсов на ноде. |
Пошаговая настройка подсистемы cgroups в ядре Linux
Сценарий 1: Включение учета памяти и swap в параметрах загрузчика GRUB
В дистрибутивах Debian/Ubuntu учет swap по умолчанию может быть отключен в ядре:
# Редактирование параметров загрузчика /etc/default/grub
# Добавьте параметры в строку GRUB_CMDLINE_LINUX:
GRUB_CMDLINE_LINUX='cgroup_enable=memory swapaccount=1'
# Обновление конфигурации GRUB и перезагрузка сервера:
update-grub
reboot
# Проверка статуса после перезагрузки:
docker info | grep -i cgroupСценарий 2: Корректное указание соотношения Memory и Swap
В cgroups v1 значение --memory-swap обязано быть БОЛЬШЕ или РАВНО значению --memory:
# ПРАВИЛЬНО: суммарная память 2G (1G RAM + 1G Swap):
docker run -d -m 1g --memory-swap 2g myimage
# Полное отключение использования Swap для контейнера:
docker run -d -m 1g --memory-swap 1g myimageСценарий 3: Проверка и переключение на Unified Cgroups v2
Убедитесь, какая версия cgroups активна в вашей операционной системе:
# Проверка версии cgroups
stat -fc %T /sys/fs/cgroup/
# Результат 'cgroup2fs' = v2, 'tmpfs' = v1
# Для переключения на cgroups v2 добавьте в /etc/default/grub:
# systemd.unified_cgroup_hierarchy=1Типовые ошибки администраторов
- Попытка выставить memory limit меньше 6MB: Ядро Linux требует минимальный порог памяти (обычно 6MB) для инициализации базовых структур процесса.
- Использование cgroups v1 синтаксиса в новых оркестраторах: Настройка устаревших параметров memsw на ядрах Linux 6.x с чистым cgroups v2 вызывает падение инициализации runc.
ITSTM настроит строгие профили cgroups v2, лимиты CPU/RAM/IOPS и предотвратит деградацию инфраструктуры.
Частые вопросы (FAQ)
Почему при docker info появляется 'WARNING: No memory limit support'?
В ядре операционной системы не активирован модуль cgroup memory. Добавьте 'cgroup_enable=memory swapaccount=1' в параметры GRUB.
Что происходит с контейнером при превышении лимита memory.max?
Ядро Linux активирует OOM Killer, который мгновенно завершает процесс PID 1 внутри контейнера сигналом SIGKILL (Exit Code 137).
Как задать лимит памяти в docker-compose.yml?
В блоке deploy.resources.limits: services -> app -> deploy -> resources -> limits -> memory: 1024M.
В чем главное преимущество cgroups v2 для Docker?
Cgroups v2 обеспечивает единую иерархию ресурсов, точный учет потребления буферизованного I/O и корректное распределение swap-памяти.