1号航站楼:

1号航站楼:

unshare从我在和手册页中阅读的所有内容来看nsenter,我应该能够将目录绑定安装到其本身(mount --make-private目录),然后使用该目录中的文件来保存持久名称空间的引用。这就是我正在做的,基本上与 相同,man unshare但具有不同的目录,并且--pid=file除了--mount=file

1号航站楼:

# mkdir -p /mnt/jails/debian/bookworm/.ns
# mount --bind /mnt/jails/debian/bookworm/.ns /mnt/jails/debian/bookworm/.ns
# touch /mnt/jails/debian/bookworm/.ns/{mount,pid}
# mount --make-private /mnt/jails/debian/bookworm/.ns
# unshare --fork --mount-proc --mount=/mnt/jails/debian/bookworm/.ns/mount --pid=/mnt/jails/debian/bookworm/.ns/pid /bin/sh & echo $!; fg
[1] 151299
151299
sh-4.4# echo $$
1
sh-4.4# grep NS /proc/self/status
NStgid: 3
NSpid:  3
NSpgid: 3
NSsid:  0

到目前为止一切顺利,上面的容器正在工作。当它运行时:

2 号航站楼:

# nsenter  --mount=/mnt/jails/debian/bookworm/.ns/mount --pid=/mnt/jails/debian/bookworm/.ns/pid /bin/sh
sh-4.4# ps ax
Error, do this: mount -t proc proc /proc
# ls /proc/1/exe -l
lrwxrwxrwx. 1 root root 0 Jul 21 18:49 /proc/1/exe -> /usr/bin/bash
sh-4.4# mount -t proc proc /proc
sh-4.4# ps ax|head
<shows pids from the host OS, not from the container>
sh-4.4# grep NS /proc/self/status
NStgid: 156987
NSpid:  156987
NSpgid: 156987
NSsid:  156921

我也在终端 2 中尝试过此操作(注意来自终端 1 的 pid),结果完全相同:

# nsenter -t 151299 -a  /bin/sh
sh-4.4# ps ax
Error, do this: mount -t proc proc /proc
# ls /proc/1/exe -l
lrwxrwxrwx. 1 root root 0 Jul 21 18:49 /proc/1/exe -> /usr/bin/bash
sh-4.4# mount -t proc proc /proc
sh-4.4# ps ax|head
<shows pids from the host OS, not from the container>
sh-4.4# grep NS /proc/self/status
NStgid: 155356
NSpid:  155356
NSpgid: 155356
NSsid:  143538

由于某种原因nsenter进入主机操作系统的 pid 空间,但是它似乎确实看到了正确的 /proc 目录的命名空间,但它sh在 Terminal2 中无效,因为 pid 命名空间不起作用,所以(我认为)这就是为什么ps ax给出一个错误。我也尝试过使用和不使用 --mount-proc

问题:

如何从终端 1 输入 PID 命名空间?

我在这里做错了什么?

(主机 Linux 内核是 5.18,运行 Oracle Linux 8。)

答案1

util-linux v2.36 之前存在一个 bug,在此提交中已修复:

0d5260b66 unshare:修复 PID 和 TIME 命名空间持久性

使用包含补丁的 util-linux 版本!

这是一个测试脚本来验证您是否有此错误:

umount -l /mnt/jails/*/*/.ns/* /mnt/jails/*/*/.ns/
sleep 1

mkdir -p /mnt/jails/debian/bookworm/.ns
mount --bind /mnt/jails/debian/bookworm/.ns /mnt/jails/debian/bookworm/.ns
touch /mnt/jails/debian/bookworm/.ns/{mount,pid}
mount --make-private /mnt/jails/debian/bookworm/.ns

unshare --fork --mount-proc --mount=/mnt/jails/debian/bookworm/.ns/mount --pid=/mnt/jails/debian/bookworm/.ns/pid sleep 99 &
upid=$!

sleep 1

if nsenter --mount=/mnt/jails/debian/bookworm/.ns/mount --pid=/mnt/jails/debian/bookworm/.ns/pid [ -d /proc/self ]; then
    kill $upid
    echo worked
    exit 0
else
    kill $upid
    echo didnt
    exit 1
fi

答案2

首先,我对这个行业持怀疑态度:

...  /bin/sh & echo $!; fg

这似乎总是以 shell 退出和我的终端处于奇怪的状态结束。所以不要这样做;赶紧跑:

unshare --fork --mount-proc --mount=/mnt/jails/debian/bookworm/.ns/mount --pid=/mnt/jails/debian/bookworm/.ns/pid

现在你有一个 shell 在它自己的 mount 和 pid 命名空间中运行。


我也在终端 2 中尝试过此操作(注意来自终端 1 的 pid),结果完全相同:

我们讨论了这个别处;如果您停止处理进程 ID,您的生活将会变得更加简单,尤其是因为您已经努力创建持久名称空间。-t <pid>使用您创建的持久命名空间来代替:

# nsenter --mount=/mnt/jails/debian/bookworm/.ns/mount --pid=/mnt/jails/debian/bookworm/.ns/pid
# ps -fe
UID          PID    PPID  C STIME TTY          TIME CMD
root           1       0  0 16:45 pts/4    00:00:00 /bin/sh
root           3       0  1 16:48 pts/15   00:00:00 -bash
root          41       3  0 16:48 pts/15   00:00:00 ps -fe

正如您所看到的,我们已经成功进入了先前unshare命令创建的命名空间。

相关内容