VM(Virtual Machine)이라는 기술과 컨테이너(Container)라는 기술은 2000년도쯤에도 존재했고, 컨테이너는 VM을 기반으로 동작했다. 또한 컨테이너 기반의 Docker 가 출시된 것은 2013년으로 10년밖에 되지 않았다.
이러한 배경속에서 VM과 Docker을 비교하며 서로를 알아갈 필요가 있다.
미리 알고 있으면 좋은 내용으로 VM 과 Docker 의 차이는 Cuest OS 의 유무이다.

- VM : 분할 공간에서의 가상환경, Virtual Machine
- 호스트 시스템 : 서버의 OS
- 게스트 OS : VM 의 OS
- 하이퍼바이저 : 게스트OS를 구동 및 모니터링
도커의 출시 배경
Pycon US 2013 에서 Docker, Inc가 처음으로 세상에 공개되었다.
Pycon에서 Docker 가 공개된 이유는 파이썬 버전이 빠르게 올라가면서 프로젝트 당 Python 버전을 편리하게 관리하기 위해서 시작되었다. Docker 가 공개되기 전 chroot, LXC 도 있었지만 제약사항과 기능 부족 등으로 한계로 인해 Docker 가 탄생하게 되었다.
chroot 란
root 디렉토리를 변경하는 기능으로 특정 프로세스의 root 디렉토리를 변경하여 root 디렉토리 밖으로 접근하는 것을 제한하는 것이었다. 하지만 chroot는 접근 권한만 제어하기 때문에 완전한 가상화가 아니었고, 프로세스 당 설정해야 하는 복잡한 과정으로 제약이 존재했다.
LXC(Linux Container) 란
LXC 이후 cgroups와 namespace기술을 사용하여 LXC라는 시스템 레벨의 가상화가 탄생하였고, OS 자체를 가상화하는 VM과는 다르게 해당 기술은 호스트 OS의 커널을 공유하고 단순히 하나의 격리되어 있는 프로세스로써 동작하기 때문에 컨테이너라고 구분 지어 부르게 되었다.
그래서 도커는
하지만 LXC가 격리된 환경을 제공하기는 했지만, 그 안에서의 서비스를 운영하기 위한 기능들이 부족했기 때문에 이미지, 컨테이너 관리 등의 다양한 기능을 제공하는 Docker가 등장하게 되었다.
이러다 보니 Docker vs VM 이라는 용어보단 Container vs VM으로 바라보는 것이 옳은 관점이다.
Docker 란 ?
Docker란 Go언어로 작성된 리눅스 컨테이너 기반으로하는 오픈소스 가상화 플랫폼이다.
유닉스 기반의 맥과 윈도우의 경우 도커 데스크탑을 설치하며 VM에 GuestOS로 리눅스를 올리던가, WSL의 우분투를 사용하게 된다.
Container (컨테이너) vs Virtual machine (VM)
Container 와 VM의 격리 레벨의 관점으로 바라보면 VM 이 Container 보다 강력하게 격리된다.
VM 은 가상화된 하드웨어 위에 OS 가 올라가는 형태로 거의 완벽하게 Host와 분리된다고 볼 수 있다.
반면 Container 는 OS 가상회이다. OS 부분을 가상화해서 올리고 커널을 Host와 공유하여 VM 보다 얕게 격리된다.
이 차이에서 발생하는 장단점을 바라볼 수 있다.
작은 용량
일단 위에 언급된 그림의 볼륨만으로도 Container 가 작다.
그 이유는 VM 은 Hyper Visor가 Hardware 을 가상화한다. 그리고 그 위에 Guest OS가 올라가게 된다.
위의 그림만 해도 3개의 GuestOS가 올라간다. 반면 Container는 Docker Engine 위에 Application 에 실행에 필요한 바이너리만 올라간다. 그 외 커널 부분은 호스트의 커널을 공유한다. 격리는 Linux Namespace 를 통해 개념적으로 실행된다.
만약 호스트의 커널과 Container 의 커널이 다르다면 다른 부분만큼만 패키징 되며 패키징 되는 만큼 공간을 절약할 수 있다.
작음으로서 만들어진 이미지가 작아지는 장점과 Network 을 덜 사용한다는 장점도 있다.
Docker 의 라이프 사이클은 우선 Registry 로 부터 이미지를 Pull 을 받아오면서 시직한다.
여기서부터 용량이 작다는 것은 네트워크를 덜 쓸 수 있고 Cloud 는 사용량이 줄어들어 과금을 덜 하게 된다.
(이 과정이 비용과도 직접적으로 연결된다.)
만약 Host 가 하나가 아니라 Clustering 환경이었다면 n*x 만큼의 용량과 비용을 사용하게 된다.
빠른 속도
VM 과 Container 는 Host 머신보다는 느리다. 하지만 Container 와 vm을 비교하면 Container 가 더 빠르다.
수만은 이유 중 간단히 비교하자면 VM 은 Container 보다 더 많은 IO 을 발생시킨다. VM 은 Host OS 에서 거의 완전히 분리된 형태로 운영이 되지만 IO 을 주고 받을 때는 VM 이 처리한 IO 를 Host OS 커널이 디스크에서 다시 받아 다시 처리해줘야 하며 이 부분에서 병목이 발생한다.
반면 Container 는 커널을 공유하기 때문에 들어온 IO 가 쉽게 처리돼서 나갈 수 있다.
결론으로 Container 이 VM 보다 더 적은 커널 처리가 들어가 Container 가 성능면에서 더 빠르다.
Guest OS 의 유무
VM 에는 Guest OS가 존재하지만 도커의 컨테이너는 존재하지 않는다.
컨테이너에는 Guest OS를 설치하지 않기 때문에 자원의 효율성 측면에서 차이가 난다.
VM는 하나씩 늘 때마다 OS를 위한 자원을 할당해주어야 하는 반면에 도커는 어플리케이션을 구동하는데 필요한 모든 패키지만 있으면 컨테이너를 구동시켜 경량화를 할 수 있다.
하나의 커널과 독립된 공간
도커는 리눅스 커널의 Cgroup(Control Groups) 과 네임스페이스 기능을 이용해서 구현되어 있다.
이 기능을 통해서 다른 프로세스 사이에 벽을 만든다. 도커 컨테이너들은 리눅스 커널을 사용하기 때문에 Docker Engine 이라는 VM을 통해 Guest OS를 갖고 있다. Docker의 Guest OS가 리눅스가 되고 이 위에 쌓이는 컨테이너에는 더이상 Guest OS가 깔리지 않으며 리눅스 커널의 기능으로 각 컨테이너들은 격리가 됨으로서 벽을 만들 수 있는 것이다.
Docker 하이퍼바이저를 포함하고 있고 실제 환경 PC과 도커의 관계에서는 Guest OS 이고 도커와 컨테이너의 관계에서는 Host OS 인 리눅스가 설치되어 있다. 컨테이너에는 VM Host와는 달리 OS가 설치되어 있지 않다.
라이프 사이클
Container 기술은 오랜 기간 존재했고, docker는 Container 기술 중 하나일 뿐이다.
그 중 docker 의 장점으로는 변경점을 바로 적용할 수 있다는 점이다. 서비스 버전을 올릴 경우를 예시로 했을 때 VM 의 경우 vm에 접근해서 Repository를 Pull 받거나, 새로 Clone을 받을 수도 있었을 것이며 Config 수정이 필요했을 수 도 있다.
만약 근데 서버가 하나가 아니라면 Jenkins를 을 사용하여 구성할 수 있을 것이다. 만약 스크립트에서 에러가 발생할 수 있으며 디버깅도 어려울 것이다. 하지만 Docker 환경이라면 내 개발 환경에서 운영 환경 image 를 만들어 Registry에 배포한 후 새로운 이미지로 컨테이너를 다시 배포하면 된다. 같은 Docker Engine 위에서 동일한 이미지로 테스트를 했기 때문에 운영 환경에서 에러가 발생할 가능성도 매우 낮으며 배포 리스크도 줄게 된다.
또한 도커 스웜(Docker Swarm), 쿠버네티스(Kubernetes) 와 같은 오케스트레이션도 제공된다. 여러 대의 Host에 여러 대의 Container를 동시에 배포하면서 Container를 관리할 수도 있다는 것이다. Scale Out도 쉽고 또한 병목 현상이 생긴 Container를 찾아낸다면 전체 Infra의 Scale Up이 아니라, 그 현상이 이뤄나는 Container의 Scale out을 통해 전체 서비스의 성능을 올릴 수 있는 유연성도 생긴다.
이로 인해 버전관리 뿐만 아니라 롤링 업데이트를 위해 HA까지 쉽게 구성할 수 있다. 이로 인해 Micro Services 로 발전할 수 있는 토대를 마련하고 적용해나갈 수 있다는 것이다.
만약 이러한 작업을 VM 으로 한다면 수 많은 Bandwidth와 Scale Out 등을 처리하기에 수많은 작업을 해야하며 많은 지식들도 함께 동원해야 할 것이다.
결과적으로 컨테이너화된 환경에서는 다수의 컨테이너를 관리하는 것이 중요한 과제이기 때문에 이를 위해 도커 스웜(Docker Swarm), 쿠버네티스(Kubernetes)와 같은 컨테이너 오케스트레이션 도구를 사용하며 컨테이너 오케스트레이션 도구는 컨테이너의 배포, 확장, 네트워킹 및 라이프사이클 관리를 자동화한다. 이를 통해 높은 가용성, 확장성 및 자원 최적화를 달성할 수 있으며 도커와 함께 컨테이너 오케스트레이션 도구를 사용하면 대규모 컨테이너화 애플리케이션 관리와 클라우드 환경에서의 서비스 운영을 간소화할 수 있다.
컨테이너의 단점이자 VM 의 장점으로는
보안
작은 용량의 내용을 보면 Container가 host의 커널을 공유한다는 개념으로 장점을 있다는 것을 알 수 있다. 하지만 Container 가 Host 를 공유한다는 것은 Container 가 해킹당하면 Host 커널이 위험해진다는 것을 뜻하기도 한다. 동시에 Host 커널까지 오지 않더라도 커널이 공격당하면, 커널을 공유한다는 개념 때문에 모든 Container가 위험해지는 현상이 발생할 수 있다.
반면 VM 은 하나의 VM 이 공격당해도 아키텍처 특징으로 인해 Host 와 다른 VM은 보호된다.
이거 무슨 소리지? 싶으면 2024년에 공개된 CVE-2024-21626 을 보면 된다. 그래도 이해가 안된다면 해줄 말이 없다.
NVD - CVE-2024-21626
CVE-2024-21626 Detail Modified This vulnerability has been modified since it was last analyzed by the NVD. It is awaiting reanalysis which may result in further changes to the information provided. Description runc is a CLI tool for spawning and running co
nvd.nist.gov
멀티 OS 지원
커널을 공유하는 장점으로 Host OS 와 전혀 다른 OS는 Container 으로 실행할 수 없다.
예를 들어 Linux 머신에서 window 서버를 container로 올릴 수 없으며 VM 은 하드웨어 가상화를 통해 Linux 머신에 Window 서버를 가상화된 OS 를 올릴 수 있다.
'DevOps > 도커 (Docker)' 카테고리의 다른 글
[Docker] - 006. Docker Swarm 이란 (0) | 2024.05.06 |
---|---|
[Docker] - 005. Docker Compose 활용하기 (0) | 2024.05.04 |
[Docker] - 004. Multi Stage Build 와 Base 이미지 만들기 (0) | 2024.04.19 |
[Docker] - 003. DockerFile 캐싱 전략 (0) | 2024.04.19 |
[Docker] - 002. Docker CLI 와 이미지 만들기 (0) | 2024.04.17 |