ターミナル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

これまでは素晴らしかったです。上記のコンテナが動作しています。実行時:

NO2。ターミナル:

# 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認知ホストOSのpid空間に入るが/procディレクトリに対する正しいネームスペースは見えるようですが、shTerminal2ではpidネームスペースが動作していないので動作しないようですから(私の考えでは)そうです。なぜps axエラーが発生するのですか?私は--mount-procを使用したり使用したりせずに試しました。

質問:

ターミナル1でPID名前空間をどのように入力しますか?

私がここで何を間違っているのか?

(ホストLinuxカーネルは5.18で、Oracle Linux 8を実行します。)

答え1

util-linux v2.36より前にはバグがありましたが、このコミットで修正されました。

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

これは常にシェルが終了し、端末が奇妙な状態で終わるようです。だから逃げないでください。

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

これで、独自のマウントと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前のコマンドで生成された名前空間を正常に入力しました。

関連情報