리눅스 네임스페이스(Linux Namespace)란?
리눅스 네임스페이스란?
리눅스 네임스페이스는 프로세스를 실행할 때 시스템의 리소스를 분리해서 실행할 수 있도록 도와주는 기능입니다. 한 시스템의 프로세스들은 기본적으로 시스템의 리소스들을 공유해서 실행됩니다. 이를 단일 네임스페이스라고 생각해볼 수 있습니다. 실제로 리눅스에서는 1번 프로세스(init)에 할당되어있는 네임스페이스들을 자식 프로세스들이 모두 공유해서 사용하는 구조로 이루어져있습니다.
/prod/<PID>/ns
디렉터리에서 현재 프로세스에서 사용하고 있는 네임스페이스의 고유 ID를 확인하는 것이 가능합니다.
$ ls -al /proc/1/ns
total 0
dr-x--x--x 2 root root 0 Jan 31 03:47 .
dr-xr-xr-x 9 root root 0 Jan 24 14:46 ..
lrwxrwxrwx 1 root root 0 Jan 31 03:47 cgroup -> 'cgroup:[4026531835]'
lrwxrwxrwx 1 root root 0 Jan 31 03:47 ipc -> 'ipc:[4026531839]'
lrwxrwxrwx 1 root root 0 Jan 31 03:47 mnt -> 'mnt:[4026531840]'
lrwxrwxrwx 1 root root 0 Jan 31 03:47 net -> 'net:[4026531993]'
lrwxrwxrwx 1 root root 0 Jan 31 03:47 pid -> 'pid:[4026531836]'
lrwxrwxrwx 1 root root 0 Jan 31 03:47 pid_for_children -> 'pid:[4026531836]'
lrwxrwxrwx 1 root root 0 Jan 31 03:47 user -> 'user:[4026531837]'
lrwxrwxrwx 1 root root 0 Jan 31 03:47 uts -> 'uts:[4026531838]'
여러가지 파일이 보입니다만 각각의 파일은 리소스 별 네임스페이스를 의미합니다. 현재 리눅스에서 지원하는 네임스페이스는 크게 보면 다음과 같습니다.
- Cgroup 네임스페이스(cgorup)
- IPC 네임스페이스(ipc)
- 네트워크 네임스페이스(network)
- 마운트 네임스페이스(mnt)
- PID 네임스페이스(pid)
- UTS 네임스페이스(user)
- 사용자 네임스페이스(uts)
- 시간 네임스페이스(time)
리눅스에서는 프로세스를 실행할 때 각 네임스페이스 별로 분리해서 실행하는 것이 가능합니다만, 앞에서 설명한대로 기본적으로는 1번 프로세스의 네임스페이스를 공유해서 실행됩니다. 위의 출력 결과 오른편의 4026...
으로 시작한 값이 각 네임스페이스 별 고유 아이디입니다. 아무거나 다른 프로세스의 네임스페이스를 확인해보겠습니다.
$ ls -l /proc/1074/ns
total 0
lrwxrwxrwx 1 root root 0 Jan 31 04:08 cgroup -> 'cgroup:[4026531835]'
lrwxrwxrwx 1 root root 0 Jan 31 04:08 ipc -> 'ipc:[4026531839]'
lrwxrwxrwx 1 root root 0 Jan 31 04:08 mnt -> 'mnt:[4026531840]'
lrwxrwxrwx 1 root root 0 Jan 31 04:08 net -> 'net:[4026531993]'
lrwxrwxrwx 1 root root 0 Jan 31 04:08 pid -> 'pid:[4026531836]'
lrwxrwxrwx 1 root root 0 Jan 31 04:08 pid_for_children -> 'pid:[4026531836]'
lrwxrwxrwx 1 root root 0 Jan 31 04:08 user -> 'user:[4026531837]'
lrwxrwxrwx 1 root root 0 Jan 31 04:08 uts -> 'uts:[4026531838]'
눈으로 비교해봐도 알 수 있지만, 네임스페이스 고유값들이 1번 프로세스와 같은 것을 알 수 있습니다. diff
를 사용해서 확인해보겠습니다.
$ diff <(ls -Al /proc/1/ns | awk '{ print $11 }') \
<(ls -Al /proc/1074/ns | awk '{ print $11 }')
출력결과가 같기 때문에 아무 내용도 출력되지 않습니다.
일반적인 경우 리눅스 네임스페이스를 직접 활용하는 경우는 많지 않습니다만, 네트워크 테스트나 컨테이너 구현에서 활용됩니다. 리눅스 컨테이너는 리눅스 네임스페이스와 루트 파일 시스템 격리 등 리눅스의 다양한 기능을 사용해 격리시킨 프로세스를 의미합니다. 더 자세한 내용은 아래 글을 참고해주세요.

컨테이너란? 리눅스의 프로세스 격리 기능
네임스페이스의 종류
PID 네임스페이스
PID 네임스페이스는 프로세스의 ID를 격리할 수 있는 네임스페이스입니다. 리눅스에서 PID는 init 프로세스 1을 시작하며 그 외에 모든 프로세스는 항상 1보다 큰 PID를 부여받습니다. PID 네임스페이스를 분리하면 PID가 다시 1부터 시작합니다. 단, 이 프로세스는 디폴트 네임스페이스와 분리된 PID 네임스페이스에 동시에 속하게 되며, 분리된 새로운 네임스페이스에서는 PID가 1부터 시작하지만, 디폴트 네임스페이스 관점에서는 1보다 큰 어떤 값을 PID로 가지게 됩니다. PID 네임스페이스에 대한 더 자세한 내용은 아래 글을 참고해주세요.

도커(Docker) 컨테이너는 가상 머신인가요? 프로세스인가요?
네트워크 네임스페이스
네트워크 네임스페이스는 프로세스의 네트워크 환경을 분리할 수 있는 네임스페이스입니다. 네트워크 환경을 분리하면 네임스페이스에 속한 프로세스들에 새로운 IP를 부여하거나 네트워크 인터페이스를 추가하는 것이 가능합니다. 네트워크 네임스페이스는 ip
명령어로 조작할 수 있으며 기본적인 사용법에 대해서는 다음 글에서 다루고 있습니다.

ip로 직접 만들어보는 네트워크 네임스페이스와 브리지 네트워크 - 컨테이너 네트워크 기초 2편
UTS 네임스페이스
UTS 네임스페이스는 호스트 네임과 NIS 도메인 이름을 격리하는 네임스페이스입니다. 네트워크 네임스페이스와 함께 네트워크를 격리하는 용도로 사용됩니다. UTS 네임스페이스에 대한 자세한 내용은 다음 글에서 소개합니다.

UTS 네임스페이스를 사용한 호스트네임 격리 - 컨테이너 네트워크 기초 1편
관련 명령어
-
unshare:
unshare
는 네임스페이스를 생성해서 프로세스를 생성하거나 영속화할 수 있도록 도와주는 명령어입니다. -
nsenter:
nsenter
는 영속화 되어있는 네임스페이스에서 프로세스를 실행하는 명령어입니다. - ip: ip는 현재 시스템의 네트워크 상태에 대해서 조회하는 용도 뿐만 아니라, 네트워크 네임스페이스를 조작하는 용도로도 사용됩니다.
함께 읽으면 좋은 문서들
네임스페이스는 아닙니다만, 루트 디렉터리를 격리할 때 사용하는 명령어로 chroot
가 있습니다. 기본적인 사용법은 unshare
와 비슷합니다. 처음 사용해보면 약간 어렵습니다만, 원리를 이해하면 직접 새로운 루트 디렉터리를 구축해 프로세스를 실행해볼 수 있으면 nsenter
등을 사용해 리눅스 네임스페이스 기능과 함께 사용하면 초보적인 수준의 컨테이너를 구현해볼 수 있습니다.

컨테이너 기초 - chroot를 사용한 프로세스의 루트 디렉터리 격리
namespace에 대한 man 페이지입니다. man 페이지 아래의 SEE ALSO
절에서 각 네임스페이스 별 매뉴얼을 찾아볼 수 있습니다.