Host OS : 가상머신이 구동되는 PC 의 운영체제
Guest OS : 각 가상머신 내에서 구동되는 별도의 운영체제
하이퍼바이저(Hypervisor) : 가상머신을 생성하고 구동하는 소프트웨어
위 그림처럼 가상머신은 애플리케이션과 OS 가 함께 가상화 된 것이다. 따라서 각 가상머신의 Guest OS 는 다른 가상머신들의 Guest OS 와 완전히 독립된 공간과 시스템 자원을 할당받고 사용한다.
즉 하이퍼바이저는 애플리케이션과 OS 를 같이 가상화하여 각 가상머신을 격리시킨다.
따라서 각 가상머신은 Guest OS 로 인해 Host OS 에게 많은 리소스를 요구하며 실행 시 부팅이 필요하다.
Container(컨테이너)
Docker Engine : 컨테이너를 구축하고 실행하는 소프트웨어
하나의 Host 에서 실행되는 컨테이너들은 모두 동일한 Host OS 를 공유
즉 Docker Engine 은 Host OS 는 공유한 상태로 각 도커 이미지를 컨테이너화해서 프로세스들을 격리
각 컨테이너는 별도의 OS 를 가지고 있지 않으므로 실행 시 부팅이 필요없으며 가상머신에 비해 가볍다는 장점이 있다.
그러면 컨테이너 격리는 어떻게 가능한가?
그렇다면 컨테이너들은 가상머신과는 다르게 모두 같은 OS 를 사용하고 있는 것인데 대체 어떻게 서로 격리될 수 있는 것인가?
도커의 컨테이너는 리눅스 컨테이너(LXC) 라는 리눅스만의 기술을 통해 각 컨테이너의 격리를 구현했었다. 그러나 LXC 는 리눅스에서만 특화되어 있다는 리스크가 존재했기 때문에 Docker 0.9 버전부터는 libcontainer 라는 자체 기술을 만들어서 컨테이너의 격리를 구현했다.
LXC 와 libcontainer 모두 리눅스 커널에서 제공하는 2 가지의 핵심 기능을 사용하여 컨테이너의 격리를 구현한다.
namespace(네임스페이스)
cgroup(리눅스 컨트롤 그룹)
namespace(네임스페이스)
namespace 는 리눅스 커널에서 제공하는 프로세스를 독립시키위한 가상화 기술이다.
프로세스가 실행되면 프로세스의 구성 요소들은 하나의 네임스페이스에 속하게 되며, 프로세스는 동일한 네임스페이스 내에 있는 리소스만 조회가 가능해진다.
프로세스가 속해있는 네임스페이스는 고유하기 때문에 다른 프로세스의 리소스를 공유하는 것이 불가능해진다.
cgroup(리눅스 컨트롤 그룹)
cgroup 은 리눅스 커널에서 제공하는 리소스에 대한 제어를 가능하게 기능이다.
이 기능을 통해 컨테이너가 사용할 수 있는 리소스의 양을 제한할 수 있다.
결론
결론적으로 도커 환경에서의 프로세스의 격리는 namespace, cgroup 이라는 리눅스 커널에서 제공하는 기술들을 통해서 구현된다.
도커 자체에 프로세스 격리 기술이 포함되어 있는 것은 아니라는 점에 유의하자.
libcontainer, libvit, LXC, systemd-nspawn 모두 도커가 사용할 수 있는 컨테이너 기술이며, 현재 도커는 자체적으로 개발한 libcontainer 를 디폴트로 설정하여 사용하고 있다.