리눅스 네임스페이스(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]'

여러가지 파일이 보입니다만 각각의 파일은 리소스 별 네임스페이스를 의미합니다. 현재 리눅스에서 지원하는 네임스페이스는 크게 보면 다음과 같습니다.

리눅스에서는 프로세스를 실행할 때 각 네임스페이스 별로 분리해서 실행하는 것이 가능합니다만, 앞에서 설명한대로 기본적으로는 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 }')

출력결과가 같기 때문에 아무 내용도 출력되지 않습니다.

일반적인 경우 리눅스 네임스페이스를 직접 활용하는 경우는 많지 않습니다만, 네트워크 테스트나 컨테이너 구현에서 활용됩니다. 리눅스 컨테이너는 리눅스 네임스페이스와 루트 파일 시스템 격리 등 리눅스의 다양한 기능을 사용해 격리시킨 프로세스를 의미합니다. 더 자세한 내용은 아래 글을 참고해주세요.

44BITS 로고

컨테이너란? 리눅스의 프로세스 격리 기능

🏷️ 키워드, 2020-01-23 - 리눅스 컨테이너는 운영체제 수준의 가상화 기술로 리눅스 커널을 공유하면서 프로세스를 격리된 환경에서 실행하는 기술을 의미합니다. 하드웨어를 가상화하는 가상 머신과 달리 커널을 공유하는 방식이기 때문에 실행 속도가 빠르고, 성능 상의 손실이 거의 없다는 장점이 있습니다.
44BITS 소식과 클라우드 뉴스를 전해드립니다. 지금 5,000명 이상의 구독자와 함께 하고 있습니다 📮

네임스페이스의 종류

PID 네임스페이스

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

44BITS 로고

도커(Docker) 컨테이너는 가상 머신인가요? 프로세스인가요?

🗒 기사, 2020-01-13 - 도커 컨테이너는 가상 머신과 비슷한 특징을 가지고 있습니다. 독립적인 파일 시스템 환경을 가지고 있고, 프로세스 아이디도 호스트와 다르고, 네트워크도 격리되어 있습니다. 하지만 분명 가상 머신은 아닙니다. 이 글에서는 도커 컨테이너가 가상머신과 어떻게 다르고, 호스트 입장에서는 단순히 프로세스라는 것을 직접 확인해봅니다.

네트워크 네임스페이스

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

44BITS 로고

ip로 직접 만들어보는 네트워크 네임스페이스와 브리지 네트워크 - 컨테이너 네트워크 기초 2편

🗒 기사, 2021-01-28 - 네트워크 네임스페이스는 프로세스 간의 네트워크를 격리해주는 매우 강력한 도구입니다. 리눅스에서는 ip를 사용해 네트워크를 조회하는 것 뿐만 아니라 네트워크 네임스페이스를 제어하는 용도로도 사용됩니다. 이 글에서는 네트워크 네임스페이스 사용법과 함께 veth(가상 인터페이스)와 가상 브리지로 직접 컨테이너 네트워크 환경을 구축해봅니다.

UTS 네임스페이스

UTS 네임스페이스는 호스트 네임과 NIS 도메인 이름을 격리하는 네임스페이스입니다. 네트워크 네임스페이스와 함께 네트워크를 격리하는 용도로 사용됩니다. UTS 네임스페이스에 대한 자세한 내용은 다음 글에서 소개합니다.

44BITS 로고

UTS 네임스페이스를 사용한 호스트네임 격리 - 컨테이너 네트워크 기초 1편

🗒 기사, 2021-01-26 - 컨테이너는 하드웨어 가상화 없이 프로세스를 격리하는 기술로 루트 디렉터리 격리와 유니온 마운트를 비롯해 리눅스 네임스페이스와 같은 리눅스의 기능들을 활용합니다. 이 시리즈에서는 컨테이너의 네트워크 격리와 관련된 기술을 소개합니다. 첫 번째 글에서는 호스트네임을 격리하는 UTS 네임스페이스에 대해서 소개합니다.

관련 명령어

함께 읽으면 좋은 문서들

네임스페이스는 아닙니다만, 루트 디렉터리를 격리할 때 사용하는 명령어로 chroot가 있습니다. 기본적인 사용법은 unshare와 비슷합니다. 처음 사용해보면 약간 어렵습니다만, 원리를 이해하면 직접 새로운 루트 디렉터리를 구축해 프로세스를 실행해볼 수 있으면 nsenter 등을 사용해 리눅스 네임스페이스 기능과 함께 사용하면 초보적인 수준의 컨테이너를 구현해볼 수 있습니다.

44BITS 로고

컨테이너 기초 - chroot를 사용한 프로세스의 루트 디렉터리 격리

🗒 기사, 2018-12-03 - chroot는 프로세스의 루트 디렉터리를 변경하는 리눅스 시스템콜/명령어입니다. 루트를 변경함으로써 아주 기초적인 단계의 컨테이너를 구현해볼 수 있습니다. chroot는 아주 단순한 프로그램입니다만, 루트가 달라지면 프로세스의 동작 방식 달라져 실제로는 사용하기가 까다로운 편입니다. 이 글에서는 chroot의 기본적인 원리와 사용법에 대해서 소개합니다.

namespace에 대한 man 페이지입니다. man 페이지 아래의 SEE ALSO 절에서 각 네임스페이스 별 매뉴얼을 찾아볼 수 있습니다.