가상화에는 하이퍼바이저 가상화와 컨테이너 가상화, 2가지 유형이 존재한다.
이번 글에서는 컨테이너 가상화에 대해 알아보도록 한다.
컨테이너
하드웨어에 설치된 커널 하나에 격리된 컨테이너 프로세스를 돌리는 구조로 OS 수준의 가상화를 제공한다. 무겁고 느린 hypervisor 가상화 방식의 단점을 해결하기위해 등장했다.
컨테이너는 애플리케이션과 그에 종속되는 것들을 패키지화하고 실행환경을 격리하는데에 목적을 둔다. 각 컨테이너들을 호스트 OS의 리소스를 공유하며, 필요한 라이브러리와 실행 파일만을 포함하고 있어 하이퍼바이저 가상화의 가상머신(VM)보다 가볍게 구동될 수 있다.
컨테이너 가상화의 특징으로는 아래와 같다.
특징 | 설명 |
성능과 자원 효율성 | 가상머신(VM)에 비해 낮은 오버헤드와 빠른 부팅 시간 |
이식성과 배포 | 배포할 App의 내용과 종속성들이 포함된 컨테이너 이미지라는 개념을 통해 높은 이식성과 빠른 배포를 제공 |
프로세스 격리 | 각 컨테이너 프로세스들이 격리되어 독립적으로 실행 |
자원 공유성 | 컨테이너는 호스트 OS의 자원을 공유하므로, 여러 컨테이너 간의 자원 공유가 쉽고 효율적 |
이러한 이유들로 인해 근래에 컨테이너 가상화 방식이 주목을 받고 있기도 하다. 특히나 마이크로서비스 아키텍쳐(MSA)에서 적합한 가상화 기술로 평가되고 있기도 하다.
컨테이너 가상화를 이용하는 사례중 가장 유명한 도커(Docker)가 존재한다.
컨테이너 가상화의 기술
컨테이너 가상화의 대표적인 기술은 Namespace와 cgroup, Union mount filesystem으로 볼 수 있다.
먼저, Namespace와 cgroup은 리눅스 운영체제에서 프로세스를 격리하고 제한하는데 사용되는 핵심 기술이다.
Namespace
리눅스 시스템에서 프로세스의 가상화를 담당, 각각의 Namespace는 특정 리소스에 대한 프로세스의 가상공간을 제공하는 기능이다. 하이퍼바이저의 VM과 다르게 동일한 OS, 커널에서 동작한다.
해당 Namespace에 있는 프로세스는 다른 프로세스들과 격리되어 독립적으로 동작한다. (프로세스가 볼 수 있는 범위 제한, Limits what you can see)
즉, 하나의 Namespace의 변경사항 등이 다른 Namespace에 영향을 끼치지 않는 것이다.
대표적인 Namespace의 종류는 아래와 같이 존재한다.
종류 | 설명 |
PID | 프로세스 간에 서로 다른 프로세스 ID를 제공함으로써, 프로세스들을 격리 |
Network | 네트워크 인터페이스와 IP주소들을 독립적으로 제공 |
Mount | 프로세스별로 마운트되는 파일시스템 격리 |
IPC | 프로세스간 통신을 격리 |
User | 프로세스별 UID,GID를 격리 |
cgroup (Control group)
프로세스들이 사용하는 시스템의 자원들을 제어(수집/격리/제한)하는 리눅스 커널 기능
cgroup은 프로세스를 그룹화해서 특정 cgroup에 속한 컨테이너들은 해당 그룹 내의 제한 내에서만 리소스를 사용할 수 있다. (프로세스가 쓸 수 있는 사용량 제한, Limits how much you can use)
cgroup은 부모-자식의 계층적 구조를 갖는데, 부모 cgroup은 자식 cgroup에 대해 제한을 설정할 수 있고, 리소스 사용량을 모니터링할 수 있다.
Union FileSystem (UFS)
여러개의 파일 시스템들을 하나의 파일 시스템에 마운트 시키는 것으로 여러 레이어(계층)로 구성된 구조를 갖는다. Docker는 이 UFS를 이용해 이미지 레이어를 구현하는데에 사용한다. Docker의 이미지는 여러 레이어의 스택으로 구성되는데, 여기서 각 레이어는 명령어를 통한 파일/디렉토리의 변경 사항으로 표현된다.
Union Filesystem에서 각 레이어는 컨테이너 레이어와 이미지 레이어로 분류된다.
컨테이너 레이어
Writeable한 레이어로 각 컨테이너마다 최상단에 생성된다. 이미지를 통해 컨테이너가 생성된 후의 모든 변경사항들이 이 레이어에서 이루어 진다.
단, 컨테이너가 종료되면 컨테이너 레이어에 쓴 내용이 휘발된다는 점이 있다.
이미지 레이어
Read-Only한 레이어로 컨테이너 생성의 기반이 되는 레이어이다. 동일한 이미지 레이어를 사용하는 이미지를 빌드할때, 그 해당되는 이미지 레이어를 로컬 캐시에서 바로 불러와서 사용하므로 빌드 시간이 단축되는 효과를 볼 수 있다. 이미지 레이어는 여러 이미지 간에 공유되고 캐싱되어 효율적으로 관리된다.
컨테이너 프로세스가 격리되어 실행되는 것과 마찬가지로 컨테이너들의 파일 시스템도 격리를 시키는 것이다. 각 컨테이너는 자체 파일 시스템 레이어를 가지고 있어 다른 컨테이너의 파일 시스템에 영향을 주지 않는다.
베이스 이미지 레이어를 여러 컨테이너가 동일하게 사용할 수 있는데, 각 컨테이너 별로 베이스 이미지에서 변경된 부분만 새로운 컨테이너 레이어로 저장하게 되어 중복되는 내용을 줄이게 된다(CoW). 이는 곧 변경 사항이 원래 레이어에 영향을 주지 않으면서, 디스크 리소스를 효율적으로 사용할 수 있게 된다.
이렇게 컨테이너 가상화 기술에 대해서 알아보았다.
최종적으로 요약하면 컨테이너 프로세스를 격리하기 위한 Namespace와 각 프로세스에 시스템 리소스를 할당해주기 위한 cgroup, 가상 파일 시스템을 관리하는 Union filesystem이 사용된 것으로 볼 수 있다.