IM Info
리눅스

컨테이너 vs 가상머신, 리눅스에서 뭘 골라야 할까

kuro editor
5분
컨테이너 vs 가상머신, 리눅스에서 뭘 골라야 할까

2013년 dotCloud가 사내 프로젝트로 시작한 Docker가 공개된 지 10년이 조금 넘은 지금, 컨테이너는 이미 서버 인프라의 기본값이 됐어요. 그런데 여전히 많은 개발 환경과 기업 인프라에서는 VMware나 KVM 기반 가상머신이 돌아가고 있고, 둘 중 하나만 골라야 하는 순간도 자주 옵니다. 그렇다면 컨테이너와 가상머신, 리눅스 환경에서 실제로는 뭘 기준으로 골라야 할까요?

컨테이너와 가상머신은 격리 계층이 다르다

컨테이너와 가상머신의 가장 근본적인 차이는 격리를 어느 계층에서 구현하는지에 있어요. 가상머신은 하이퍼바이저가 CPU, 메모리, 디스크 같은 하드웨어 자체를 가상으로 에뮬레이션해서 그 위에 완전히 독립된 게스트 OS와 커널을 통째로 올리는 방식이에요. 반면 컨테이너는 별도의 커널 없이 호스트 리눅스 커널을 그대로 공유하고, 그 위에서 네임스페이스(namespace)로 프로세스·네트워크·파일시스템을 나누고 cgroups로 자원 사용량을 제한하는 방식으로 격리를 흉내 내요.

그래서 가상머신 안에는 우분투 게스트든 CentOS 게스트든 완전히 독립된 커널이 하나씩 돌지만, 같은 호스트 위의 Docker 컨테이너들은 전부 호스트 커널 하나를 나눠 쓰고 있는 셈이에요. 이 차이 하나가 이어지는 부팅 속도, 리소스 오버헤드, 보안 수준까지 전부를 결정짓는 출발점이 됩니다.

부팅 속도와 리소스 오버헤드는 왜 이렇게 차이가 날까

컨테이너가 수백 밀리초 만에 뜨는 반면 가상머신은 수십 초가 걸리는 이유는 부팅 과정에서 처리해야 할 일의 양이 다르기 때문이에요. 가상머신은 전원을 켜는 순간부터 BIOS·부트로더·커널 초기화·드라이버 로딩까지 물리 서버와 똑같은 부팅 절차를 그대로 거쳐야 해서, 아무리 최적화해도 완전한 부팅에는 수십 초 이상이 필요합니다. 반면 컨테이너는 이미 켜져서 돌고 있는 호스트 커널 위에 격리된 프로세스 하나를 새로 띄우는 것에 가까워서, docker run 명령 한 번이면 사실상 즉시 애플리케이션이 실행돼요.

메모리와 디스크도 마찬가지예요. 가상머신은 게스트 OS 커널과 시스템 서비스, 라이브러리까지 통째로 메모리에 올려야 해서 최소 수백 MB에서 많게는 수 GB의 메모리를 미리 할당해야 하지만, 컨테이너는 애플리케이션 프로세스가 필요로 하는 만큼만 자원을 쓰기 때문에 같은 서버에 컨테이너를 수백 개 단위로 띄우는 것도 어렵지 않아요. 경량 컨테이너용 배포판인 Alpine Linux가 컨테이너 생태계에서 인기 있는 이유도 여기 있는데, musl libc와 busybox로 이미지 용량을 최소화해서 이 오버헤드 격차를 한 번 더 벌려주기 때문이에요.

보안 격리는 가상머신이 한 단계 위다

보안 관점에서는 가상머신이 컨테이너보다 근본적으로 더 강한 격리를 제공한다는 게 업계 정설이에요. 가상머신은 게스트마다 독립된 커널을 쓰기 때문에 한 VM 안에서 커널 취약점이 터져도 그 피해가 하이퍼바이저 계층을 넘어 다른 VM이나 호스트로 번지려면 하이퍼바이저 자체를 뚫어야 하는 훨씬 높은 장벽을 넘어야 해요. 반면 컨테이너는 호스트 커널을 공유하는 구조라서, 커널 자체에 존재하는 취약점이나 설정 실수로 인한 권한 상승이 발생하면 컨테이너 탈출(container escape)로 이어져 호스트나 다른 컨테이너까지 위협받을 가능성이 있습니다.

물론 리눅스 진영도 이 문제를 그냥 두지는 않았어요. seccomp 프로파일로 시스템 콜을 제한하고, AppArmor나 SELinux 같은 강제접근제어(MAC)를 얹고, gVisor나 Kata Containers처럼 컨테이너와 커널 사이에 별도의 격리 계층을 끼워 넣는 시도들이 이런 약점을 메우기 위해 나왔어요. 그런데도 멀티테넌트 환경에서 신뢰할 수 없는 코드를 돌려야 한다면, 여전히 가상머신 수준의 격리를 기본값으로 두는 게 안전한 선택이에요.

그렇다면 실제로는 언제 뭘 써야 할까

결론부터 말하면 컨테이너는 애플리케이션 배포와 마이크로서비스에, 가상머신은 강한 격리와 서로 다른 OS 환경이 필요할 때에 적합해요. 웹 서버, API 서버, 배치 작업처럼 애플리케이션 단위로 빠르게 배포하고 스케일을 늘렸다 줄였다 해야 하는 워크로드라면 컨테이너의 빠른 시작 속도와 낮은 오버헤드가 압도적으로 유리합니다. Kubernetes 같은 오케스트레이션 도구와 맞물리면 수십 개 서비스를 하나의 클러스터에서 효율적으로 운영할 수 있는 것도 컨테이너 쪽 강점이에요.

반대로 윈도우 서버와 리눅스 서버를 한 물리 장비에서 같이 돌려야 하거나, 커널 버전 자체가 다른 환경을 테스트해야 하거나, 고객사별로 완전히 분리된 인프라를 제공해야 하는 호스팅 사업이라면 가상머신 쪽이 정답에 가까워요. 컨테이너 호스트 OS를 비교한 글에서 다뤘듯이 컨테이너 전용으로 설계된 배포판들도 결국 그 밑에는 가상머신이나 베어메탈 서버가 깔려 있는 경우가 많은데, 이건 두 기술이 경쟁 관계가 아니라 계층을 나눠 함께 쓰이는 관계라는 걸 보여주는 대목이에요.

두 기술을 같이 쓰는 하이브리드 구성이 표준이 됐다

여기서 끝이 아니에요. 실무에서는 컨테이너와 가상머신을 양자택일하기보다 겹쳐서 쓰는 구성이 이미 표준으로 자리 잡았어요. AWS, GCP, Azure 같은 퍼블릭 클라우드는 고객마다 KVM 기반 가상머신 인스턴스로 하드웨어 수준 격리를 먼저 보장한 다음, 그 인스턴스 안에서 고객이 다시 Docker 컨테이너를 띄워 애플리케이션을 배포하는 이중 구조를 씁니다. 가상머신이 테넌트 간 강한 벽을 세워주고, 컨테이너는 그 벽 안에서 배포 속도와 자원 밀도를 끌어올리는 역할 분담인 셈이에요.

불변 리눅스로 불리는 Fedora Silverblue 같은 배포판이 등장한 것도 비슷한 맥락으로 볼 수 있어요. 시스템 자체를 읽기 전용으로 만들고 애플리케이션은 컨테이너 기술로 분리해서 관리하는 방식인데, 결국 컨테이너와 가상머신이 서로의 약점을 메워가며 리눅스 인프라 전체의 격리 모델을 다시 짜고 있는 흐름이라고 볼 수 있어요. 그래서 “컨테이너냐 가상머신이냐”라는 질문의 답은 어느 한쪽이 아니라, 워크로드 성격에 따라 두 계층을 어떻게 조합하느냐에 달려 있어요.

자주 묻는 질문

Q1. 컨테이너와 가상머신을 같이 써도 되나요?

네, 실제로 클라우드 환경 대부분이 이 조합을 쓰고 있어요. AWS EC2 같은 가상머신 인스턴스 위에 Docker 컨테이너를 올려서 하드웨어 수준 격리와 배포 편의성을 동시에 챙기는 방식이 표준이에요.

Q2. Docker는 왜 리눅스 커널이 있어야 동작하나요?

Docker 컨테이너는 자체 커널 없이 호스트 리눅스 커널의 네임스페이스와 cgroups 기능을 빌려 쓰는 구조이기 때문이에요. 그래서 macOS나 윈도우에서 Docker를 쓰면 내부적으로 경량 리눅스 가상머신을 하나 띄워서 그 위에 컨테이너를 올리는 방식으로 동작해요.

Q3. 가상머신보다 컨테이너가 항상 더 좋은 선택인가요?

아니요, 보안 격리가 최우선인 멀티테넌트 환경이나 커널 버전 자체가 달라야 하는 워크로드라면 오버헤드를 감수하고도 가상머신이 더 적합해요. 컨테이너는 속도와 밀도에서 유리하지만 격리 강도는 가상머신에 못 미쳐요.

Q4. KVM과 VirtualBox 중 어떤 걸 써야 하나요?

서버나 프로덕션 환경이라면 리눅스 커널에 내장된 KVM이 성능과 안정성 면에서 유리하고, 데스크톱에서 간단히 테스트용 VM을 띄우는 용도라면 GUI가 편한 VirtualBox도 충분해요.

Q5. 컨테이너 안에서 GUI 애플리케이션도 돌릴 수 있나요?

네, X11 소켓이나 Wayland 소켓을 컨테이너에 마운트하면 가능하지만 원래 용도가 서버 프로세스 격리이다 보니 설정이 번거롭고, GUI 앱을 자주 다뤄야 한다면 가상머신이 더 간단해요.

Q6. 컨테이너 이미지 용량이 가상머신 이미지보다 항상 작나요?

일반적으로는 맞아요. Alpine 기반 이미지는 수 MB 단위로 끝나는 경우가 많지만, 가상머신 이미지는 게스트 OS 전체를 포함하기 때문에 최소 수백 MB에서 수십 GB까지 커질 수 있어요.

k
kuro editor 자료 조사하고 분석하고 글을 읽기 쉽게 작성합니다
프로필

댓글

첫 번째 댓글을 남겨보세요!