Открыть сервис

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

Пространства имён Linux — это механизм ядра операционной системы Linux, позволяющий изолировать и виртуализировать глобальные системные ресурсы, предоставляя процессам (или группам процессов) собственное представление о системе. Каждое пространство имён создаёт для своего набора процессов иллюзию, что они обладают независимым экземпляром определённого ресурса, такого как сетевой стек, дерево процессов, файловая система, идентификаторы пользователей или межпроцессное взаимодействие. Данный механизм является фундаментальной основой для технологий контейнеризации, таких как Docker, LXC и Podman.

История

Идея изоляции ресурсов в операционных системах не нова и восходит к концепции «chroot jail» (изменение корневого каталога), появившейся в Unix в 1979 году. Однако chroot обеспечивал лишь ограниченную изоляцию файловой системы, не затрагивая другие ресурсы. В 2002 году в ядре Linux версии 2.4.19 была реализована изоляция пространства имён для файловой системы (mount namespace). Разработка велась в рамках проекта VServer, направленного на создание виртуальных окружений на уровне ядра.

Значительный прогресс произошёл в 2006 году, когда в ядро Linux 2.6.19 были добавлены пространства имён для идентификаторов процессов (PID namespace), что позволило процессам внутри контейнера иметь собственные PID, отличные от хостовых. В 2008 году в версии 2.6.24 появились сетевые пространства имён (network namespace), а также пространства имён для IPC (Inter-Process Communication) и UTS (UNIX Time-Sharing System). В 2013 году в ядро 3.8 были добавлены пространства имён для идентификаторов пользователей (user namespace), что значительно повысило безопасность контейнеров, позволив запускать процессы с правами root внутри контейнера, не имея привилегий на хосте.

В 2016 году в ядро 4.6 были включены пространства имён для групп управления (cgroup namespace), что позволило изолировать иерархию cgroups внутри контейнера. Последним на данный момент типом стали пространства имён для пространства имён (time namespace), добавленные в ядро 5.6 в 2020 году, предназначенные для изоляции системного времени.

Типы пространств имён

Ядро Linux поддерживает восемь типов пространств имён, каждый из которых изолирует определённый глобальный ресурс. Для каждого типа существует системный вызов clone(), unshare() или setns(), позволяющий создавать или присоединяться к существующему пространству имён.

Mount namespace (mnt)

Изолирует точки монтирования файловой системы. Процессы в разных mount namespace видят разные иерархии файловых систем. Это позволяет создавать изолированные корневые файловые системы (rootfs) для контейнеров. При создании нового mount namespace можно скопировать список точек монтирования из родительского пространства или начать с пустого. Данный тип является наследником chroot, но предоставляет более гибкую и полную изоляцию.

PID namespace (pid)

Изолирует идентификаторы процессов. Процессы внутри одного PID namespace видят только свои собственные процессы, а идентификаторы процессов внутри контейнера начинаются с 1 (init-процесс). С точки зрения хоста, эти же процессы имеют другие, глобальные PID. Это предотвращает возможность воздействия на процессы хоста из контейнера через знание их PID. Вложенные PID namespace позволяют создавать многоуровневую изоляцию.

Network namespace (net)

Изолирует сетевой стек: сетевые интерфейсы, IP-адреса, таблицы маршрутизации, правила брандмауэра (iptables, nftables), сокеты и другие сетевые ресурсы. Каждое сетевое пространство имён имеет собственный loopback-интерфейс (lo) и может иметь виртуальные интерфейсы (veth), связывающие его с другими пространствами имён или с физическим сетевым интерфейсом хоста. Это позволяет контейнерам иметь собственные IP-адреса и настраивать сетевую изоляцию.

User namespace (user)

Изолирует идентификаторы пользователей и групп (UID/GID), а также ключи (keys) и capabilities (привилегии). Это наиболее важный тип с точки зрения безопасности. Внутри user namespace процесс может иметь UID 0 (root) и обладать полным набором привилегий, но при этом на хосте он будет отображаться как непривилегированный пользователь с высоким UID (например, 65534). Это позволяет запускать контейнеры с правами root без предоставления реальных привилегий на хосте. User namespace могут быть вложенными.

IPC namespace (ipc)

Изолирует механизмы межпроцессного взаимодействия System V (очереди сообщений, семафоры, разделяемая память) и POSIX (shared memory). Процессы в разных IPC namespace не могут взаимодействовать друг с другом через эти механизмы, что предотвращает утечку данных между контейнерами.

UTS namespace (uts)

Изолирует имя хоста (hostname) и доменное имя (NIS domain name). Процессы внутри контейнера могут видеть собственное имя хоста, отличное от имени хоста хостовой системы. Это используется для настройки сетевой идентификации контейнера.

Cgroup namespace (cgroup)

Изолирует иерархию контрольных групп (cgroups). Процессы внутри контейнера видят только свою часть дерева cgroups, что предотвращает возможность вмешательства в управление ресурсами других контейнеров или хоста. Появился в ядре 4.6.

Time namespace (time)

Изолирует системное время (CLOCK_MONOTONIC и CLOCK_BOOTTIME). Позволяет устанавливать смещение времени для процессов внутри контейнера, что может быть полезно для тестирования или приложений, чувствительных к времени. Появился в ядре 5.6.

Устройство и работа

Создание пространства имён происходит через системные вызовы. Основной способ — использование флагов при вызове clone(), который создаёт новый процесс с новыми пространствами имён. Например, clone(..., CLONE_NEWNS | CLONE_NEWPID, ...) создаст процесс с новыми mount и PID namespace. Системный вызов unshare() позволяет отключить процесс от текущего пространства имён и создать новое, не создавая новый процесс. Системный вызов setns() позволяет присоединить текущий процесс к существующему пространству имён, указав его файловый дескриптор.

Каждое пространство имён представлено в файловой системе /proc в виде файлов в каталогах /proc/[pid]/ns/. Например, /proc/1/ns/net указывает на сетевое пространство имён процесса с PID 1. Эти файлы являются символическими ссылками на уникальные inode, представляющие пространство имён. Процесс может получить файловый дескриптор, указывающий на пространство имён, открыв соответствующий файл.

Пространства имён могут быть вложенными. Например, можно создать PID namespace внутри другого PID namespace, что создаёт иерархию. Процессы в родительском пространстве видят все процессы в дочерних, но не наоборот.

Применение

Контейнеризация

Основное применение пространств имён — создание контейнеров. Такие системы, как Docker, LXC и Podman, используют комбинацию пространств имён для изоляции процессов. Типичный контейнер использует:

  • mount namespace — для изоляции файловой системы;
  • pid namespace — для изоляции процессов;
  • network namespace — для изоляции сети;
  • user namespace — для безопасного запуска от root;
  • ipc namespace — для изоляции IPC;
  • uts namespace — для изоляции hostname;
  • cgroup namespace — для изоляции ресурсов.

Виртуализация на уровне ОС

Пространства имён позволяют создавать лёгкие виртуальные окружения (так называемые «контейнеры операционной системы»), которые изолированы друг от друга, но используют одно и то же ядро. Это эффективнее полной виртуализации (например, KVM, VMware), так как не требует запуска отдельной операционной системы.

Изоляция приложений

Пространства имён могут использоваться для изоляции отдельных приложений, например, в системах песочниц (sandbox). Утилита unshare позволяет запустить команду в новом пространстве имён. Например, unshare -n ping 8.8.8.8 запустит ping в новом сетевом пространстве имён, не имеющем доступа к сети.

Тестирование и отладка

С помощью пространств имён можно создавать изолированные тестовые среды, не затрагивающие основную систему. Например, можно смонтировать другую файловую систему, изменить hostname или настроить сеть, не влияя на другие процессы.

Критика и ограничения

Несмотря на широкое распространение, пространства имён имеют ряд ограничений и критических замечаний:

  • Неполная изоляция. Пространства имён изолируют не все системные ресурсы. Например, такие ресурсы, как /proc/sys, /sys, /dev, а также некоторые файлы в /proc (например, /proc/self/mountinfo) остаются общими для всех пространств имён. Это может привести к утечкам информации или возможностям для атак.
  • Сложность управления. Управление большим количеством вложенных пространств имён может быть сложным и требовать глубоких знаний ядра.
  • Безопасность. Хотя user namespace значительно повышает безопасность, неправильная настройка может привести к эскалации привилегий. Например, если процесс с root внутри user namespace получает доступ к некоторым системным вызовам, это может быть опасно.
  • Производительность. Создание и переключение между пространствами имён требует определённых накладных расходов, хотя в большинстве случаев они незначительны.

Интересные факты

  • В ядре Linux существует возможность создавать «вложенные» пространства имён практически для всех типов, что позволяет создавать иерархические структуры изоляции.
  • Пространства имён являются ключевым компонентом технологии «сетевых неймспейсов» (network namespace), используемой для создания виртуальных сетей в проектах, таких как Open vSwitch и Kubernetes.
  • В 2019 году в ядро Linux была добавлена поддержка «пространств имён для времени» (time namespace), что позволило изолировать системное время для контейнеров.
  • Механизм пространств имён не является уникальным для Linux; аналогичные концепции существуют в других операционных системах, например, в FreeBSD (jails) и Solaris (zones).

Источники

  • Kerrisk, M. (2010). The Linux Programming Interface: A Linux and UNIX System Programming Handbook. No Starch Press.
  • Rosen, R. (2014). Linux Containers: A Technical Overview. Linux Foundation.
  • Docker Inc. (2023). Docker Overview: Namespaces. Docker Documentation.
  • Linux Kernel Organization. (2023). Linux Kernel Documentation: Namespaces. kernel.org.
  • Kerner, S. M. (2016). Linux Kernel 4.6: New Features and Improvements. ServerWatch.

BFOmetr — база данных и аналитика по компаниям России.

На главную BFOmetr →