<div><img src="https://top-fwz1.mail.ru/counter?id=3548135;js=na" style="position:absolute;left:-9999px;" alt="Top.Mail.Ru" /></div>
Managed Kubernetes — разверните готовый кластер за 5 минут →
Вход / Регистрация

Механизмы контейнеризации: cgroups

3280
8 минут чтения
Средний рейтинг статьи: 5

Статья обновлена 28 октября 2025 г.

Контейнеризация — это технология упаковки кода и его зависимостей (библиотек, артефактов и т. д.), которая позволяет запускать приложения в изолированной среде на любой операционной системе. Контейнеризация использует ядро хостовой операционной системы, при этом изоляция осуществляется средствами ОС, а не аппаратными ресурсами, как в случае с виртуальными машинами. Для запуска контейнера операционная система выделяет ресурсы: память, процессорное время, дисковое и сетевое пространство. 

В Linux для изоляции и управления ресурсами используются два ключевых механизма: namespaces и cgroups. Namespaces группируют и изолируют процессы, а cgroups (control groups) позволяют задавать ограничения на использование ресурсов. Сегодня мы более подробно поговорим о механизме cgroups.

Что такое cgroups?

Control Groups (cgroups) — это механизм ядра Linux, предназначенный для группировки процессов и управления их доступом к системным ресурсам, таким как процессор (CPU), оперативная память, дисковый ввод-вывод и сеть. Впервые cgroups были интегрированы в ядро Linux в 2007 году (версия 2.6.24) и с тех пор стали фундаментальной основой для технологий контейнеризации, таких как Docker, Kubernetes и LXC.

Основная идея cgroups заключается в объединении процессов в группы, которые наследуют общие ограничения на использование ресурсов. Это позволяет эффективно распределять ресурсы в многопользовательских или многоконтейнерных средах, предотвращая проблему «шумного соседа» — ситуацию, когда один процесс чрезмерно потребляет ресурсы, ухудшая производительность других.

Проще говоря, представьте, что ваш компьютер — это общий пирог, а программы или пользователи — гости за столом. Cgroups выступает в роли «контроллера», который распределяет куски пирога так, чтобы каждый получил свою долю, не позволяя одному гостю забрать всё. Например, вы можете настроить cgroups, чтобы ограничить использование CPU для определенной группы процессов до 20% или задать максимальный объем памяти, доступный для контейнера.

Структура cgroups

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

Основные группы:

  • cpu: ограничивает использование процессорного времени и задает приоритеты для процессов.

  • memory: контролирует использование оперативной памяти и пространства файла подкачки (swap).

  • blkio: регулирует операции ввода-вывода для блочных устройств.

  • devices: управляет доступом процессов к устройствам.

  • cpuset: привязывает процессы к определенным ядрам процессора.

  • net_cls и net_prio: обеспечивают маркировку сетевых пакетов и управление их приоритетами.

  • freezer: позволяет приостанавливать («замораживать») и возобновлять («размораживать») процессы.

  • pids: ограничивает максимальное количество процессов или потоков в группе.

Более подробно с описанием каждой группы можно ознакомиться по ссылке.

В версии cgroups v1 каждая подсистема монтировалась и настраивалась отдельно, что создавало сложности при управлении и координации ресурсов. Эти проблемы были устранены в cgroups v2, которая была интегрирована в ядро Linux 4.5 (2016 год). Новая версия использует единую иерархию, где все контроллеры применяются ко всем группам одновременно. Это упрощает конфигурацию, повышает согласованность и облегчает делегирование прав управления.

Как работают cgroups?

Создание и управление группами

Cgroups доступны через виртуальную файловую систему, обычно монтируемую в /sys/fs/cgroup. Для создания новой группы достаточно создать директорию:

mkdir /sys/fs/cgroup/mygroup

Внутри созданной директории появляются файлы и поддиректории, связанные с доступными контроллерами (memory, cpu, blkio и т.д.). Эти файлы позволяют настраивать параметры ограничений. Например, чтобы ограничить объем памяти для группы необходимо выполнить команду:

echo "100M" > /sys/fs/cgroup/mygroup/memory.max

Чтобы добавить процессу в группу, необходимо записать его идентификатор (PID) в файл cgroup.procs, где <PID> — это номер процесса:

echo <PID> > /sys/fs/cgroup/mygroup/cgroup.procs

После этого процесс с указанным PID будет подчиняться ограничениям, заданным для группы. Например, если установлен лимит памяти в 100 МБ, процесс не сможет использовать больше этого объема.

Уведомления и события

Cgroups поддерживают мониторинг событий, что позволяет отслеживать состояние ресурсов. Например, можно настроить уведомления о превышении лимита памяти или активации механизма OOM-killer, который завершает процессы при нехватке памяти. Для включения OOM-killer и настройки уведомлений используется файл memory.oom_control:

echo "1" > /sys/fs/cgroup/mygroup/memory.oom_control

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

Использование Cgroups в контейнеризации

LXC

Cgroups является фундаментальной основой для технологии контейнеризации LXC (Linux Containers). LXC, как одна из первых и нативных технологий контейнеризации для ядра Linux, глубоко интегрирована с механизмами cgroups, которая обеспечивает изоляцию и управление ресурсами. LXC предоставляет администратору прямой контроль над конфигурацией cgroups. Все параметры управления ресурсами задаются в файле конфигурации контейнера.

Основные параметры для управления ресурсами в LXC:

  • lxc.cgroup.memory.max — ограничивает максимальный объем оперативной памяти, которую может использовать контейнер.

  • lxc.cgroup.cpu.weight — задает приоритет контейнеру при распределении процессорного времени. Принимает значения от 1 до 10000.

  • lxc.cgroup.blkio.weight — задает приоритет для операций ввода/вывода. Принимает значения от 10 до 1000.

Docker

Популярный инструмент контейнеризации Docker использует механизм cgroups для эффективного управления ресурсами контейнеров. Cgroups позволяют изолировать и ограничивать использование ресурсов, таких как процессор, оперативная память и дисковый ввод/вывод. При запуске контейнера Docker автоматически создает отдельную группу cgroups для процесса и настраивает соответствующие контроллеры. Это обеспечивает изоляцию ресурсов и предотвращает их чрезмерное использование одним контейнером.

Основные параметры управления ресурсами в Docker:

  • --memory=512m: Устанавливает лимит оперативной памяти. Контейнер не сможет использовать больше ОЗУ чем задано в данном параметре. Значения можно задавать в байтах, килобайтах, мегабайтах и гигабайтах.

  • --cpus=1.5: Ограничивает использование ядер и мощности процессора. Ограничения можно задавать для количества ядер процессора (параметр cpus), длины цикла (параметр --cpu-period, задается в микросекундах) и количества доступных циклов за период (параметр --cpu-quota).

  • --blkio-weight: Управляет приоритетами операций ввода-вывода для дисков.

Пример команды для запуска контейнера с ограничениями ресурсов:

docker run --memory=256m --cpus=0.5 --blkio-weight=100 nginx

Docker интегрируется с runc (инструмент для запуска контейнеров в Linux), который напрямую взаимодействует с cgroups.

Kubernetes

Kubernetes также активно использует cgroups для управления ресурсами контейнеров. Ресурсы задаются в спецификациях подов через параметры requests и limits в YAML-манифестах. Параметр requests определяет минимально необходимые ресурсы для работы контейнера, а limits — максимальные ресурсы, которые может использовать контейнер. Это позволяет Kubernetes эффективно распределять ресурсы. Пример использования limits и requests в Kubernetes:

resources:
 limits:
   memory: "128Mi"
   cpu: "500m"

 requests:
   memory: "64Mi"
   cpu: "250m"

Сравнение с другими механизмами

Cgroups работают в связке с другими механизмами изоляции:

  • Namespaces: Изолируют PID (уникальный идентификатор процесса), сеть, файловую систему, но не ресурсы.

  • Seccomp/AppArmor/SELinux: Ограничивают системные вызовы и доступ.

  • Capabilities: Контролируют привилегии процессов.

Без использования cgroups контейнеры могли бы бесконтрольно потреблять ресурсы хостовой системы.

Отличие Cgroups версий v1 vs v2

Характеристика

Cgroups v1

Cgroups v2

Документация

Cgroups v1

Cgroups v2

Иерархия

Раздельные подсистемы

Единая иерархия

Делегирование

Сложное, требует прав root-пользователя

Упрощенное через namespaces

Мониторинг

Ограниченный

Улучшенный. Включает в себя события и индикатор pressure stall)

Поддержка в контейнеризации

Docker до версии 19.03

Docker версии 20.10 и выше, Kubernetes версии 1.25 и выше

Проблемы и ограничения

  • OOM-killer: При исчерпании памяти ядро может убить процессы вне контейнера, если лимиты настроены неправильно.

  • Производительность: Частые проверки cgroups добавляют дополнительной нагрузки на оборудование.

  • Совместимость: Не все дистрибутивы ядра поддерживают v2 по умолчанию.

  • Сложность отладки: Мониторинг вложенных cgroups требует инструментов вроде systemd-cgtop.

Заключение

Cgroups — это мощный и гибкий механизм, который лежит в основе современной контейнеризации. Он обеспечивает детализированный контроль над ресурсами, позволяя запускать тысячи контейнеров на одном хосте без риска перегрузки системы. Понимание cgroups критически важно для системных администраторов и разработчиков, работающих с Docker, Kubernetes или другими оркестраторами контейнеров.

С развитием облачных технологий и edge-вычислений cgroups становятся еще более актуальными. Например, в IoT-системах cgroups помогают эффективно распределять ограниченные ресурсы на устройствах с малой вычислительной мощностью. Кроме того, интеграция cgroups v2 с технологией BPF открывает новые возможности для динамического управления ресурсами и трассировки производительности.

3280
8 минут чтения
Средний рейтинг статьи: 5
Пока нет комментариев