1. Namespace

Namespace 기술은 cgourp(Control Group)과 함께 컨테이너(Container) 솔루션을 구성하는 기술 중 하나입니다. 이번 글에서는 namespcae에 대해 정리한 후linux에서 제공하는 namespcae의 종류에 대해 정리하고자 합니다.

namespace는 전역 시스템 리소스를 추상화하여 전역 리소스의 자체 격리 인스턴스가있는 namespace 내의 프로세스에 표시 되도록합니다. 전역 리소스에 대한 변경은 namespace의 멤버, 즉 동일한 namespace를 가진 다른 프로세스에서 볼 수 있지만 다른 namespace를 가진 프로세스에서는 보이지 않습니다. namespcae를 사용하는 것은 컨테이너를 구현하는 것입니다.

Namespace Constant Isolates
IPC CLONE_NEWIPC System V IPC, POSIX message queues
Network CLONE_NEWNET Network devices, stacks, ports, etc.
Mount CLONE_NEWNS Mount points
PID CLONE_NEWPID Process IDs
User CLONE_NEWUSER User and group IDs
UTS CLONE_NEWUTS Hostname and NIS domain name

namespace API

namespace API에는 아래의 시스템 콜과 함께 /proc 파일이 포함됩니다. 먼저 system call에 대해 설명드립니다.

시스템 콜

API Description
setns(2) setns 시스템 콜은 호출하는 프로세스가 존재하는 namespace에 조인합니다. 조인하고자 하는 namespace는 /proc/[pid]/ns 디렉토리 아래 존재하는 하나의 namespace 파일디스크립터(fd) 를 이용합니다.
clone(2) clone(2) 시스템 콜은 새로운 프로세스를 생성합니다. 시스템 콜 호출 시 flags argument로 CLONE_NEW* flag를 하나 이상 전달합니다. CLONE_NEW* flag는 위에서 설명한 바 있습니다. 그럼 각 flag에 해당하는 새로운 namespace가 생성되며 그 namepsaces의 멤버로 자식 프로세스가 생성됩니다.
unshare(2) unshare() 시스템 콜을 호출한 프로세스를 새로운 namespace로 이동시킵니다. 만약 flags argutment가 CLONE_NEW* flag를 입력한다면, 새로운 namespace가 생성되고, 해당 namespace의 멤버로 이동합니다.

여기서 유의할 점은 clone(2) 와 unshare(2) 시스템 콜을 사용하여 새로운 namespace들을 생성하기 위해선 CAP_SYS_ADMIN capability가 필요합니다. user namespace 생성은 예외적으로 privilege가 필요하지 않습니다.

/proc/[pid]/ns 디렉토리

그럼 /proc 파일시스템에서 namespace에 대해 간략히 정리하겠습니다. 모든 프로세스들은 /proc/[pid]/ns 디렉토리가 존재합니다. 아래 ns 디렉토리에 여러 namespace가 존재하는 것을 확인할 수 있습니다. 이 namespace는 setns(2) 시스템 콜을 이용해 namespace를 변경하고자 할 때 변경을 원하는 namespace의 fd로 사용됩니다.

$ ls -l /proc/$$/ns
total 0
lrwxrwxrwx. 1 mtk mtk 0 Jan 14 01:20 ipc -> ipc:[4026531839]
lrwxrwxrwx. 1 mtk mtk 0 Jan 14 01:20 mnt -> mnt:[4026531840]
lrwxrwxrwx. 1 mtk mtk 0 Jan 14 01:20 net -> net:[4026531956]
lrwxrwxrwx. 1 mtk mtk 0 Jan 14 01:20 pid -> pid:[4026531836]
lrwxrwxrwx. 1 mtk mtk 0 Jan 14 01:20 user -> user:[4026531837]
lrwxrwxrwx. 1 mtk mtk 0 Jan 14 01:20 uts -> uts:[4026531838]

각 namespace 별 proc 파일은 다음과 같습니다.

namespace /proc file
IPC namespace /proc/[pid]/ns/ipc
Mount namespace /proc/[pid]/ns/mount
Network namespace /proc/[pid]/ns/net
PID namespace /proc/[pid]/ns/pid
User namespace /proc/[pid]/ns/user
uts namespace /proc/[pid]/ns/uts

Namespace 간략 정리

각 Namespace의 상세내용은 다른 글로 정리하고자 하며, 여기서는 간략하게 정리하고자 합니다.

IPC namespace (CLONE_NEWIPC)

IPC namespace는 특정 IPC 자원들(System V IPC,와 POSIX message queue)을 격리시킵니다. 특정 IPC 자원들의 공통적인 특징은 IPC 객체가 파일시스템 경로명 외의 메커니즘으로 식별된다는 것입니다. System V IPC에는 메시지 큐, 세마포어, 공유메모리를 가리킵니다.

Network namespace (CLONE_NEWNET)

Network namespace는 네트워크와 관련된 시스템 자원의 격리, 고립을 제공합니다. 해당되는 시스템 자원으로는 네트워크 디바이스들, IPv4, IPv6 프로토콜 스택, IP routing tables, 방화벽, /proc/net 디렉토리, /sys/class/net 디렉토리, 포트 번호 등등이 있습니다. 물리적 네트워크 장치는 정확히 하나의 네트워크 네임스페이스를 가질 수 있습니다. 가상 네트워크 장치는 네트워크 namespace 간에 터널을 생성하는데 사용할 수 있는 추상화된 파이프를 제공합니다.

Network namespace가 해제되면, 물리 네트워크 장치는 초기 Network namespace로 변경됩니다. Network namespace를 사용하기 위해선 CONFIG_NET_NS 커널 옵션이 설정되어 있어야 합니다.

Mount namespaces (CLONE_NEWNS)

Mount namespace는 파일시스템 마운트 지점의 집합을 고립, 격리합니다. 즉, 서로 다른 Mount namespace의 프로세스가 파일 시스템 구조에 대해 다른 뷰를 가질 수 있습니다. mount(2), umount(2) 를 이용해 Mount namespace 내에 마운트 집합들을 수정할 수 있습니다.

/proc/[pid]/mounts 파일은 현재 프로세스의 Mount namespace에 마운트된 모든 파일시스템을 나열합니다. 이 파일의 포맷은 **fstab(5)**를 참고해주세요.

seunghason@linuxias$cat /proc/self/mounts
sysfs /sys sysfs rw,nosuid,nodev,noexec,relatime 0 0
proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0
udev /dev devtmpfs rw,nosuid,relatime,size=16413672k,nr_inodes=4103418,mode=755 0 0

...

binfmt_misc /proc/sys/fs/binfmt_misc binfmt_misc rw,relatime 0 0
tmpfs /run/user/1000 tmpfs rw,nosuid,nodev,relatime,size=3288548k,mode=700,uid=1000,gid=1000 0 0
gvfsd-fuse /run/user/1000/gvfs fuse.gvfsd-fuse rw,nosuid,nodev,relatime,user_id=1000,group_id=1000 0 0

/proc/[pid]/mountstat 파일은 프로세스의 Mount namespace의 마운트 지점에 대한 정적, 설정 정보들을 보여줍니다. 보여지는 정보에 대한 것은 아래를 참고해주세요.

device /dev/sda7 mounted on /home with fstype ext3 [statistics]
(       1      )            ( 2 )             (3 ) (4)
The fields in each line are:
(1)  The name of the mounted device (or "nodevice" if there is no corresponding device).
(2)  The mount point within the filesystem tree.
(3)  The filesystem type.
(4)  Optional statistics and configuration information.
     Currently (as at Linux 2.6.26), only NFS filesystems export information via this field.

PID namespace

PID namespace는 프로세스 ID 공간을 격리 시킵니다. 이 말인 즉, 다른 PID namespace의 프로세스들은 같은 PID를 가질 수도 있음을 의미합니다. PID namespace들은 프로세스 집합의 종료, 재시작과 같은 기능을 제공하기 위한 컨테이너를 허용합니다. 또한 컨테이너를 새로운 호스트로 마이그레이션하는 등의 기능을 컨테이너가 제공할 수 있도록 해줍니다.

PID namepsace의 특이한 점은 새로운 PID namespace의 PID는 1 부터 시작한다는 것입니다. standalone 시스템과 동일하게 각 namespace의 시작 프로세스는 pid를 1번을 가지게됩니다.

PID namespace를 사용하기 위해선 CONFIG_PID_NS 커널 옵션을 설정해야 합니다.

User namespace

User namespace는 시큐리티와 관련된 식별자 및 속성을 분리하며, 특히 User ID와 Group ID, 루트 디렉토리, Key, Capability를 분리합니다. 프로세스의 User, Group ID는 user namespace 내,외부적으로 다를수 있습니다. 특히 프로세스는 User namespace 외부에 권한이 없는 정상적인 User ID를 가질 수 있으며, 동시에 namepsace 내부에 User ID 0을 가질 수 있습니다. 즉, 프로세스에는 user namespace 내의 작업에 대한 전체 권한이 있지만 namespace 외부 작업에 대한 권한이 없습니다. 자세한 내용은 다른 글로 살펴보겠습니다.

UTS namespace

UTS namespace는 두개의 시스템 식별자를 고립, 격리시킵니다. 두 개의 시스템 식별자는 hostname과 NIS domain name입니다. 이 식별자들은 sethostname(2), **setdomainname(2)**으로 설정가능합니다. UTS namespace의 사용은 CONFIG_UTS_NS 커널 옵션을 설정해야 합니다.

이상으로 Namespace에 대해 간단히 정리해보았습니다. 다음 글에서 각 namespace의 사용 및 예제에 대해 다뤄보겠습니다.

감사합니다.

감사합니다.