728x90




네임스페이스(namespace)란?


하나의 시스템에서 수행되지만, 각각 별개의 독립된 공간인 것처럼 격리된 환경을 제공하는 경량 프로세스 가상화 기술

- 경량 프로세스는 부모 프로세스와 자원을 공유하는 프로세스를 의미


LXC의 네임스페이스는 6 종류와 플래그

- 마운트 네임스페이스 : CLONE_NEWNS

- UTS 네임스페이스 : CLONE_NEWUTS

- IPC 네임스페이스 : CLONE_NEWIPC

- PID 네임스페이스 : CLONE_NEWPID

- 사용자 네임스페이스 : CLONE_NEWUSER

- 네트워크 네임스페이스 : CLONE_NEWNET


네임스페이스 사용 시 위의 6개의 상수 플래그를 clone(), unshare(), setns() 시스템 콜에 전달하여 수행

- clone() : 새로운 프로세스를 생성하고 이를 새로 지정된 네임스페이스에 연결

- unshare() : 현재 프로세스를 새로 지정된 네임스페이스에 연결

- setns() : 이미 존재하는 네임스페이스에 프로세스를 연결


상수 플래그는 "/usr/include/linux/sched.h" 에 지정되어 있음




마운트(mount) 네임스페이스란?


프로세스와 그 자식 프로세스가 각기 다른 파일시스템 마운트 지점을 제공


기본적으로 모든 프로세스는 동일한 기본 네임스페이스를 공유하기 때문에, 파일 시스템을 마운트하거나 마운트를 해제하는 등의 변경을 모든 프로세스가 인지할 수 있음


만약 clone() 시스템 콜을 통해 프로세스를 생성할 때 CLONE_NEWNS 플래그가 전달되면, 새로 생성되는 프로세스는 호출한 프로세스가 갖고있는 마운트 트리의 사본을 가져옴


이 사본은 부모 프로세스에 영향을 미치지 않고 새로 생성된 프로세스가 파일시스템을 마운트 or 언마운트 등의 변경을 할 수 있도록 함


이 시점부터 기본 네임스페이스의 모든 파일시스템 마운트 및 언마운트는 새로운 네임스페이스에서 볼 수 있지만, 각각의 프로세스 별 마운트 네임스페이스 내부에서의 변경을 해당 프로세스의 네임스페이스 밖에서는 알 수 없음




마운트 네임스페이스 생성 (코드)


clone()을 이용한 마운트 네임스페이스 생성 예제


#define _GNU_SOURCE
#include <sched.h>

static int childFunc(void *arg) {
        //새로 생성된 마운트 네임스페이스에서 동작할 기능 추가
        //마운트 디렉토리 확인 등
}

int main() {
        pid_t child_pid;

        child_pid = clone(childFunc, child_stack + STACK_SIZE, CLONE_NEWNS | SIGCHLD, argv[1]);

        //기본 네임스페이스에서 동작할 기능 추가
        //마운트 디렉토리 확인 등

        waitpid(child_pid, NULL, 0);
        exit(EXIT_SUCCESS);
}




마운트 네임스페이스 생성 (unshare 유틸리티)


마운트 할 디렉토리(/tmp/mount_ns) 생성


$ mkdir /tmp/mount_ns



mount 플래그를 unshared 시스템 콜에 전달

- 현재 bash 프로세스를 자체 마운트 네임스페이스로 이동

- "-m"옵션 -> 마운트 네임스페이스


$ unshare -m /bin/bash


readlink 명령을 이용해 네임스페이스의 관련 inode 번호 확인

- unshare 명령을 통해 bash 프로세스가 별도의 네임스페이스에 존재

- /proc/$$ 는 현재 bash 쉘의 프로세스 ID(PID)


$ readlink /proc/$$/ns/mnt
mnt:[4026532211]


임시 마운트 지점을 만들어 /tmp/mount_ns에 마운트


$ mount -n -t tmpfs tmpfs /tmp/mount_ns


새로 만든 네임스페이스에서 마운트 지점 확인

- 마운트 지점은 새로 생성한 네임스페이스의 일부
- 현재 bash 프로세스는 우리가 생성한 네임스페이스로부터 실행되었기 때문에 해당 마운트 지점 확인 가능


$ df -h | grep mount_ns
tmpfs          3.9G      0  3.9G   0%  /tmp/mount_ns
$ cat /proc/mounts | grep mount_ns
tmpfs  /tmp/mount_ns  tmpfs rw,relatime 0 0


새로운 터미널 세션을 열고, 네임스페이스 inode ID 확인


$ readlink /proc/$$/ns/mnt
mnt:[4026531840]
- 앞에서 한 다른 터미널의 마운트 네임스페이스와 inode ID가 다름


4단계에서 마운트한 마운트 지점이 새 터미널에 표시되는지 확인

$ df -h | grep mount_ns
$
$ cat /proc/mounts | grep mount_ns
$

- 새로운 터미널은 기본 네임스페이스

- 기본 네임스페이스에서는 마운트 지점이 보이지 않음




마운트 지점이 격리되어있음을 확인 가능


▪그러므로 마운트 네임스페이스를 이용해 컨테이너 내부에 각기 다른 파일시스템 레이아웃이 존재 가능


















728x90