오늘날 수많은 애플리케이션이 컨테이너 환경 위에서 실행된다. 컨테이너는 어떻게 독립된 시스템처럼 동작할 수 있을까? 이를 가능하게 해주는 두 가지 기술이 바로 Namespace와 Cgroup이다.
이 두 가지 핵심 기술에 대해서 알아보도록 하자.
Namespace
리눅스 컨테이너 기술의 핵심은 단순히 프로세스를 실행하는 것이 아니라, 그 프로세스를 다른 프로세스들과 격리된 환경에서 실행하는 것이다. 이를 가능하게 해주는 것이 바로 Namespace(네임스페이스)이다.
네임스페이스는 리눅스 커널이 제공하는 기능으로, 각 프로세스가 자신만의 공간을 가진 것처럼 보이도록 만들어준다. 컨테이너 구성에 필요한 주요 네임스페이스는 다음과 같다: Mount Namespace, UTS Namespace, IPC Namespace, PID Namespace, Network Namespace
Mount Namespace
•
격리 대상: 파일 시스템(마운트 포인트)
•
설명:
◦
각 프로세스마다 자신만의 파일 시스템을 가질 수 있게 한다.
◦
컨테이너 내부에서 디렉터리를 mount 또는 unmount해도 다른 컨테이너나 호스트에는 영향을 주지 않는다.
◦
이 기능을 통해 컨테이너마다 / 루트 파일 시스템을 독립적으로 구성한다.
PID Namespace
•
격리 대상: 프로세스 ID
•
설명:
◦
컨테이너 내부에서는 PID 1부터 시작하는 고유한 프로세스 ID 공간을 가진다.
◦
컨테이너 안에서 ps나 top을 실행하면, 해당 네임스페이스 내의 프로세스만 보인다.
▪
ps: Process Status; 현재 실행 중인 프로세스 상태 제공
▪
top: 실시간으로 프로세스와 리소스 사용량을 모니터링
◦
중요한 점은 컨테이너 안의 PID 1인 프로세스가 사라지면 해당 컨테이너가 종료된다.
Network Namespace
•
격리 대상: 네트워크 인터페이스, 라우팅 테이블 등
•
설명:
◦
각 컨테이너는 자신만의 네트워크 인터페이스, IP 주소, 라우팅 설정 등을 가질 수 있다.
◦
별도의 가상 네트워크 인터페이스(veth)를 통해 호스트나 다른 컨테이너와 연결된다.
◦
컨테이너 간 통신이나 외부와의 통신을 위해, 컨테이너는 veth pair로 호스트와 연결된다.
UTS Namespace
•
격리 대상: 호스트 이름(hostname)
•
설명: 컨테이너마다 독립적인 호스트 이름(hostname)을 사용할 수 있도록 한다.
IPC Namespace
•
격리 대상: 메시지 큐, 공유 메모리, 세마포어 등
•
설명:
◦
프로세스 간 통신을 위한 자원들을 컨테이너 단위로 격리한다.
◦
각 컨테이너는 자신만의 IPC 공간을 사용하므로, 다른 컨테이너에 있는 프로세스 간에는 통신할 수 없다.
이 네임스페이스들을 조합해서 사용할 때, 진정으로 격리 환경이 완성된다. 덕분에 리눅스 커널 위에서 여러 개의 고립된 작은 OS처럼 보이는 컨테이너를 실행할 수 있게 된다.
Cgroup
Namespace로 논리적인 격리 환경을 만들었다면, 다음은 리소스를 제한 및 제어하는 Cgroup(Control Group)이 필요하다. 컨테이너가 사용할 리소스를 제한 및 제어하는 역할을 하는 게 바로 Cgroup이다.
위의 그림처럼 프로세스를 각 그룹(Group)으로 묶은 뒤, 각 Group에게 컴퓨터의 리소스(CPU, Memory, Network, Storage I/O 등)을 할당해 준다. 그리고 그룹에 속한 프로세스들에게 해당 그룹에 할당된 리소스를 상한선으로 할당해 준다.