루트 액세스 권한이 있는 Debian jessie 서버를 사용하여 Linux 네임스페이스를 이해하려고 합니다.
다음 C 코드를 고려해보세요.
# /tmp/test.c
#define _GNU_SOURCE
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
static char child_stack[1048576];
static int my_child() {
system("/bin/bash");
}
int main() {
pid_t child_pid = clone(my_child, child_stack+1048576,
CLONE_NEWPID | CLONE_NEWNS | SIGCHLD, NULL);
waitpid(child_pid, NULL, 0);
return 0;
}
다음으로 단일 터미널의 단일 세션에서 다음 명령을 실행합니다.
/tmp# id
uid=0(root) gid=0(root) groups=0(root),1093867019
/tmp# echo $$
1804
/tmp# ps -eaf | head
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 May08 ? 00:00:01 /sbin/init
root 2 0 0 May08 ? 00:00:00 [kthreadd]
root 3 2 0 May08 ? 00:00:00 [ksoftirqd/0]
root 5 2 0 May08 ? 00:00:00 [kworker/0:0H]
root 7 2 0 May08 ? 00:00:11 [rcu_sched]
root 8 2 0 May08 ? 00:00:00 [rcu_bh]
root 9 2 0 May08 ? 00:00:00 [migration/0]
root 10 2 0 May08 ? 00:00:00 [watchdog/0]
root 11 2 0 May08 ? 00:00:00 [khelper]
/tmp# grep /proc /proc/$$/mountinfo
15 19 0:3 / /proc rw,nosuid,nodev,noexec,relatime shared:12 - proc proc rw
33 15 0:29 / /proc/sys/fs/binfmt_misc rw,relatime shared:20 - autofs systemd-1 rw,fd=22,pgrp=1,timeout=300,minproto=5,maxproto=5,direct
/tmp# gcc test.c
/tmp# ./a.out
/tmp# echo $$
2
/tmp# echo $PPID
1
/tmp# ps -eaf | head
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 May08 ? 00:00:01 /sbin/init
root 2 0 0 May08 ? 00:00:00 [kthreadd]
root 3 2 0 May08 ? 00:00:00 [ksoftirqd/0]
root 5 2 0 May08 ? 00:00:00 [kworker/0:0H]
root 7 2 0 May08 ? 00:00:11 [rcu_sched]
root 8 2 0 May08 ? 00:00:00 [rcu_bh]
root 9 2 0 May08 ? 00:00:00 [migration/0]
root 10 2 0 May08 ? 00:00:00 [watchdog/0]
root 11 2 0 May08 ? 00:00:00 [khelper]
tmp# grep /proc /proc/$$/mountinfo
15 19 0:3 / /proc rw,nosuid,nodev,noexec,relatime shared:12 - proc proc rw
33 15 0:29 / /proc/sys/fs/binfmt_misc rw,relatime shared:20 - autofs systemd-1 rw,fd=22,pgrp=0,timeout=300,minproto=5,maxproto=5,direct
/tmp# mount -t proc proc /proc
/tmp# grep /proc /proc/$$/mountinfo
92 70 0:3 / /proc rw,nosuid,nodev,noexec,relatime shared:12 - proc proc rw
93 92 0:29 / /proc/sys/fs/binfmt_misc rw,relatime shared:20 - autofs systemd-1 rw,fd=22,pgrp=0,timeout=300,minproto=5,maxproto=5,direct
97 92 0:34 / /proc rw,relatime shared:27 - proc proc rw
/tmp# ps -eaf
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 07:31 pts/0 00:00:00 ./a.out
root 2 1 0 07:31 pts/0 00:00:00 /bin/bash
root 14 2 0 07:31 pts/0 00:00:00 ps -eaf
/tmp# exit
exit
/tmp# echo $$
1804
/tmp# grep /proc /proc/$$/mountinfo
grep: /proc/1804/mountinfo: No such file or directory
/tmp# ps -eaf
Error, do this: mount -t proc proc /proc
/tmp# mount -t proc proc /proc
/tmp# grep /proc /proc/$$/mountinfo
15 19 0:3 / /proc rw,nosuid,nodev,noexec,relatime shared:12 - proc proc rw
33 15 0:29 / /proc/sys/fs/binfmt_misc rw,relatime shared:20 - autofs systemd-1 rw,fd=22,pgrp=1,timeout=300,minproto=5,maxproto=5,direct
98 15 0:34 / /proc rw,relatime shared:27 - proc proc rw
69 98 0:3 / /proc rw,relatime shared:28 - proc proc rw
종료 후 하위 프로세스가 /proc
마운트되지 않는 이유는 무엇입니까? 하위 프로세스에서 마운트 지점을 변경하면 상위 프로세스의 마운트 지점에 영향을 미쳐서는 안 됩니까? 이는 질문에 대한 Emmett의 답변과 모순되는 것 같습니다.https://stackoverflow.com/questions/22889241/linux-understanding-the-mount-namespace-clone-clone-newns-flag.
답변1
clone
이 플래그를 사용하여 하위 프로세스가 생성되면 CLONE_NEWNS
하위 프로세스는 자체 마운트 네임스페이스를 얻습니다. 하위 네임스페이스의 마운트 작업( mount
, umount
등 ) mount --bind
은 해당 네임스페이스 내에서만 유효하지만 상위 네임스페이스의 마운트 작업은 새 네임스페이스 외부에서만 유효합니다.
공유 설치는 예외입니다. 마운트는 다음과 같습니다.공유됨, 이 경우 작업은 공유에 마운트된 모든 네임스페이스에 영향을 미칩니다. 공유 마운트의 일반적인 사용 사례는 하위 네임스페이스(예: chroot)에서 이동식 드라이브를 사용할 수 있도록 만드는 것입니다. 더 많은 관계 유형(비공개 마운트, 바인딩할 수 없는 마운트)을 참조하세요.커널 문서.
다음을 확인하여 마운트가 공유되는지 확인할 수 있습니다. 행에 포함되어 있으면 마운트가 공유되고 해당 숫자는 공유되는 네임스페이스 집합을 식별하는 고유한 값입니다. 행에 그러한 표시가 없으면 설치는 비공개입니다./proc/PID/mountinfo
shared:NUMBER
귀하의 시스템에서는 /proc
공유됩니다. 자식 네임스페이스에 proc의 새 인스턴스를 마운트하면 부모 네임스페이스에 마운트되므로 /proc
새 인스턴스도 공유되므로 자식 네임스페이스와 부모 네임스페이스 모두에서 볼 수 있습니다. 하위 네임스페이스를 종료하면 두 번째 인스턴스는 /proc
여전히 활성 상태인 상위 네임스페이스와 공유되므로 마운트된 상태로 유지됩니다.
시나리오를 복잡하게 만드는 두 가지 사항은 PID 네임스페이스를 만들고 /proc
실험 대상과 관찰 수단으로 모두 사용한다는 것입니다. 설치하지 않았다고 ps
불평 하면 /proc
실제로 잘못된 오류 메시지가 표시됩니다.잘못된 proc
설치됨(a는 proc
잘못된 네임스페이스를 나타냄) ls /proc
및 를 사용하여 이를 관찰 할 수 있습니다 cat /proc/1/mountinfo
. 임시 파일 시스템을 실험해 보는 것이 좋습니다. 그러면 무슨 일이 일어나고 있는지 이해하는 것이 더 쉬울 것입니다.
부모# ./a.out 아이들 #echo$$ 2 하위 # ls /proc 이것은 부모의 proc입니다. /proc/PID는 부모 PID 네임스페이스에 있습니다. 아이 # ps 1 … 내부에 하위 # mount -t proc proc /proc 하위 마운트 네임스페이스의 /proc가 이제 하위 PID 네임스페이스에 사용됩니다. 아이 # ps 1 ...a. 출력 아이 #퇴장 아버지#
지금까지는 비공개인지 공유인지는 중요하지 않았지만 /proc
이제는 중요합니다. 비공개 인 경우 이 시점에서 영향을 받은 적이 없으며 PID 네임스페이스를 표시하는 /proc
상위 항목을 살펴봅니다 . /proc
그러나 /proc
공유되는 경우 mount
이전에 실행한 명령은 두 네임스페이스 모두에 영향을 미치므로 다음과 같습니다.
상위 번호 ls /proc ACPI 사운드 버디인포 ... 상위 번호 ps 1 오류가 발생했습니다. 다음을 수행하십시오: mount -t proc proc /proc 실제로 /proc가 마운트되어 있지만 이는 이전에 생성한 PID 네임스페이스의 proc이며 현재 실행 중인 프로세스가 없습니다. 상위 # grep -c ' /proc ' /proc/mounts 2 상위#제거/proc 상위 네임스페이스 /proc의 하위 PID 네임스페이스를 숨긴 /proc를 마운트 해제했으므로 "정상" /proc가 다시 표시됩니다. 상위 번호 ps 1 … 내부에