설치하다

설치하다

저는 Linux 컨테이너의 내부 작동 방식을 이해하려고 노력하고 있습니다. 제가 배운 한 가지는 특수 플래그를 전달하여 셸을 컨테이너화할 수 있다는 것입니다. 플래그 중 하나는 PID용입니다.

ps그러나 이는 여전히 호스트와 컨테이너의 모든 프로세스를 표시하므로 명령에 원하는 효과를 제공하지 않습니다 . 이는 ps디렉토리에서 읽기 때문일 수 있습니다 ./proc

컨테이너에서 실행 중인 프로세스만 표시하는 방법 중 하나 ps는 가짜 루트 파일 시스템(운영 체제의 디렉터리/유틸리티만 포함)으로 루트를 지정한 다음 /proc호스트 디렉터리를 가짜 fs의 proc 디렉터리에 마운트하는 것입니다.

나는 이것이 실제로 왜 작동하는지 이해하지 못합니다. /proc디렉토리를 다른 마운트 지점에 마운트하면 컨테이너화된 것처럼 동작하는 이유는 무엇입니까 ?

Docker와 같은 컨테이너가 제대로 작동하려면 가짜 루트 파일 시스템이 필요한 이유는 무엇입니까?

내가 뭐 놓친 거 없니?

제가 설명하는 기술은이 비디오DockerCon에서.

메서드가 완료되는 정확한 시간에 대한 링크를 설정했습니다.

답변1

해당 unshare명령에 대해 이야기하고 있다고 가정하면, 해결책은 --mount-proc마운트 네임스페이스를 공유 해제하고 /proc새 pid 네임스페이스를 참조하는 새 네임스페이스를 마운트하는 옵션을 사용하는 것입니다. pid_namespaces(7)매뉴얼 페이지를 참조하십시오 :

/proc 및 PID 네임스페이스

/proc 파일 시스템(/proc/[pid] 디렉터리에 있음)은 /proc 파일 시스템이 다른 네임스페이스의 프로세스에서 표시되는 경우에도 마운트를 수행하는 프로세스의 PID 네임스페이스에 표시되는 프로세스에만 표시됩니다.

새 PID 네임스페이스를 만든 후 자식이 루트 디렉터리를 변경하고 /proc에 새 procfs 인스턴스를 마운트하면 ps(1)와 같은 도구가 제대로 작동할 수 있도록 하는 것이 유용합니다.

clone(2) 또는 unshare(2)에 대한 플래그 인수에 CLONE_NEWNS를 포함하여 새 마운트 네임스페이스를 동시에 생성하는 경우 루트 디렉터리를 변경할 필요가 없습니다. 새 procfs 인스턴스는 /proc에 직접 마운트될 수 있습니다.

셸에서 /proc를 마운트하는 명령은 다음과 같습니다.

$ mount -t proc proc /proc

/proc/self 경로에서 readlink(2)를 호출하면 procfs에 의해 마운트된 PID 네임스페이스(즉, procfs를 마운트하는 프로세스의 PID 네임스페이스)에 호출자의 프로세스 ID가 생성됩니다. 이는 프로세스가 다른 네임스페이스에서 해당 PID를 검색하려고 할 때 자체 검사 목적으로 유용합니다.

$ sudo unshare -p   -f ps -o pid,ppid,pidns,mntns,comm
  PID  PPID      PIDNS      MNTNS COMMAND
27462 24107 4026531836 4026531840 sudo
27463 27462 4026531836 4026531840 unshare
27464 27463 4026532863 4026531840 ps
$ sudo unshare -p --mount-proc  -f ps -o pid,ppid,pidns,mntns,comm
  PID  PPID      PIDNS      MNTNS COMMAND
    1     0 4026532864 4026532863 ps

unsharedocker와 같은 네임스페이스에 액세스하기 위한 래퍼 및 시스템 호출을 위한 저수준 유틸리티입니다 nsenter.unshare(2)setns(2)

strace무슨 일이 일어나는지 그들에게 알려줄 수 있습니다 . 두 번째에서는:

  1. mnt 및 pid 네임스페이스 공유를 해제합니다.

    5281  unshare(CLONE_NEWNS|CLONE_NEWPID) = 0
    
  2. 아이를 포크하다 (왜냐하면 -f)

    5281  clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f6b0af4a7d0) = 5282
    

    물려받은 아이공유되지 않음네임스페이스

  3. 마운트가 상위 네임스페이스나 하위 네임스페이스 모두에 전파되지 않도록 새 mnt 네임스페이스에서 마운트 전파를 비활성화합니다.

    5282  mount("none", "/", NULL, MS_REC|MS_PRIVATE, NULL) = 0
    5282  mount("none", "/proc", NULL, MS_REC|MS_PRIVATE, NULL) = 0
    
  4. 내부에 새 pid 네임스페이스에 대한 새 proc을 마운트합니다 /proc(왜냐하면 ps그것이 발견될 것으로 예상되는 위치이고 우리가 mnt 네임스페이스를 만든 이유이기 때문입니다). 또 다른 옵션은 일부 바인드 마운트 및 를 사용하는 것입니다 chroot. fs는 pid 네임스페이스를 proc상위 mnt 네임스페이스에 마운트할 수도 있지만 그렇게 하면 큰 문제가 발생할 수 있습니다.

    5282  mount("proc", "/proc", "proc", MS_NOSUID|MS_NODEV|MS_NOEXEC, NULL) = 0
    
  5. ps이 네임스페이스에서 실행

    5282  execve("/bin/ps", ["ps", "-o", "pid,ppid,pidns,mntns,comm"], 0x7fff5a325dd8 /* 73 vars */) = 0
    

답변2

방금 영상을 봤습니다. 그녀는 proc 유형을 /proc로 마운트했고 가능한 한 많이 표시했습니다(다른 프로세스 네임스페이스에 있었습니다). 호스트를 볼 수 있지만 /proc프로세스 네임스페이스에 누수가 있습니다.

상황이 뒤섞여 있습니다. 다양한 네임스페이스가 있습니다. 비디오에는 호스트 이름 네임스페이스(그녀는 그다지 주의를 기울이지 않았음), 프로세스 네임스페이스 및 파일 시스템 네임스페이스(chroot를 통해)가 나와 있습니다. 파일 시스템과 프로세스 네임스페이스를 혼합하고 있습니다. 아마도 ps파일 시스템( /proc)을 사용하고 있지만 프로세스 네임스페이스를 사용하기를 원하기 때문일 수 있습니다. proc은 프로세스 네임스페이스를 사용하므로 새 proc이 생성되면 새 네임스페이스에 있게 됩니다.

설치하다

설치는 재설치가 아닙니다(재설치 옵션 없음).

여러 개의 프로세스를 가질 수 있나요? 시도 해봐. 예, 하지만 다른 곳에서는 ps가 이를 사용합니다 /proc. 심지어 치트를 위해 정적 파일로 대체할 수도 있습니다 . 그러나 파일, 디렉토리 또는 특수 파일(chroot를 수행하지 않는 한)은 ps하나만 존재할 수 있습니다./proc

커널이 모든 procs를 쓰는지 여부

아니요, 커널은 동시에 두 위치에 쓰지 않습니다(쓸 내용이 없습니다(디스크 공간이 아님)). proc에서 읽을 때 커널은 적절한 데이터를 생성합니다(사용하는 네임스페이스에 따라 다름). re in) 한 번에 하나만 읽을 수 있으므로 한 번에 하나만 만들 수 있고 필요한 만큼만 읽을 수 있습니다(파일 1개만).

Linux의 어떤 네임스페이스가 어떤 파일 시스템에 해당하는지에 대한 문서가 있습니까?

ls이는 네임스페이스가 어느 네임스페이스에 있는지 묻는 것과 같습니다 . 그렇지는 않지만 네임스페이스의 영향을 받습니다. 따라서 proc은 현재 프로세스 네임스페이스 내의 프로세스에 대해서만 알 수 있습니다. proc의 다른 부분은 다른 네임스페이스 유형의 영향을 받을 수 있습니다(해당 기능에 따라 다름).

관련 정보