Как ограничить ресурсы процессов в Linux с помощью cgroups и systemd
Control Groups (cgroups) — это механизм ядра Linux, который позволяет ограничивать, приоритизировать и отслеживать использование системных ресурсов процессами.
Основная идея проста: объединить один или несколько процессов в группу и задать для неё правила, например — не более 200 МБ памяти, 50% процессорного времени и ограничение скорости чтения с диска.
С помощью cgroups можно задать лимиты на:
- использование CPU;
- потребление оперативной памяти;
- количество ввода/вывода (I/O);
- сетевую активность.
Эта технология используется большинством контейнерных решений (например, Docker и Kubernetes), а также интегрирована в systemd, что делает её доступной для любого процесса без контейнеризации.
Как устроены cgroups
Система cgroups состоит из:
- контроллеров — модулей ядра, отвечающих за управление конкретным типом ресурса;
- иерархий — древовидных структур, где каждая группа может наследовать или переопределять лимиты;
- групп процессов (cgroup units) — наборов процессов, к которым применяются заданные ограничения.
| Контроллер | Назначение |
|---|---|
cpu | Ограничение процессорного времени |
memory | Лимиты по оперативной памяти |
io / blkio | Контроль дискового ввода/вывода |
pids | Количество процессов |
cpuset | Привязка процессов к конкретным CPU |
Процесс можно добавить в группу вручную или через systemd-юнит.
Пример использования cgroups напрямую
Создадим ограничение на использование памяти для группы процессов.
sudo mkdir /sys/fs/cgroup/mygroup
echo 100M | sudo tee /sys/fs/cgroup/mygroup/memory.max
echo $$ | sudo tee /sys/fs/cgroup/mygroup/cgroup.procsТеперь текущий процесс не сможет потреблять больше 100 МБ оперативной памяти.
Если лимит будет превышен — ядро завершит процесс с ошибкой Out of Memory (OOM).
Использование cgroups через systemd
Современные системы используют systemd как основной интерфейс для управления cgroups.
Каждый сервис, запущенный через systemd, автоматически получает собственную группу.
Посмотреть состояние можно командой:
systemctl status sshd.serviceЧтобы задать лимиты ресурсов, открой файл юнита (или создайте override):
sudo systemctl edit myapp.serviceДобавь секцию [Service] с нужными ограничениями:
[Service]
MemoryMax=256M
MemorySwapMax=0
CPUQuota=50%
IOReadBandwidthMax=/dev/sda 10M
IOWriteBandwidthMax=/dev/sda 5M
TasksMax=100
Что означают параметры:
MemoryMax=256M— ограничивает потребление оперативной памяти сервисом. Если процесс превысит лимит, ядро его завершит (OOM).MemorySwapMax=0— запрещает использование swap-файла, чтобы приложение не начало «тормозить» при нехватке RAM.CPUQuota=50%— выделяет сервису половину процессорного времени одного ядра. Например, на 4-ядерной машине это эквивалентно 2 ядрам.IOReadBandwidthMax=/dev/sda 10M— ограничивает скорость чтения с указанного устройства до 10 МБ/с.IOWriteBandwidthMax=/dev/sda 5M— ограничивает скорость записи до 5 МБ/с.TasksMax=100— задаёт максимум одновременно запущенных потоков и процессов для юнита. Полезно, чтобы runaway-приложения не создавали сотни потоков и не повесили систему.
Сохрани файл и перезапусти сервис:
sudo systemctl daemon-reload
sudo systemctl restart myapp.serviceПример с ограничением CPU по ядрам
Если нужно не процентное ограничение, а привязка к конкретным ядрам:
[Service]
CPUAffinity=0 1
Эта настройка заставит сервис работать только на ядрах 0 и 1.
Полезно, если нужно изолировать ресурсоёмкие задачи от других процессов.
Полезные параметры systemd для ограничения ресурсов
| Параметр | Что делает |
|---|---|
MemoryMax= | Максимальный объём оперативной памяти |
MemorySwapMax= | Лимит на swap |
CPUQuota= | Процент использования CPU (например, 50%) |
CPUWeight= | Приоритет CPU между сервисами |
IOReadBandwidthMax= / IOWriteBandwidthMax= | Лимит пропускной способности ввода/вывода |
TasksMax= | Максимум процессов/потоков для юнита |
Мониторинг и проверка лимитов
Чтобы убедиться, что лимиты применились:
systemd-cgls # показывает дерево cgroups
systemd-cgtop # отображает использование ресурсов в реальном времениДля конкретного юнита:
systemctl status myapp.serviceили подробнее через systemd-analyze:
systemd-analyze resource myapp.serviceИтого
- cgroups — базовый механизм ядра для контроля ресурсов.
- systemd — удобная надстройка, которая автоматически создает и управляет cgroups для сервисов.
- С их помощью можно:
- изолировать процессы;
- задавать лимиты CPU и памяти;
- защищать сервер от runaway-процессов.
Ограничение ресурсов через cgroups и systemd — это важная часть оптимизации и стабильности серверов Linux, особенно при запуске множества сервисов или контейнеров.
Настроить мониторинг за 30 секунд
Надежные оповещения о даунтаймах. Без ложных срабатываний