Как работает Linux namespaces и как они используются в контейнерах

8 минут чтения
Средний рейтинг статьи — 4.8

Контейнеры часто воспринимаются как нечто абстрактное — Docker, Kubernetes, pod’ы. Но в основе всей контейнеризации в Linux лежат вполне конкретные механизмы ядра. Один из ключевых — Linux namespaces.

В этой статье разберёмся, что такое namespaces, какие они бывают, как изолируют процессы и почему без них контейнеры в привычном виде просто не существовали бы.

Что такое Linux namespaces

Namespaces — это механизм ядра Linux, который позволяет изолировать процессы друг от друга, показывая им разные представления системных ресурсов.

Проще говоря:

  • процессы в разных namespaces могут думать, что они работают на отдельной системе;
  • при этом физически они находятся на одном ядре.

Каждый namespace изолирует определённый тип ресурсов: процессы, сеть, файловую систему, пользователей и т.д.

Основные виды namespaces

На сегодняшний день Linux поддерживает несколько типов namespaces, каждый из которых отвечает за свою область изоляции.

PID namespace

PID namespace изолирует идентификаторы процессов.

Что это даёт:

  • внутри контейнера есть свой PID 1;
  • процессы контейнера не видят процессы хоста;
  • одинаковые PID могут существовать в разных namespaces.

Это позволяет контейнеру выглядеть как отдельная система с собственным init-процессом.

Network namespace

Network namespace изолирует сетевой стек.

Внутри namespace:

  • свои сетевые интерфейсы;
  • собственные IP-адреса;
  • отдельные таблицы маршрутизации;
  • свои правила iptables.

Именно благодаря этому каждый контейнер может иметь собственную сеть.

Mount namespace

Mount namespace отвечает за изоляцию точек монтирования.

Это позволяет:

  • каждому контейнеру иметь собственное дерево файловой системы;
  • монтировать и размонтировать FS, не влияя на хост;
  • использовать overlayfs для слоёв образов.

Контейнер «видит» только те файловые системы, которые ему смонтировали.

UTS namespace

UTS namespace изолирует hostname и domain name.

Благодаря ему:

  • каждый контейнер может иметь собственное имя хоста;
  • команды вроде hostname работают независимо от хоста.

Небольшой, но важный элемент изоляции.

IPC namespace

IPC namespace изолирует механизмы межпроцессного взаимодействия:

  • shared memory;
  • semaphores;
  • message queues.

Это предотвращает случайное или вредоносное взаимодействие процессов разных контейнеров.

User namespace

User namespace — один из самых важных и сложных.

Он позволяет:

  • маппить UID/GID внутри контейнера в другие UID/GID на хосте;
  • запускать процессы с UID 0 внутри контейнера без root-доступа на хосте.

Именно user namespaces делают возможными rootless-контейнеры.

Как namespaces используются в контейнерах

Когда вы запускаете контейнер, Docker или другой runtime:

  1. Создаёт набор namespaces (PID, NET, MOUNT и т.д.)
  2. Запускает процесс внутри этих namespaces
  3. Ограничивает ресурсы через cgroups
  4. Подменяет корневую файловую систему

В результате процесс:

  • думает, что он единственный на системе;
  • имеет свою сеть и файловую систему;
  • не видит процессы и ресурсы хоста.

На самом деле это обычный процесс Linux, просто хорошо изолированный.

Namespaces ≠ безопасность

Важно понимать: namespaces — это изоляция, но не полноценная безопасность.

Проблемы:

  • уязвимости ядра пробивают изоляцию;
  • ошибки конфигурации дают доступ к хосту;
  • не все namespaces включены по умолчанию.

Поэтому в продакшене namespaces всегда дополняются:

  • cgroups;
  • seccomp;
  • AppArmor или SELinux;
  • capabilities.

Можно ли использовать namespaces без Docker

Да. Namespaces — это часть ядра Linux, и их можно использовать напрямую:

  • unshare — запуск процесса в новом namespace;
  • nsenter — вход в namespace существующего процесса;
  • системные вызовы clone() и setns().

Docker — это просто удобная обёртка над этими возможностями.

Связь namespaces и cgroups

Важно понимать, что namespaces отвечают за изоляцию, а cgroups — за ограничение ресурсов.

Если namespaces определяют что процесс видит, то cgroups определяют сколько ресурсов он может потреблять:

  • CPU
  • память
  • I/O
  • количество процессов

Именно связка namespaces + cgroups делает контейнеры управляемыми и безопасными.

В этой статье мы рассказали, что такое cgroups v2, чем они отличаются от v1 и как с их помощью ограничивать ресурсы контейнеров и процессов в Linux.

Итог

Linux namespaces — фундамент контейнеризации:

  • они изолируют процессы, сеть, FS и пользователей;
  • позволяют запускать множество контейнеров на одном ядре;
  • делают контейнеры лёгкими и быстрыми по сравнению с VM.

Понимание namespaces помогает лучше разбираться в Docker, Kubernetes и в устройстве Linux в целом.

8 минут чтения
Средний рейтинг статьи — 4.8

Настроить мониторинг за 30 секунд

Надежные оповещения о даунтаймах. Без ложных срабатываний