- cgroups
- Contents
- Installing
- With systemd
- Hierarchy
- Find cgroup of a process
- cgroup resource usage
- Custom cgroups
- As service
- Service unit file
- Grouping unit under a slice
- As root
- As unprivileged user
- Controller types
- User delegation
- User-defined slices
- Run-time adjustment
- With libcgroup
- Ad-hoc groups
- Persistent group configuration
- With the cgroup virtual filesystem
- Examples
- Matlab
- With systemd
- With libcgroup
- Documentation
- Tips and tricks
- Enable cgroup v1
- Борьба за ресурсы, часть 1: Основы Cgroups
- Контроль на уровне ядра
- Свой кусок пирога
- Выкручиваем на полную!
cgroups
Control groups (or cgroups as they are commonly known) are a feature provided by the Linux kernel to manage, restrict, and audit groups of processes. Compared to other approaches like the nice(1) command or /etc/security/limits.conf , cgroups are more flexible as they can operate on (sub)sets of processes (possibly with different system users).
Control groups can be accessed with various tools:
- using directives in systemd unit files to specify limits for services and slices;
- by accessing the cgroup filesystem directly;
- via tools like cgcreate , cgexec and cgclassify (part of the libcgroupAUR and libcgroup-gitAUR packages);
- using the «rules engine daemon» to automatically move certain users/groups/commands to groups ( /etc/cgrules.conf and /usr/lib/systemd/system/cgconfig.service ) (part of the libcgroupAUR and libcgroup-gitAUR packages); and
- through other software such as Linux Containers (LXC) virtualization.
cgmanager is deprecated and unsupported as it does not work with systemd versions 232 and above.
For Arch Linux, systemd is the preferred and easiest method of invoking and configuring cgroups as it is a part of the default installation.
Contents
Installing
Make sure you have one of these packages installed for automated cgroup handling:
- systemd — for controlling resources of a systemd service.
- libcgroupAUR , libcgroup-gitAUR — set of standalone tools ( cgcreate , cgclassify , persistence via cgconfig.conf ).
With systemd
Hierarchy
Current cgroup hierarchy can be seen with systemctl status or systemd-cgls command.
Find cgroup of a process
The cgroup name of a process can be found in /proc/PID/cgroup .
For example, the cgroup of the shell:
cgroup resource usage
The systemd-cgtop command can be used to see the resource usage:
Custom cgroups
systemd.slice(5) systemd unit files can be used to define a custom cgroup configuration. They must be placed in a systemd directory, such as /etc/systemd/system/ . The resource control options that can be assigned are documented in systemd.resource-control(5) .
This is an example slice unit that only allows 30% of one CPU to be used:
Remember to run systemctl daemon-reload to pick up any new or changed .slice files.
As service
Service unit file
Resources can be directly specified in service definition or as a Systemd#Drop-in files
Grouping unit under a slice
Service can be specified what slice to run in:
As root
systemd-run can be used to run a command in a specific slice.
—uid=username option can be used to spawn the command as specific user.
The —shell option can be used to spawn a command shell inside the slice.
As unprivileged user
Unprivileged users can divide the resources provided to them into new cgroups, if some conditions are met.
Cgroups v2 must be utilized for a non-root user to be allowed managing cgroup resources.
Controller types
Not all resources can be controlled by user.
Controller | Can be controlled by user | Options |
---|---|---|
cpu | Requires delegation | CPUAccounting, CPUWeight, CPUQuota, AllowedCPUs, AllowedMemoryNodes |
io | Requires delegation | IOWeight, IOReadBandwidthMax, IOWriteBandwidthMax, IODeviceLatencyTargetSec |
memory | Yes | MemoryLow, MemoryHigh, MemoryMax, MemorySwapMax |
pids | Yes | TasksMax |
rdma | No | ? |
eBPF | No | IPAddressDeny, DeviceAllow, DevicePolicy |
User delegation
For user to control cpu and io resources, the resources need to be delegated. This can be done by creating a unit overload.
For example if your user id is 1000:
Reboot and verify that the slice your user session is under has cpu and io controller:
User-defined slices
The user slice files can be placed in
To run the command under certain slice:
You can also run your login shell inside the slice:
Run-time adjustment
cgroups resources can be adjusted at run-time using systemctl set-property command. Option syntax is the same as in systemd.resource-control(5) .
For example, cutting off internet access for all user sessions:
With libcgroup
You can enable the cgconfig service with systemd. This allows you to track any errors in cgconfig.conf more easily.
Ad-hoc groups
One of the powers of cgroups is that you can create «ad-hoc» groups on the fly. You can even grant the privileges to create custom groups to regular users. groupname is the cgroup name:
Now all the tunables in the group groupname are writable by your user:
Cgroups are hierarchical, so you can create as many subgroups as you like. If a normal user wants to run a bash shell under a new subgroup called foo :
To make sure (only meaningful for legacy (v1) cgroups):
A new subdirectory was created for this group. To limit the memory usage of all processes in this group to 10 MB, run the following:
Note that the memory limit applies to RAM use only — once tasks hit this limit, they will begin to swap. But it won’t affect the performance of other processes significantly.
Similarly you can change the CPU priority («shares») of this group. By default all groups have 1024 shares. A group with 100 shares will get a
10% portion of the CPU time:
You can find more tunables or statistics by listing the cgroup directory.
You can also change the cgroup of already running processes. To move all ‘bash’ commands to this group:
Persistent group configuration
If you want your cgroups to be created at boot, you can define them in /etc/cgconfig.conf instead. For example, the «groupname» has a permission for $USER and users of group $GROUP to manage limits and add tasks. A subgroup «groupname/foo» group definitions would look like this:
This is equivalent to these shell commands:
With the cgroup virtual filesystem
This article or section needs expansion.
Starting with systemd 232, the cgm method described in the next section, this section will instead describe a manual method to limit memory usage.
Create a new cgroup named groupname:
Example: set the maximum memory limit to 100MB:
Move a process to the cgroup (note: only one PID can be written at a time, repeat this for each process that must be moved):
Examples
Matlab
Doing large calculations in MATLAB can crash your system, because Matlab does not have any protection against taking all your machine’s memory or CPU. The following examples show a cgroup that constrains Matlab to first 6 CPU cores and 5 GB of memory.
With systemd
Launch Matlab like this (be sure to use the right path):
With libcgroup
Change username to the user Matlab is run as.
You can also restrict the CPU share with the cpu constraint.
Launch Matlab like this (be sure to use the right path):
Documentation
- For information on controllers and what certain switches and tunables mean, refer to kernel’s documentation v1 or v2 (or install linux-docs and see /usr/src/linux/Documentation/cgroup )
- A detailed and complete Resource Management Guide can be found in the fedora project documentation.
For commands and configuration files, see relevant man pages, e.g. man cgcreate or man cgrules.conf
Tips and tricks
Enable cgroup v1
Cgroup v2 is now enabled by default. If you want to switch to cgroup v1 instead, you need to set the following kernel parameter:
Источник
Борьба за ресурсы, часть 1: Основы Cgroups
Компьютеры – это «железо». И сегодня мы вернулись в исходную точку, в том смысле, что сейчас редко найдешь физический хост, на котором выполняется одна единственная задача. Даже если на сервере крутится только одно приложение, оно, скорее всего, состоит из нескольких процессов, контейнеров или даже виртуальных машин (ВМ), и все они работают на одном сервере. Red Hat Enterprise Linux 7 неплохо справляется с распределением системных ресурсов в таких ситуациях, но по умолчанию ведет себя как добрая бабушка, угощающая внуков домашним пирогом и приговаривающая: «Всем поровну, всем поровну».
В теории принцип «всем поровну», конечно, прекрасен, но на практике некоторые процессы, контейнеры или ВМ оказываются важнее других, и, следовательно, должны получать больше.
В Linux уже давно есть средства управления использованием ресурсов (nice, ulimit и прочее), однако с появлением Red Hat Enterprise Linux 7 и systemd у нас наконец-то появился мощный набор таких инструментов, встроенный в саму ОС. Дело в том, что ключевой компонент systemd – это уже готовый, настроенный набор cgroups, который в полной мере задействуется на уровне ОС.
Хорошо, а что это вообще за cgroups, и причем здесь управление ресурсами или производительностью?
Контроль на уровне ядра
Начиная с вышедшей в январе 2008 года версии 2.6.24, в ядре Linux появилось то, что изначально было придумано и создано в Google под именем «process containers», а в Linux стало называться «control groups», сокращенно cgroups. Вкратце, cgroups – это механизм ядра, позволяющий ограничивать использование, вести учет и изолировать потребление системных ресурсов (ЦП, память, дисковый ввод/вывод, сеть и т. п.) на уровне коллекций процессов. Cgroups также могут замораживать процессы для проверки и перезапуска. Контроллеры cgroups впервые появились в 6-й версии Red Hat Enterprise Linux, но там их надо было настраивать вручную. А вот с приходом Red Hat Enterprise Linux 7 и systemd преднастроенный набор cgroups идет уже в комплекте с ОС.
Все это работает на уровне ядра ОС и поэтому гарантирует строгий контроль над каждым процессом. Так что теперь какому-нибудь зловреду крайне сложно нагрузить систему так, чтобы она перестала реагировать и зависла. Хотя, конечно, багованный код с прямым доступом к «железу» (например, драйверы), все еще на такое способен. При этом, Red Hat Enterprise Linux 7 предоставляет интерфейс для взаимодействия с cgroups, и вся работа с ними в основном ведется через команду systemd.
Свой кусок пирога
На диаграмме ниже, напоминающей нарезанный пирог, представлены три cgroups, которые по умолчанию есть на сервере Red Hat Enterprise Linux 7 – System, User и Machine. Каждая из этих групп называется «слайс» (slice – сектор). Как видно на рисунке, каждый слайс может иметь дочерние секторы-слайсы. И, как и в случае с тортом, в сумме все слайсы дают 100% соответствующего ресурса.
Теперь рассмотрим несколько концепций cgroups на примере процессорных ресурсов.
На рисунке выше видно, что процессорное время поровну делится между тремя слайсами верхнего уровня (System, User и Machine). Но так происходит только под нагрузкой. Если же какой-то процесс из слайса User попросит 100% процессорных ресурсов, и никому больше эти ресурсы в данный момент не нужны, то он получит все 100% процессорного времени.
Каждый из трех слайсов верхнего уровня предназначен для своего типа рабочих нагрузок, которым нарезаются дочерние сектора в рамках родительского слайса:
- System – демоны и сервисы.
- User – пользовательские сеансы. Каждый пользователь получает свой дочерний слайс, причем все сеансы с одинаковым UID «живут» в одном и том же слайсе, чтобы особо ушлые умники не могли получить ресурсов больше положенного.
- Machine – виртуальные машины, типа KVM-гостей.
Кроме того, для управления использованием ресурсов применяется концепция так называемых «шар» (share – доля). Шара – это относительный числовой параметр; его значение имеет смысл только в сравнении со значениями других шар, входящих в ту же cgroup. По умолчанию все слайсы имеют шару, равную 1024. В слайсе System на рисунке выше для httpd, sshd, crond и gdm заданы CPU-шары, равные 1024. Значения шар для слайсов System, User и Machine тоже равны 1024. Немного запутанно? На самом деле это можно представить в виде дерева:
- System — 1024
- httpd — 1024
- sshd — 1024
- crond — 1024
- gdm — 1024
- User — 1024
- bash (mrichter) — 1024
- bash (dorf) — 1024
- Machine — 1024
- testvm — 1024
В этом списке у нас есть несколько запущенных демонов, пара пользователей и одна виртуальная машина. Теперь представим, что все они одновременно запрашивают всё процессорное время, какое только можно получить.
- Слайс System получает 33,333% процессорного времени и поровну делит его между четырьмя демонами, что дает каждому из них по 8,25% ресурсов ЦП.
- Слайс User получает 33,333% процессорного времени и делит его между двумя пользователями, каждый из которых имеет по 16,5% ресурсов ЦП. Если пользователь mrichter выйдет из системы или остановит все свои запущенные процессы, то пользователю dorf станет доступно 33% ресурсов ЦП.
- Слайс Machine получает 33,333% процессорного времени. Если выключить ВМ или перевести ее в холостой режим, то слайсы System и User будут получать примерно по 50 % ресурсов ЦП, которые затем поделятся между их дочерними слайсами.
Кроме того, для любого демона, пользователя или виртуальной машины можно вводить не только относительные, но и абсолютные ограничения на потребление процессорного времени, причем не только одного, но и нескольких процессоров. Например, у слайса пользователя mrichter есть свойство CPUQuota. Если выставить его на 20 %, то mrichter ни при каких обстоятельствах не получит больше 20 % ресурсов одного ЦП. На многоядерных серверах CPUQuota может быть больше 100 %, чтобы слайс мог пользоваться ресурсами более чем одного процессора. Например, при CPUQuota = 200 % слайс может полностью задействовать два процессорных ядра. При этом важно понимать, что CPUQuota не резервирует, иначе говоря, не гарантирует заданный процент процессорного времени при любой загруженности системы – это лишь максимум, который может быть выделен слайсу с учетом всех прочих слайсов и настроек.
Выкручиваем на полную!
Как можно поменять настройки слайсов?
Для этого у каждого слайса есть настраиваемые свойства. И поскольку это Linux, мы можем вручную прописывать настройки в файлах конфигураций или же задавать из командной строки.
Во втором случае используется команда systemctl set-property. Вот что будет на экране, если набрать эту команду, добавить в конце имя слайса (в нашем случае User) и затем нажать клавишу Tab для отображения опций:
Не все свойства на этом скриншоте являются настройками cgroup. Нас в основном интересуют те, что начинаются на Block, CPU и Memory.
Если вы предпочитаете не командную строку, а config-файлы (например, для автоматизированного развертывания на нескольких хостах), то тогда придется заняться файлами в папке /etc/systemd/system. Эти файлы автоматически создаются при установке свойств с помощью команды systemctl, но их также можно создавать в текстовом редакторе, штамповать через Puppet или даже генерировать скриптами на лету.
Итак, с базовыми понятиями cgroups все должно быть ясно. В следующий раз пройдем по некоторым сценариям и посмотрим, как изменения тех или иных свойств влияют на производительность.
А буквально завтра приглашаем всех на Red Hat Forum Russia 2018 – будет возможность задать вопросы напрямую инженерам Red Hat.
Другие посты по cgroups из нашей серии «Борьба за ресурсы» доступны по ссылкам:
Источник