DevOps в серии буткемпов K8s

Примечание: полная ментальная карта DevOps в K8s доступна по адресу: «DevOps в ментальной карте K8s»

Linux Cgroups — один из основных принципов реализации технологии контейнеров. Это помогает контролировать и изолировать использование ресурсов различными группами процессов, а также обеспечивает лучший контроль и управление системными ресурсами.

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

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

Что такое групповые группы Linux

Linux Cgroups (группы управления) — это функция ядра Linux, которая позволяет управлять и ограничивать количество системных ресурсов, таких как процессорное время, память и пропускная способность ввода-вывода, которые может использовать процесс или группа процессов.

Например, вы можете использовать Cgroups, чтобы убедиться, что определенный процесс или группа процессов не потребляют слишком много ресурсов ЦП или памяти, или чтобы ограничить объем дисковых операций ввода-вывода, выполняемых процессом.

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

Например, ниже приведен пример использования Cgroups для ограничения использования памяти:

  • Создайте новую Cgroup:
$ mkdir /sys/fs/cgroup/memory/test_cgroup
  • Установить лимит памяти:
$ sh -c "echo 200M > /sys/fs/cgroup/memory/test_cgroup/memory.limit_in_bytes"
$ cat /sys/fs/cgroup/memory/test_cgroup/memory.limit_in_bytes
20971520
  • Добавьте процесс в test_cgroup:
$ echo $PID > /sys/fs/cgroup/memory/test_group/tasks

В приведенном выше примере мы смонтировали файловую систему cgroup, создали новую cgroup с именем «test_cgroup», установили ограничение памяти на 200 МБ и переместили процесс с PID $PID в cgroup. Теперь процесс и все его дочерние процессы будут ограничены использованием только 200 МБ памяти. Если процесс попытается использовать более 200 МБ, он будет остановлен ядром Linux.

Основные понятия Cgroup Linux

Иерархия

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

Контроллеры

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

Задания

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

Ограничения ресурсов

Ограничения ресурсов определяют количество ресурсов, которые может использовать контрольная группа. Например, ограничение памяти указывает максимальный объем памяти, который может использовать контрольная группа, а ограничение ЦП указывает максимальное количество процессорного времени, которое может потреблять контрольная группа.

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

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

Файловая система

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

Подсистемы Cgroup Linux

CGroups Поддерживаемые подсистемы включают следующие категории, которые определяют подсистему для каждого ресурса, которым можно управлять:

  • cpuset: Выделить для процесса в cgroup отдельный узел CPU, то есть его можно привязать к конкретному CPU
  • cpuacct: Статистика использования ЦП процессами в cgroup
  • memory: ограничить использование памяти процессом в контрольной группе и может сообщать об использовании памяти
  • devices: контролировать, к каким файловым устройствам могут обращаться процессы в cgroup (создание, чтение и запись файлов устройств)
  • freezer: Приостановить или возобновить задачу в контрольной группе
  • net_cls: Вы можете пометить сетевые пакеты процессов в cgroups, а затем использовать модуль tc (управление трафиком) для управления пакетами
  • blkio: Ограничьте ввод-вывод блочного устройства процесса в контрольной группе.
  • perf_event: Отслеживайте время выполнения процесса в контрольной группе, которое можно использовать для настройки производительности.
  • hugetlb: функция управления ресурсами hugetlb
  • pids: Ограничить количество процессов, которые можно создать в контрольной группе.
  • net_prio: Разрешить администраторам динамически устанавливать приоритет сетевой передачи через различные приложения.

Вы можете найти подсистему, поддерживаемую текущей системой, просмотрев /proc/cgroupsфайл CGroups:

$ cat /proc/cgroups
#subsys_name hierarchy num_cgroups enabled
cpuset       10        3           1
cpu          3         63          1
cpuacct      3         63          1
blkio        7         63          1
memory       8         69          1
devices      9         63          1
freezer      4         3           1
net_cls      2         3           1
perf_event   6         3           1
net_prio     2         3           1
hugetlb      11        3           1
pids         5         63          1

Вы также можете использовать команду mount --type cgroupthe, чтобы проверить, какие контрольные группы смонтированы в текущей системе:

$ mount --type cgroup
cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd)
cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_cls,net_prio)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpu,cpuacct)
cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer)
cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids)
cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event)
cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)
cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb)

Подкаталог групповой группы Linux

В cgroups Linux каждая cgroup представлена ​​каталогом в файловой системе cgroup. Путь к этому каталогу создается путем объединения имен контрольной группы и ее родительских контрольных групп, разделенных косой чертой.

Например, предположим, что у вас есть иерархия cgroup с двумя уровнями: корневая cgroup и две дочерние cgroup с именами «group1» и «group2». Путь к контрольной группе «group1» будет «/group1», а путь к контрольной группе «group2» будет «/group1/group2».

Например, точка монтирования подсистемы cpu находится по адресу /sys/fs/cgroup/cpu/ и выглядит так:

$ ll /sys/fs/cgroup/cpu/
total 0
-rw-r--r--  1 root root 0 Feb 12 15:32 cgroup.clone_children
-rw-r--r--  1 root root 0 Jan 29 15:34 cgroup.procs
-r--r--r--  1 root root 0 Feb 12 15:32 cgroup.sane_behavior
-r--r--r--  1 root root 0 Feb 12 15:32 cpuacct.stat
-rw-r--r--  1 root root 0 Feb 12 15:32 cpuacct.usage
-r--r--r--  1 root root 0 Feb 12 15:32 cpuacct.usage_all
-r--r--r--  1 root root 0 Feb 12 15:32 cpuacct.usage_percpu
-r--r--r--  1 root root 0 Feb 12 15:32 cpuacct.usage_percpu_sys
-r--r--r--  1 root root 0 Feb 12 15:32 cpuacct.usage_percpu_user
-r--r--r--  1 root root 0 Feb 12 15:32 cpuacct.usage_sys
-r--r--r--  1 root root 0 Feb 12 15:32 cpuacct.usage_user
-rw-r--r--  1 root root 0 Feb 12 15:32 cpu.cfs_period_us
-rw-r--r--  1 root root 0 Feb  4 14:55 cpu.cfs_quota_us
-rw-r--r--  1 root root 0 Feb  4 14:55 cpu.rt_period_us
-rw-r--r--  1 root root 0 Feb 12 15:32 cpu.rt_runtime_us
-rw-r--r--  1 root root 0 Feb  4 14:55 cpu.shares
-r--r--r--  1 root root 0 Feb 12 15:32 cpu.stat
drwxr-xr-x  3 root root 0 Feb  4 15:04 docker
-rw-r--r--  1 root root 0 Feb 12 15:32 notify_on_release
-rw-r--r--  1 root root 0 Feb 12 15:32 release_agent
drwxr-xr-x 60 root root 0 Feb  4 14:55 system.slice
-rw-r--r--  1 root root 0 Feb 12 15:32 tasks
drwxr-xr-x  2 root root 0 Feb  4 14:55 user.slice

Если мы проверим сервис docker, то увидим:

$ systemctl status docker
● docker.service - Docker Application Container Engine
   Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled; vendor preset: disabled)
   Active: active (running) since Sat 2023-02-04 14:55:06 UTC; 1 weeks 1 days ago
     Docs: https://docs.docker.com
  Process: 26807 ExecStartPre=/usr/libexec/docker/docker-setup-runtimes.sh (code=exited, status=0/SUCCESS)
  Process: 26805 ExecStartPre=/bin/mkdir -p /run/docker (code=exited, status=0/SUCCESS)
 Main PID: 26810 (dockerd)
    Tasks: 18
   Memory: 249.3M
   CGroup: /system.slice/docker.service
           └─26810 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --default-ulimit nofile=32768:65536

Вы можете видеть, что docker.service Cgroup находится по адресу /system.slice/docker.service , однако это всего лишь относительный путь, а фактический каталог файловой системы находится в соответствующей подсистеме, например, /sys/fs/cgroup/cpu/system.slice/docker.service .

Заключение