Поиск по сайту:

Что такое пространства имен Linux и для чего они используются?


Пространства имен Linux являются базовой технологией контейнерных технологий, таких как Docker. Это функция ядра Linux, которая позволяет системе ограничивать ресурсы, которые видят контейнеризованные процессы, и гарантирует, что ни один из них не будет мешать другому.

Что такое пространства имен?

Когда вы запускаете множество различных процессов и приложений на одном сервере, как в случае с инструментами развертывания, такими как Kubernetes, важно, чтобы каждый процесс был изолирован, в основном для безопасности.

Один контейнер не должен иметь возможности получить контроль над ресурсами другого, потому что, если этот контейнер будет скомпрометирован, это может поставить под угрозу всю систему. Этот метод атаки похож на то, как работает ошибка процессора Meltdown; разные потоки процессора должны быть изолированы друг от друга. Точно так же процессы, работающие в разных виртуальных системах (контейнерах), должны быть изолированы от других контейнеров.

Пространства имен обеспечивают эту изоляцию на уровне ядра. Подобно тому, как работает chroot приложения, который заключает процесс в другой корневой каталог, пространства имен разделяют другие аспекты системы. Доступно семь пространств имен:

  • Mount или mnt. Очень похожее на chroot, пространство имен Mount виртуально разделяет файловую систему. Процессы, запущенные в отдельных пространствах имен монтирования, не могут получить доступ к файлам за пределами своей точки монтирования. Поскольку это делается на уровне ядра, это намного безопаснее, чем изменение корневого каталога с помощью chroot.
  • Процесс или pid. В Linux первые процессы появляются как потомки PID 1, который формирует корень дерева процессов. Пространство имен процесса отсекает ветвь дерева PID и не разрешает доступ дальше по ветке. Процессы в дочерних пространствах имен на самом деле будут иметь несколько PID: первый представляет собой глобальный PID, используемый основной системой, а второй PID представляет PID в дочернем дереве процессов, которое будет перезапущено с 1.
  • Взаимодействие между процессами или ipc. Это пространство имен определяет, могут ли процессы напрямую общаться друг с другом.
  • Сеть или net. Это пространство имен определяет, какие сетевые устройства могут видеть процессы. Однако это ничего не настраивает автоматически — вам все равно нужно создавать виртуальные сетевые устройства и управлять соединением между глобальными сетевыми интерфейсами и дочерними сетевыми интерфейсами. Программное обеспечение для контейнеризации, такое как Docker, уже разобралось с этим и может управлять сетью вместо вас.
  • Пользователь. Это пространство имен позволяет процессу иметь «виртуальный корень» внутри своего собственного пространства имен, не имея фактического корневого доступа к родительской системе. Он также разделяет информацию UID и GID, поэтому дочерние пространства имен могут иметь свои собственные пользовательские конфигурации.
  • УТС. Это пространство имен контролирует информацию об имени хоста и домене и позволяет процессам думать, что они работают на серверах с разными именами.
  • Cgroup — еще одна функция ядра, очень похожая на пространства имен. Cgroups позволяют системе определять ограничения ресурсов (ЦП, память, дисковое пространство, сетевой трафик и т. д.) для группы процессов. Это полезная функция для контейнерных приложений, но она не обеспечивает никакой «изоляции информации», как пространства имен. Пространство имен cgroup – это отдельная вещь, которая определяет, какие cgroups могут видеть процессы, а не назначает его конкретной cgroup.

По умолчанию любой процесс, который вы запускаете, использует глобальные пространства имен, и большинство процессов в вашей системе делают то же самое, если не указано иное.

Работа с пространствами имен

Вы можете использовать команду lsns (ls-namespaces), чтобы просмотреть текущие активные пространства имен в вашей системе. Эту команду необходимо запускать от имени пользователя root, иначе список может быть неполным.

Выше показан lsns результат новой установки Ubuntu. Каждое пространство имен указано вместе с идентификатором процесса, пользователем и командой, создавшей его. Семь пространств имен, созданных из /sbin/init с PID 1, являются семью глобальными пространствами имен. Единственными другими пространствами имен являются пространства имен mnt для системных демонов, а также службы Livepatch от Canonical.

Если бы вы работали с контейнерами, этот список был бы намного длиннее. Вы можете вывести этот список в формате JSON с флагом -J , который гораздо проще использовать с языком сценариев.

Вы можете изменить текущее пространство имен с помощью утилиты nsenter. Эта команда позволяет вам «входить» в пространство имен другого процесса, обычно в целях отладки. На самом деле он может выполнять любую команду в этом пространстве имен, но по умолчанию он просто пытается загрузить оболочку (обычно /bin/bash).

Вы указываете идентификатор процесса, затем каждое пространство имен, которое вы хотите ввести:

sudo nsenter -t PID --mount --net --pid  //etc.

Например, попытка ввести пространство имен монтирования для kdevtmpfs загрузит вас в это пространство имен, но впоследствии завершится ошибкой, поскольку не удастся найти /bin/bash, что на самом деле означает, что работало, потому что видимый корневой каталог был изменен.

Если ваше дочернее пространство имен mnt включает /bin/bash, вы можете ввести его и загрузить оболочку. Это можно сделать вручную, но следует выполнять с помощью монтирования привязки, которое может манипулировать деревом каталогов и связывать файлы через пространства имен mnt. Это может привести к некоторым интересным вариантам использования, например заставить два процесса читать разное содержимое из одного и того же файла.

Чтобы создать новые пространства имен, вам нужно создать ответвление от существующего (обычно глобального) и указать, какие пространства имен вы хотите изменить. Это делается с помощью команды unshare , которая запускает команду с новым пространством имен, «не используемым совместно» с мастером.

Чтобы отменить совместное использование пространства имен хостов, используйте:

sudo unshare -u command

Если команда не указана, unshare по умолчанию запускает bash. Это создает новое пространство имен, которое будет отображаться в выводе lsns:

Мультиплексор терминала screen используется здесь, чтобы поддерживать работу bash в фоновом режиме, иначе пространство имен исчезло бы при закрытии процесса.

Если вы не занимаетесь программированием на очень низком уровне, вам, вероятно, не придется самостоятельно прикасаться к пространствам имен. Программы контейнеризации, такие как Docker, будут управлять деталями за вас, и в большинстве случаев, когда вам нужна изоляция процессов, вам следует просто использовать существующий инструмент. Однако важно понимать, как пространства имен работают в контексте контейнеризации, особенно если вы выполняете какую-либо низкоуровневую настройку своих контейнеров Docker или должны выполнять какую-либо ручную отладку.