# Linux namespaces _Процессы и ресурсы · LinuxLab Knowledge Base_ **TL;DR:** Namespaces - механизм ядра, который даёт процессу собственный изолированный view на ресурс (сеть, mount-points, PID, UID, IPC, hostname, time). На них построены все контейнеры. ## Зачем нужны namespaces Контейнеры - это не виртуальные машины. У них одно ядро с хостом. Изоляцию даёт связка двух механизмов: - [cgroups](/kb/cgroups.md) - лимит «**сколько** ресурсов можно тратить» - **namespaces** - лимит «**что** видно процессу» ## Семь типов | namespace | что изолирует | флаг unshare/clone | |---|---|---| | **mnt** | mount points (свой набор смонтированных FS) | `CLONE_NEWNS` | | **net** | интерфейсы, маршруты, ARP, сокеты, файрвол | `CLONE_NEWNET` | | **pid** | дерево PID; PID 1 в ns ≠ PID 1 на хосте | `CLONE_NEWPID` | | **user** | UID/GID; root внутри = unprivileged снаружи | `CLONE_NEWUSER` | | **uts** | hostname, domainname | `CLONE_NEWUTS` | | **ipc** | System V IPC, shared memory | `CLONE_NEWIPC` | | **cgroup** | view на cgroup-tree (видишь только своё поддерево) | `CLONE_NEWCGROUP` | | **time** | CLOCK_MONOTONIC offset (Linux 5.6+) | `CLONE_NEWTIME` | ## Как создаются Три способа: 1. **`clone()` / `unshare()` syscall** - программа просит у ядра новый namespace 2. **`ip netns add NAME`** - создаёт network namespace, монтирует `/run/netns/NAME` чтобы можно было сослаться (см. [veth-pair](/kb/veth-pair.md)) 3. **`unshare CMD`** - обёртка которая делает `unshare()` + `exec()` ## Что видно в /proc//ns/ Каждый процесс - это набор **namespace handle**'ов в `/proc//ns/`: ```bash ls -l /proc/self/ns/ # net -> 'net:[4026531992]' # mnt -> 'mnt:[4026531840]' # pid -> 'pid:[4026531836]' # ... ``` Число в скобках - inode-id namespace'а. Если у двух процессов одинаковый ID для `net` - они в одном network namespace. Это первичный способ диагностики «в каком ns я нахожусь». Перейти в существующий namespace другого процесса - `nsenter`: ```bash sudo nsenter -t -n -p ip addr # выполнить ip addr в net+pid ns процесса ``` ## Связь с Docker Когда ты делаешь `docker run image`, Docker: 1. `unshare()` со всеми флагами кроме `time` 2. Создаёт [veth-pair](/kb/veth-pair.md), один конец оставляет на хосте в bridge, другой кладёт в новый net-namespace 3. Mount'ит overlay-FS как корень процесса 4. Помещает процесс в [cgroups](/kb/cgroups.md) для лимитов 5. `exec`-нул бинарь из image Всё. Никакой VM, никакого гипервизора - только namespaces + cgroups. ## Команды ```bash ls -l /proc/self/ns/ ``` Все namespace'ы в которых сидит текущий процесс ```bash sudo ip netns add red && ip netns list ``` Создать новый network namespace и перечислить все ```bash sudo ip netns exec red ip addr ``` Выполнить команду внутри указанного network namespace ```bash sudo unshare --net --uts -- bash ``` Запустить bash в свежих net+uts namespace'ах ```bash sudo nsenter -t 1234 -a ``` Войти ВО ВСЕ namespace'ы процесса 1234 (-a: all) ## См. также - [Процесс и PID](/kb/process-and-pid.md) - [cgroups (v2)](/kb/cgroups.md) - [veth pair](/kb/veth-pair.md) - [tmpfs и overlayfs - RAM-disk и слои](/kb/tmpfs-overlayfs.md) - [chroot - изоляция процесса в каталог](/kb/chroot.md) - [runc, runsc, kata - container runtimes](/kb/runc-and-runsc.md)