# Namespaces и cgroups

> Два механизма ядра Linux, на которых построены контейнеры: пространства имён изолируют то, что процесс видит, а cgroups ограничивают, сколько ресурсов он потребляет.

Источник: https://llmdocs.ru/wiki/namespaces-cgroups/ · обновлено 2026-11-09 · лицензия CC BY-SA 4.0

- **Подсистема**: ядро Linux
- **Namespaces**: с 2002 (mount), полный набор к 2013 (user), cgroup ns 2016, time ns 2020
- **cgroups**: Google (2006), в ядре с 2.6.24 (2008)
- **cgroup v2**: стабильна с ядра 4.5 (2016)
- **Видов namespaces**: 8 (mnt, pid, net, ipc, uts, user, cgroup, time)
- **Утилиты**: unshare, nsenter, lsns, systemd-cgls, systemd-cgtop
**Namespaces** (пространства имён) и **cgroups** (*control groups*, контрольные группы) — два механизма ядра [Linux](https://llmdocs.ru/wiki/linux.md), из которых собирается то, что мы называем контейнером. Пространства имён отвечают на вопрос «*что* процесс видит»: свой список процессов, свою сеть, свою файловую систему, своё имя хоста. Контрольные группы отвечают на вопрос «*сколько* процесс может потребить»: процессорного времени, памяти, операций ввода-вывода. Контейнер — это обычный процесс, запущенный в отдельных namespaces и помещённый в свою cgroup; никакой виртуальной машины при этом нет.

## История

Первым в 2002 году появилось пространство имён точек монтирования (mount namespace, ядро 2.4.19), вдохновлённое ОС Plan 9. Остальные добавлялись постепенно, и набор, достаточный для полноценных контейнеров, сложился к ядру 3.8 (2013) с появлением user namespaces.[6] Механизм cgroups инженеры Google начали разрабатывать в 2006 году под названием «process containers»; в ядро он вошёл в 2.6.24 (2008). Из-за запутанной иерархии первой версии была создана **cgroup v2** с единым деревом, стабильная с ядра 4.5 (2016).[3] На этих механизмах построены LXC (2008), [Docker](https://llmdocs.ru/wiki/docker.md) (2013) и все современные среды выполнения.

## Пространства имён

Каждый процесс принадлежит одному пространству имён каждого вида; по умолчанию — общим «корневым».[1]

| Вид | Флаг | Что изолирует |
|---|---|---|
| mnt | `CLONE_NEWNS` | дерево точек монтирования (своя корневая ФС) |
| pid | `CLONE_NEWPID` | номера процессов: внутри контейнера приложение — PID 1 |
| net | `CLONE_NEWNET` | сетевые интерфейсы, маршруты, правила iptables, порты |
| ipc | `CLONE_NEWIPC` | очереди сообщений и разделяемую память System V / POSIX |
| uts | `CLONE_NEWUTS` | имя хоста и домена |
| user | `CLONE_NEWUSER` | UID/GID: root внутри может быть обычным пользователем снаружи |
| cgroup | `CLONE_NEWCGROUP` | видимую часть дерева cgroups |
| time | `CLONE_NEWTIME` | смещения часов `CLOCK_MONOTONIC` и `CLOCK_BOOTTIME` |

Пространства создаются системными вызовами `clone()` и `unshare()`, присоединиться к существующему можно через `setns()`. Они видны как файлы в `/proc/<PID>/ns/`.

**User namespaces** особенно важны для безопасности: они позволяют запускать контейнеры без прав root на хосте (*rootless*-режим [Podman](https://llmdocs.ru/wiki/podman.md) и Docker).[4]

## Контрольные группы

cgroup — это узел иерархии в виртуальной файловой системе `/sys/fs/cgroup`, к которому привязаны процессы и **контроллеры** ресурсов.[2] В cgroup v2 основные контроллеры такие:

- **cpu** — веса (`cpu.weight`) и жёсткие квоты (`cpu.max`, например `50000 100000` = половина ядра);
- **memory** — лимит (`memory.max`); при его превышении внутри группы срабатывает OOM killer;
- **io** — ограничение пропускной способности и IOPS для блочных устройств;
- **pids** — максимальное число процессов (защита от fork-бомбы);
- **cpuset** — привязка к конкретным ядрам и NUMA-узлам.

В современных дистрибутивах деревом cgroups управляет [systemd](https://llmdocs.ru/wiki/systemd.md): каждая служба, пользовательская сессия и контейнер получают свою группу. [Kubernetes](https://llmdocs.ru/wiki/kubernetes.md) переводит `requests` и `limits` из описания [Pod](https://llmdocs.ru/wiki/pod.md) в настройки cgroup на узле; начиная с версии 1.25 поддержка cgroup v2 стабильна, а cgroup v1 объявлена устаревшей.[5]

## Попробовать вручную

```bash
# новая оболочка в отдельных pid-, mount- и uts-пространствах
sudo unshare --pid --fork --mount-proc --uts bash
hostname sandbox; ps aux          # видны только процессы этой оболочки

# пространства имён процесса и вход в них (как docker exec)
lsns -p <PID>
sudo nsenter -t <PID> -n ip addr   # сеть контейнера

# cgroups
systemd-cgls                       # дерево групп
systemd-run --scope -p MemoryMax=200M -p CPUQuota=50% ./heavy_job
cat /sys/fs/cgroup/system.slice/nginx.service/memory.current
```

## Изоляция и её пределы

Все контейнеры на хосте делят **одно ядро**. Уязвимость в ядре или опасные привилегии (`--privileged`, монтирование сокета Docker, лишние capabilities) позволяют выбраться из контейнера. Поэтому namespaces и cgroups дополняют другими механизмами: capabilities (дробление прав root), seccomp (фильтр системных вызовов), AppArmor и SELinux. Для более жёсткой изоляции применяют песочницы вроде gVisor и микро-VM вроде Kata Containers и Firecracker.

## См. также

- [Контейнеризация](https://llmdocs.ru/wiki/containerization.md)
- [Образ контейнера и OCI](https://llmdocs.ru/wiki/oci-image.md)
- [Процессы и сигналы](https://llmdocs.ru/wiki/processes-signals.md)
- [Права доступа в Unix](https://llmdocs.ru/wiki/unix-permissions.md)

## Источники

1. [man 7 namespaces — overview of Linux namespaces](https://man7.org/linux/man-pages/man7/namespaces.7.html)
2. [man 7 cgroups — Linux control groups](https://man7.org/linux/man-pages/man7/cgroups.7.html)
3. [Linux kernel docs — Control Group v2](https://docs.kernel.org/admin-guide/cgroup-v2.html)
4. [man 7 user_namespaces](https://man7.org/linux/man-pages/man7/user_namespaces.7.html)
5. [Kubernetes Docs — About cgroup v2](https://kubernetes.io/docs/concepts/architecture/cgroups/)
6. [LWN — Namespaces in operation (series, 2013)](https://lwn.net/Articles/531114/)
