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
命令创建的命名空间。