# cgroups (v2) _Процессы и ресурсы · LinuxLab Knowledge Base_ **TL;DR:** cgroups v2 - иерархическая виртуальная FS под `/sys/fs/cgroup` через которую ядро лимитирует CPU/память/I/O процессов. Docker/k8s/systemd пишут сюда. ## Что такое cgroup **Control group** - группа процессов с общими ограничениями ресурсов (CPU, RAM, I/O, PIDs, network) и общим учётом потребления. В cgroups v2 (стандарт на современных Ubuntu/Debian/Fedora) - **одна** иерархия каталогов под `/sys/fs/cgroup/`. Каждый каталог это cgroup. Подкаталоги - дочерние cgroup'ы (наследуют лимиты родителя). Каждый процесс приписан **к ровно одному** cgroup'у. Узнать свой: ```bash cat /proc/self/cgroup # 0::/system.slice/docker-abc123.scope ``` Полный путь = `/sys/fs/cgroup` + значение из файла. ## Контроллеры В рамках одной иерархии включаются «контроллеры» - модули учёта/лимитов: - `cpu` - share / quota; `cpu.max` = `quota period` (e.g. `50000 100000` = половина CPU) - `memory` - `memory.max` = hard limit, `memory.high` = soft (троттл с reclaim) - `io` - bandwidth и iops по устройствам (`io.max`) - `pids` - `pids.max` (сколько процессов разрешено) - `cpuset` - пиннинг к конкретным ядрам и NUMA-нодам Включаются через `cgroup.subtree_control`: ```bash cat /sys/fs/cgroup/cgroup.controllers # доступные cat /sys/fs/cgroup/cgroup.subtree_control # включённые на дочерних ``` ## Что туда пишут Docker / k8s / systemd Когда ты делаешь `docker run --cpus=0.5 --memory=256m`: - Docker создаёт `/sys/fs/cgroup/system.slice/docker-.scope/` - Пишет `cpu.max = "50000 100000"` (50ms из 100ms) - Пишет `memory.max = 268435456` - Помещает PID контейнерного init в `cgroup.procs` k8s pod с `resources: limits: { cpu: 500m, memory: 256Mi }` делает то же через kubelet → cri-o/containerd → ядро. systemd unit с `MemoryMax=512M` - то же самое, только через `slice`/`scope`-юниты. ## PSI - Pressure Stall Information Самое полезное в v2 - файлы `cpu.pressure`, `memory.pressure`, `io.pressure`. Они показывают сколько % времени процесс **ждал** ресурс. PSI точнее [load-average](/kb/load-average.md) потому что нормализован и работает per-cgroup (важно в контейнерах). ``` some avg10=12.34 avg60=8.90 avg300=4.50 total=... full avg10=2.10 avg60=1.80 avg300=0.90 total=... ``` `some` = хотя бы один процесс ждал; `full` = ВСЕ процессы ждали. ## OOM в cgroup Когда процесс в cgroup'е упирается в `memory.max`, срабатывает [oom-killer](/kb/oom-killer.md) - но только в пределах этого cgroup'а, остальная система не страдает. ## Команды ```bash cat /proc/self/cgroup ``` В каком cgroup'е находится текущий процесс ```bash MY=$(awk -F: '{print $3}' /proc/self/cgroup); ls /sys/fs/cgroup$MY ``` Какие контроллеры доступны для нашего cgroup'а ```bash cat /sys/fs/cgroup/cpu.max ``` CPU-лимит текущего корневого cgroup'а: ` ` µs или `max` ```bash cat /sys/fs/cgroup/memory.current ``` Сколько RAM cgroup использует прямо сейчас (байты) ```bash cat /sys/fs/cgroup/cpu.pressure ``` PSI - точная метрика «насколько ресурс в дефиците» на per-cgroup уровне ## См. также - [Процесс и PID](/kb/process-and-pid.md) - [Linux namespaces](/kb/namespaces.md) - [cgroups v2 - unified hierarchy, PSI, eBPF control](/kb/cgroups-v2-deep.md) - [OOM killer](/kb/oom-killer.md) - [kubelet - архитектура агента ноды Kubernetes](/kb/kubelet-internals.md)