Docker vs LXC vs VM - Conclusion

TaekJun Jeong·2026년 9월 17일

OS

목록 보기
5/5
post-thumbnail

개념·네트워킹·환경 구축·측정을 거쳐, 마지막으로 "그래서 실제로 뭘 골라야 하나"를 정리합니다.


한 줄 결론

같은 nginx를 세 tier에 올려 직접 재보니, 앱 자체의 무게는 거의 같았습니다(0.4~4 MB).

차이는 전부 "격리 단위가 무엇을 짊어지느냐"에서 나왔습니다.

그래서 선택 기준은 성능이 아니라 "얼마나 강한 격리가, 무엇을 위해 필요한가"입니다.



실험 결과

축결과정리
무게부팅 0.56s / 4.25s / 30s · 디스크 153MB / 1.4GB / 13GBDocker < LXC < VM (일관)
격리컨테이너는 cgroup으로 자원만 봉쇄(커널 공유),
VM은 커널 패닉조차 게스트에 가둠
격리 강도 Docker < LXC < VM
보안LXD는 uid 리매핑으로 컨테이너 root를 비특권화(1000000),
Docker는 기본 root(0)
LXD 기본 보안 > Docker 기본
스냅샷VM(qcow2) 0.04s < Docker 0.18s < LXC(dir) 31s속도는 tier가 아니라 CoW 백엔드

핵심은 마지막 줄입니다.

무거운 VM이 스냅샷은 제일 빨랐습니다.

"가벼우면 다 빠르겠지"라는 직관은 틀렸고, 각 항목이 다른 계층(앱·OS·커널·스토리지)에서 결정된다는 걸 실측으로 확인했습니다.



Docker — 앱 하나를 빠르게 굴릴 때

셋 중 제일 가볍고 빠릅니다.

이미지를 레지스트리에 올려두면 어디서든 똑같이 뜨니 이식성도 좋고요.

컨테이너를 애지중지 키우기보다 필요하면 지우고 다시 만드는 방식이라, 자주 배포하고 확장하는 CI/CD나 마이크로서비스에 잘 맞습니다.

대신 격리는 셋 중 가장 약합니다.

기본이 커널 공유에 root라, 신뢰할 수 없는 코드를 돌리거나 여러 테넌트를 한 호스트에 태우는 상황이라면 부담스럽습니다.

그럴 땐 rootless나 userns-remap, 또는 gVisor·Kata 같은 샌드박스 런타임으로 보완합니다.

gVisor·Kata

"컨테이너처럼 편한데 VM처럼 격리 센" 걸 노리는 샌드박스 런타임.

일반 컨테이너와 VM 사이를 메꾸는 오픈소스 기술.

gVisor (Google) — "가짜 커널을 하나 세운다"

  • 컨테이너가 커널한테 요청(syscall)을 보낼 때, 진짜 호스트 커널로 바로 안 가고 gVisor가 만든 유저스페이스 가짜 커널(Sentry)이 중간에서 가로채서 대신 처리함.
  • 효과: 컨테이너에서 커널 취약점을 찔러도 그 공격이 가짜 커널선에서 막힘. 호스트 커널 공격 표면이 확 줄음.
  • 단점: syscall 다 가로채니 성능 오버헤드가 있고, 지원 안 하는 syscall이 있어서 호환성 이슈(일부 앱이 안 돎).

Kata Containers — "아예 작은 VM에 넣어버린다"

  • 각 컨테이너를 경량 VM 안에 통째로 넣음.
    겉은 컨테이너인데 속은 진짜 VM(자기 커널 + 하이퍼바이저)이다.
  • 즉 "컨테이너 API + VM 격리". 커널이 진짜로 분리돼서 VM급 격리를 얻음.
  • 단점: 진짜 VM을 띄우니 일반 컨테이너보다 무겁고(부팅·메모리 오버헤드), 하드웨어 가상화(vmx/svm)가 필요.


LXC — 가벼운 서버 한 대가 필요할 때

LXC는 컨테이너인데 다루는 느낌은 VM에 가깝습니다.

안에서 systemd가 돌고 여러 프로세스가 상주하고, 상태를 유지한 채 ssh 들어가듯 씁니다.

그러면서도 무게는 29MB로, GB 단위인 VM보다 훨씬 가볍고요.

"VM처럼 쓰고는 싶은데 그만큼 무겁긴 싫을 때" 자리가 여기입니다.

보안도 은근한 강점이 있습니다.

LXD는 기본으로 컨테이너의 root를 호스트의 비특권 유저(uid 1000000)로 매핑해두기 때문에, 설령 탈출하더라도 호스트에선 아무 권한이 없습니다.

Docker가 기본적으로 컨테이너 root = 호스트 root인 것과 대조됩니다.

물론 커널을 공유한다는 근본 한계는 그대로라 커널 탈출 위험은 남고, 이미지·레지스트리 생태계는 Docker가 한참 앞섭니다.



VM — 진짜 벽이 필요할 때

VM만 할 수 있는 게 하나 있습니다. 바로 커널을 통째로 분리하는 것이죠.

실험에서 게스트 커널을 강제로 패닉시켜봤는데도 호스트(Mac)는 uptime 하나 흔들리지 않았습니다.

컨테이너의 격리가 소프트웨어로 그은 선이라면, VM은 하드웨어가 강제하는 벽입니다.

다른 커널이나 OS가 필요할 때, 신뢰할 수 없는 워크로드를 가둘 때, 규제·보안상 확실한 경계가 필요할 때 VM이 필요합니다.

값은 비쌉니다.

부팅 30초, 디스크·메모리 GB 단위.

다만 스냅샷만은 백엔드가 qcow2라면 오히려 제일 빠를 수 있다는 게 이번 실험의 반전이었습니다.



고를 때 스스로에게 던지는 질문

  1. 다른 커널·OS가 필요한가 → VM (컨테이너는 호스트 커널을 공유하니 애초에 불가능)

  2. 신뢰할 수 없는 코드를 격리해야 하나 → VM, 아니면 gVisor·Kata

  3. 앱 하나를 자주 배포·확장하나 → Docker

  4. 상태를 유지하며 서버처럼 다루고 싶나 → LXC

  5. 컨테이너를 쓰되 기본 보안이 조금 더 필요한가 → LXC(userns) 또는 Docker rootless



사실은 하나만 고르지 않습니다

이 실험의 구조 자체가 답이기도 합니다.

Xen VM 위에서 LXC와 Docker 컨테이너를 돌렸으니까요. 실무도 대개 이렇게 층을 쌓아 사용한다고 합니다.

바깥은 VM이나 베어메탈로 강한 격리 경계를 긋고, 그 안에서 컨테이너로 앱을 빠르게 굴립니다.

그러니 진짜 질문은 "Docker냐 VM이냐"가 아니라 "어느 층에 무엇을 둘 것인가"에 더 가깝습니다.



정리

결국 셋의 차이는 "커널을 공유하느냐, 무엇을 격리 단위로 짊어지느냐" 한 줄로 좁혀집니다.

Docker는 프로세스를, LXC는 OS 한 벌을, VM은 커널까지 짊어집니다.

짊어진 만큼 격리가 단단해지고 그만큼 무거워지죠.

그러니 제일 좋은 것을 찾기보다, 지금 필요한 격리가 어느 층인지를 먼저 정하면 됩니다.


감사합니다.




정택준
Team: https://nangman.cloud/ko
E-mail: taekjunnnn@nangman.cloud

0개의 댓글