Команда unshare не создает новое пространство имен PID

avatar
Andrew Bolotov
8 августа 2021 в 21:11
353
1
0

Я изучаю ядро ​​​​Linux и сейчас занимаюсь темой namepsaces. Я попытался поиграть с командой «unshare», чтобы понять пространство имен и его основы. Проблема в том, что это не так, или, что более вероятно, я что-то делаю не так. Буду признателен, если вы поможете мне понять. Я пытаюсь выполнить программу busybox sh как в собственном пространстве имен PID. Вот что я делаю:

[ab@a ~]$ sudo unshare --pid  busybox sh
/home/ab # ps
PID TTY          TIME CMD
6014 pts/1    00:00:00 sudo
6016 pts/1    00:00:00 busybox
6026 pts/1    00:00:00 ps

Как я вижу из вывода команды ps, все процессы видны в новой среде. И это подтверждается, когда я проверяю идентификатор пространства имен pid вновь созданного процесса и текущего. См. ниже

[ab@a ~]$ ps -p 6016,$$
PID TTY          TIME CMD
4604 pts/0    00:00:00 bash
6016 pts/1    00:00:00 busybox
[ab@a ~]$ sudo ls -l /proc/4604/ns
total 0
lrwxrwxrwx. 1 ab ab 0 Aug  8 23:49 ipc -> ipc:[4026531839]
lrwxrwxrwx. 1 ab ab 0 Aug  8 23:49 mnt -> mnt:[4026531840]
lrwxrwxrwx. 1 ab ab 0 Aug  8 23:49 net -> net:[4026531968]
lrwxrwxrwx. 1 ab ab 0 Aug  8 23:49 pid -> pid:[4026531836]
lrwxrwxrwx. 1 ab ab 0 Aug  8 23:49 user -> user:[4026531837]
lrwxrwxrwx. 1 ab ab 0 Aug  8 23:49 uts -> uts:[4026531838]
[ab@a ~]$ sudo ls -l /proc/6016/ns
total 0
lrwxrwxrwx. 1 root root 0 Aug  9 00:07 ipc -> ipc:[4026531839]
lrwxrwxrwx. 1 root root 0 Aug  9 00:07 mnt -> mnt:[4026531840]
lrwxrwxrwx. 1 root root 0 Aug  9 00:07 net -> net:[4026531968]
lrwxrwxrwx. 1 root root 0 Aug  9 00:07 pid -> pid:[4026531836]
lrwxrwxrwx. 1 root root 0 Aug  9 00:07 user -> user:[4026531837]
lrwxrwxrwx. 1 root root 0 Aug  9 00:07 uts -> uts:[4026531838]

Итак, пространство имен pid остается прежним, несмотря на то, что я предоставил аргумент --pid для отмены совместного использования вызова. Не могли бы вы помочь мне понять, почему это происходит. Спасибо

Источник

Ответы (1)

avatar
200 not ok
9 августа 2021 в 02:07
1

Решение

вы должны добавить --fork и --mount-proc переключиться на unshare как указано на странице руководства

-f, --fork
          Fork the specified program as a child process of unshare rather than running it directly. This is useful
          when creating a new PID namespace. Note that when unshare is waiting for the child process, then it
          ignores SIGINT and SIGTERM and does not forward any signals to the child. It is necessary to send
          signals to the child process.

Пояснение (из man pid_namespaces)

принадлежность процесса к пространству имен PID определяется при создании процесса и не может быть изменена после этого.

то, что на самом деле делает unshare, когда вы указываете --pid, устанавливает дескриптор файла /proc/[PID]/ns/pid_for_children для текущего процесса в новое пространство имен PID, в результате чего дочерние элементы, впоследствии созданные этим процессом, помещаются в другое пространство имен PID ( его дети не сами!! важно!).

Итак, когда вы передаете --fork в unshare, ваша программа (в данном случае busybox sh) разветвляется как дочерний процесс unshare и помещается в новое пространство имен PID.

Зачем мне нужен --mount-proc ?

Попробуйте запустить unshare только с --pid и --fork и посмотрим, что произойдет.

wendel@gentoo-grill ~ λ sudo unshare --pid --fork busybox sh
/home/wendel # echo $$
1
/home/wendel # ps
PID   USER     TIME  COMMAND
12443 root      0:00 unshare --pid --fork busybox sh
12444 root      0:00 busybox sh
24370 root      0:00 {ps} busybox sh
.
.
. // bunch more

из echo $$ мы видим, что pid на самом деле равен 1, поэтому мы знаем, что мы должны быть в новом пространстве имен PID, но когда мы запускаем ps, мы видим другие процессы, как будто мы все еще находимся в родительском пространстве имен PID .

Это связано с тем, что /proc — это специальная файловая система с именем procfs, созданная ядром в памяти и взятая из справочной страницы.

Файловая система /proc показывает (в каталогах /proc/[pid]) только процессы, видимые в пространстве имен PID процесса, выполнившего монтирование, даже если файловая система /proc просматривается из процессов в других пространствах имен.

Итак, чтобы такие инструменты, как ps, работали правильно, нам нужно повторно смонтировать /proc, используя процесс в новом пространстве имен.

Но, предполагая, что ваш процесс находится в корневом пространстве имен монтирования, если мы повторно смонтируем /proc, это многое испортит для других процессов в том же пространстве имен монтирования, потому что теперь они ничего не видят (в /proc). Поэтому вы также должны поместить свой процесс в новое пространство имен монтирования.

Хорошо, что у отмены общего доступа есть --mount-proc.

--mount-proc[=mountpoint]
          Just before running the program, mount the proc filesystem at mountpoint (default is /proc). This is useful when creating a new PID namespace. It also implies creating a new mount namespace since the /proc mount would
          otherwise mess up existing programs on the system. The new proc filesystem is explicitly mounted as private (with MS_PRIVATE|MS_REC).

Давайте проверим, что --mount-proc также помещает ваш процесс в новое пространство имен монтирования.

удар снаружи:

wendel@gentoo-grill ~ λ ls -go /proc/$$/ns/{user,mnt,pid}
lrwxrwxrwx 1 0 Aug  9 10:05 /proc/17011/ns/mnt -> 'mnt:[4026531840]'
lrwxrwxrwx 1 0 Aug  9 10:10 /proc/17011/ns/pid -> 'pid:[4026531836]'
lrwxrwxrwx 1 0 Aug  9 10:10 /proc/17011/ns/user -> 'user:[4026531837]'

busybox:

wendel@gentoo-grill ~ λ doas ls -go /proc/16436/ns/{user,mnt,pid}
lrwxrwxrwx 1 0 Aug  9 10:05 /proc/16436/ns/mnt -> 'mnt:[4026533479]'
lrwxrwxrwx 1 0 Aug  9 10:04 /proc/16436/ns/pid -> 'pid:[4026533481]'
lrwxrwxrwx 1 0 Aug  9 10:17 /proc/16436/ns/user -> 'user:[4026531837]'

Обратите внимание, что их пространство имен пользователя такое же, но mount и pid разные.

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

Andrew Bolotov
9 августа 2021 в 10:58
0

Большое спасибо за ваш быстрый ответ! Это действительно помогает. Не могли бы вы прояснить для меня еще одну вещь. Почему я вижу из bash снаружи, что busybox все еще находится в том же пространстве имен pid, а выполнение ls -l /proc/$$/ns из busybox дает другой идентификатор пространства имен pid? Означает ли это, что я не могу видеть идентификаторы пространств имен pid контейнера с хоста?

200 not ok
9 августа 2021 в 21:15
0

@AndrewBolotov Извините, я не совсем понимаю ваш вопрос. Не могли бы вы перефразировать свой вопрос?

Andrew Bolotov
10 августа 2021 в 19:41
0

Спасибо, похоже, я указал неверный PID при проверке идентификатора пространства имен PID, и отсюда возникает путаница.