Установка cgroups в Unix/Linux

Установка cgroups в Unix/Linux

cgroups (англ. control group) — механизм ядра Linux, который ограничивает и изолирует вычислительные ресурсы (процессорные, сетевые, ресурсы памяти, ресурсы ввода-вывода) для групп процессов. Механизм позволяет образовывать иерархические группы процессов с заданными ресурсными свойствами и обеспечивает программное управление ими.

Вы можете использовать CGroups для ограничения количества ресурсов, которые может потреблять процесс или группа.

Архитектура cgroups

Механизм cgroups состоит из двух составных частей: ядра (cgroup core) и так называемых подсистем.

  • net_cls — помечает сетевые пакеты специальным тэгом, что позволяет идентифицировать пакеты, порождаемые определённой задачей в рамках контрольной группы;
  • devices — разрешает или блокирует доступ к устройствам;
  • blkio — устанавливает лимиты на чтение и запись с блочных устройств;
  • pids — используется для ограничения количества процессов в рамках контрольной группы.
  • cpu — обеспечивает доступ процессов в рамках контрольной группы к CPU;
  • hugetlb — активирует поддержку больших страниц памяти для контрольных групп;
  • cpuacct — генерирует отчёты об использовании ресурсов процессора;
  • freezer — приостанавливает и возобновляет выполнение задач в рамках контрольной группы
  • cpuset — распределяет задачи в рамках контрольной группы между процессорными ядрами;
  • memory — управляет выделением памяти для групп процессов;
  • netprio — используется для динамической установки приоритетов по трафику;

Установка cgroups в Unix/Linux

Данная тема охватит несколько ОС с наглядными примерами.

Установка cgroups в CentOS/RedHat

Данные управляющие группы и подсистемы ( к которым они относятся), могут управляться с помощью shell команд и утилит. Однако самый простой способ работы с такими группами — установить пакет libcgroup. Чтобы установить его, выполните следующую команду:

# yum install libcgroup -y

Служба cgconfig (конфигурация группы управления) используется для создания групп и управления подсистемами. Данный сервис может быть настроен для запуска во время загрузки и восстановления предустановленных групп, что делает их постоянными при перезагрузках. Чтобы запустить cgconfig  службы, выполните:

# service cgconfig start

Для проверки статуса, можно выполнить:

# service cgconfig status
Running

Чтобы добавить службу в автозагрузку ОС, выполните:

# chkconfig cgconfig on

Установка cgroups в Gentoo

Команда для установки:

$ su -c 'emerge libCGroup'

Установка cgroups в Fedora

Команда для установки:

$ su -c 'yum -y install libCGroup-tools'

Установка cgroups в Debian/Ubuntu

Не было необходимости еще!

Настройка cgroups в Unix/Linux

Документация ядра предоставляет общее описание с примерами. Но я в своей статье «Установка cgroups в Unix/Linux» опишу все возможные примеры максимально подробно.

Пакет cgroups-bin (который зависит от libcgroup1), уже предоставленный дистрибутивом. Настройка выполняется путем редактирования следующих двух файлов:

  • /etc/cgconfig.conf — В зависимости от содержимого файла конфигурации cgconfig может создавать иерархии, монтировать необходимые файловые системы, создавать группы и устанавливать параметры подсистемы (ограничения ресурсов) для каждой группы. Иерархия представляет собой набор групп, расположенных в дереве, так что каждая задача в системе находится в одной из групп в иерархии.
  • /etc/cgrules.conf — Служит для добавления ограничений для пользователей, групп, процессов.

Менеджер рабочей нагрузки (cgconfig) отвечает за распределение ресурсов.

Добавление нового процесса в менеджер можно следующим образом:

# cgexec [-g <controllers>:<path>] command [args]

Добавление уже запущенного процесса в менеджер:

# cgclassify [-g <controllers>:<path>] <pidlist>

Или, можно использовать автоматический режим при работе с файлом cgrules.conf и CGroup Rules Daemon (cgred), который заставляет каждый вновь созданный процесс использовать ограничение по группе (но об этом позже).

И так, начнем редактирование:

# vim /etc/cgconfig.conf

Вот пример моего:

group group1 {
        perm {
                task {
                        uid = captain;
                        gid = captain;
                }
                admin {
                        uid = root;
                        gid = root;
                }
        }

        cpu {
                cpu.shares = 500;
        }
}

group limitcpu{
        cpu {
                cpu.shares = 400;
        }
}

group limitmem{
        memory {
                memory.limit_in_bytes = 512m;
        }
}
group limitio{
        blkio {
                blkio.throttle.read_bps_device = "11:0 2097152";
        }
}
group browsers{
        cpu {
                cpu.shares = 200;
        }
        memory {
                memory.limit_in_bytes = 128m;
        }
}

Можно этот файл использовать а можно создать новый файл в /etc/cgconfig.d директории, например:

# vim /etc/cgconfig.d/test.conf

Пояснения:

  • В группе limitcpu ограничиваем общие ресурсы cpu доступными для процессов в этой группе до 400. cpu.shares указывает относительную долю времени процессора, доступного для задач в cgroup.
  • В группе limitmem ограничиваем доступную памяти cgroup процессам до 512 МБ.
  • В limitio группе ограничиваем пропускную способность диска до 2 Мбайт/с. Здесь ограничиваем чтение ввода-вывода на основной диск, /dev/vda, с основным: младший номер 11:0 и 2MiB/s преобразуется в байты в секунду (2x1024x1024 = 2097152).
  • В browsers группе ограничиваем общие ресурсы процессора до 200 и доступную память до 128 МБ.

Затем убедитесь, что настроенные группы отображаются правильно:

# lscgroup
cpuset:/
cpu:/
cpu:/browsers
cpu:/limitcpu
cpu:/group1
cpuacct:/
memory:/
memory:/browsers
memory:/limitmem
devices:/
freezer:/
net_cls:/
blkio:/
blkio:/limitio

Наша следующая цель — добавить процессы (задачи), для которых мы хотим ограничить ресурсы для ранее созданных групп. Cgred (механизм управления группами) — это служба, которая перемещает задачи в группы в соответствии с параметрами, заданными в файле /etc/cgrules.conf. Записи в файле /etc/cgrules.conf могут принимать одну из двух форм:

user subsystems control_group

ИЛИ:

user:command subsystems control_group

user ссылается на имя пользователя или имя группы с префиксом «@». Подсистемы (subsystems) относятся к списку подсистем, которые разделенному запятыми. control_group представляет собой путь к cgroup, а команда обозначает имя процесса или полный путь к процессу процесса. Записи в файле /etc/cgrules.conf могут содержать следующие дополнительные обозначения:

  • @ — Указывает группу вместо отдельного пользователя. Например, @admin указывает всех пользователей в admin группе.
  • * — Использовать «все\всех». Например, если установить * в user поле, то это будет говорить, что будут использоватся все пользователи в ОС.
  • % — Представляет элемент тот же, что и элемент в строке выше.

Теперь добавим ограничение к программам/процессам, которые хотим ограничить, открываем:

# vim /etc/cgrules.conf

И прописываем:

captain cpu group1/
*:firefox cpu,memory browsers/
*:hdparm blkio limitio/
sammy blkio limitio/
@admin:memhog memory limitmem/
*:cpuhog cpu limitcpu/

В приведенных выше строках устанавливаем следующие правила:

  • Для пользователя (captain) ограничиваем CPU.  Для этого, ему назначаем group1 группу.
  • Процессы firefox запускаемые от любого пользователя, будут автоматически добавлены в browsers группу и ограничеваем в подсистеме CPU и RAM.
  • Процессы hdparm запускаемые от любого пользователя, будут добавленs в blkio группу с ограничением подсистемы blkio в соответствии с значениями параметров, указанными в этой группе.
  • Все процессы, выполняемые пользователем sammy, будут добавлены в лимитированную группу и ограничены в подсистеме blkio.
  • Процессы memhog, запускаемые кем-либо из группы admin, будут добавлены в limitmem cgroup и ограничены по памяти.
  • Процессы cpuhog, выполняемые от любого пользователя, будут добавлены в limitcpu группу и ограничены по CPU.

Нам нужно запустить/перезапустить cgred-службу, чтобы изменения конфигурации cgrules вступили в силу, сделайте это, используя команду:

# service cgred restart

Нам также необходимо убедиться, что служба cgred включена для запуска при атозагрузке системы, чтобы наши правила сохранялись при перезагрузке:

# chkconfig cgred on

ЗАМЕЧАНИЕ: Для служб, которые поддерживают sysconfig, вы можете добавить CGROUP_DAEMON=»subsystem:control_group» переменную  в /etc/sysconfig/servicename вместо редактирования файла cgrules.conf. Например, для httpd службы, вы можете добавить CGROUP_DAEMON=»blkio:/limitio» в файл /etc/sysconfig/httpd.conf, чтобы добавить httpd-процессы в группу limitio.

Затем перезапустите:

# service cgconfig restart

Настройка завершена.

Использование, тестирование cgroups в Unix/Linux

Запуск службы cgconfig создает виртуальную файловую систему, установленную в /cgroup со всеми подсистемами. Проверим это:

# ls /cgroup

Получаем следующие подсистемы:

blkio cpu cpuacct cpuset devices freezer memory net_cls

Можно запустить команду `lscgroup ‘для проверки:

$ sudo lscgroup

Вы увидите подсистемы в несколько иной компоновке:

cpuset:/
cpu:/
cpuacct:/
memory:/
devices:/
freezer:/
net_cls:/
blkio:/

Протестируем ограничение на диск, для этого — нужно установить утилиту hdparm. Например, для rpm’s ОС, выполните:

# yum install hdparm

Теперь давайте запустим команду для измерения скорости чтения вашего жесткого диска, например:

# hdparm --direct -t /dev/vda

Вывод будет такой:

/dev/vda:
Timing O_DIRECT disk reads: 6 MB in 3.00 seconds = 2.00 MB/sec

На выходе показана пропускная способность диска 2 МБ/с. Если вы остановите службы cgconfig и cgred и снова запустите команду hdparm, вы можете увидеть исходную/стандартную скорость чтения с того момента, когда правила группы не были реализованы.

Создание cgroups в Unix/Linux

Чтобы создать CGroup c ограничением по CPU/RAM, выполним:

# cgcreate -g cpu,memory:your_cgroup_name

Где:

  • cpu,memory — Какие ресурсы будут ограничены. Можно еще ограничить — cpuset,cpuacct.
  • your_cgroup_name — Название вашей cgroup группы.

Можно установить ограничение прям в консоле, например, — установим ограничение по использованию RAM:

# cgset -r memory.limit_in_bytes=1G your_cgroup_name

Можно установить ограничение прям в консоле, например, — установим ограничение по использованию CPU приоритет до ~10% (1024 — это 100% приоритет):

# cgset -r cpu.shares=102 your_cgroup_name

Если используете systemD, то можно использовать SystemD Slices, нпример:

# systemctl set-property user.slice MemoryLimit=512M
# systemctl set-property system.slice MemoryLimit=1024M

Или, можно закинуть в fstab:

# cat /etc/fstab | grep -E "cgroup"

cgroup /sys/fs/cgroup cgroup defaults 0 0

Мне этого хватило что-бы пофиксить кое-что связанное с докером. Если появятся мысли что дополнить — обязательно дополню. Вот и все, статья «Установка cgroups в Unix/Linux» завершена.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *