0. 들어가며
도커(Docker)는 현대 소프트웨어 개발과 배포의 핵심 도구로 자리잡았다. 많은 개발자들이 도커를 사용하지만, "도커가 왜 필요한가?"라는 근본적인 질문에 답하기 어려워하는 경우가 많다. 이 질문에 답하기 위해서는 먼저 도커가 등장하기 전의 상황을 이해해야 한다. 도커는 단순히 유행이 아니라, 개발자들이 오랫동안 겪어온 고통스러운 문제를 해결하기 위해 등장했기 때문이다.
1. "내 PC에서는 잘 되는데요?"의 슬픔
개발자라면 한 번쯤 겪어봤을 상황이다.
개발자: "기능 개발 완료했습니다! 로컬에서는 잘 돌아가요."
운영팀: "서버에 배포했는데 실행이 안 됩니다. JDK 버전이 뭐죠?"
개발자: "JDK 18인데요."
운영팀: "서버는 JDK 17인데... 그리고 필요한 라이브러리가 몇 개 없네요."
혹은 이렇게 표현하기도 한다.
"내 PC에서는 잘 되는데, 왜 서버에서는 안 되죠?"
이 문제의 근본 원인은 '환경의 차이' 때문이다. 개발 환경과 운영 환경은 다음과 같은 요소들이 다를 수 있다.
- 운영체제(OS) 버전 (Ubuntu 20.04 vs CentOS 7)
- 프로그래밍 언어 런타임 버전 (JDK 18 vs JDK 17)
- 시스템 라이브러리 및 의존성
- 환경 변수 및 설정 파일
이러한 환경 불일치 문제를 해결하기 위해 등장한 기술이 바로 가상화(Virtualization) 기술이다.
2. 1세대 가상화 기술: 가상 머신(VM)
2.1. 가상 머신이란 무엇인가?

가상 머신(Virtual Machine)은 물리적인 컴퓨터(호스트 머신) 위에 소프트웨어로 구현된 가상의 컴퓨터를 만드는 기술이다.
- 하이퍼바이저(Hypervisor): 물리적 서버 위에서 여러 가상 머신을 생성하고 관리하는 소프트웨어 계층이다. VMware, VirtualBox 등이 대표적이다.
- 게스트 OS(Guest OS): 각 가상 머신마다 설치되는 독립적인 운영체제다. VM1은 Ubuntu, VM2는 CentOS처럼 서로 다른 OS를 사용할 수도 있다.
- 애플리케이션: 각 게스트 OS 위에서 실행되는 프로그램이다.
2.2. 가상 머신은 어떻게 환경 불일치 문제를 해결했나?
가상 머신을 사용하면 다음과 같은 프로세스로 개발 및 배포가 이루어진다.
- 개발 환경 구성: 개발자는 Ubuntu 20.04에 JDK 18, 필요한 라이브러리를 모두 설치한다.
- 이미지 생성: 이 개발 환경 전체를 하나의 VM 이미지로 패키징한다. 용량은 보통 수 GB 정도 된다.
- 배포: 이 VM 이미지를 서버에 복사하고 실행한다.
- 실행: 서버는 호스트 OS와 상관없이, VM 이미지 안에 담긴 Ubuntu 20.04를 부팅하고 그 위에서 애플리케이션을 실행한다.
결과적으로, 서버의 환경과 무관하게 개발 환경과 완전히 동일한 환경에서 애플리케이션이 실행된다. 따라서 "내 PC에서는 잘 되는데..." 문제가 해결된다.
2.3. 가상 머신의 한계
이론적으로 완벽해 보이는 가상 머신에도 치명적인 단점이 있었다.
① 무겁다 (Heavy)
각 VM이 완전한 운영체제(게스트 OS) 를 포함하기 때문에 이미지 크기가 수 GB에 달한다. 디스크 공간을 많이 차지하고, 네트워크로 전송하는 데도 오랜 시간이 걸린다.
② 느리다 (Slow)
VM을 실행하려면 게스트 OS를 부팅하는 과정이 필요하다. 보통 수십 초에서 수 분이 소요되며, 이는 컨테이너에 비해 매우 느린 속도다.
③ 자원 소모가 크다 (Resource Intensive)
각 VM이 게스트 OS를 구동하기 위해 CPU, 메모리 등의 자원을 할당받아야 한다. 10개의 VM을 띄우면 10개의 OS가 각각 메모리를 차지하므로 자원 낭비가 심하다.
비유하자면: 가상 머신은 "집(애플리케이션)을 짓기 위해 땅(물리 서버)에 아파트 단지 전체(게스트 OS)를 짓는 것"과 같다. 집 한 채를 짓기 위해 단지 전체를 짓는 것은 너무 과하고 비효율적이다.
3. 2세대 가상화 기술: 도커 컨테이너
이러한 VM의 한계를 극복하고 등장한 것이 바로 컨테이너(Container) 기반 가상화 기술이고, 그 대표주자가 도커(Docker) 다.
3.1. 도커란?
도커는 컨테이너(Container) 라는 가볍고 독립적인 환경에서 애플리케이션을 실행하고 관리할 수 있게 해주는 오픈소스 가상화 플랫폼이다.
도커의 핵심 철학: "빌드(Build)하고, 쉽(Ship)하고, 런(Run)한다." 즉, 어떤 환경에서든 동일하게 실행될 수 있는 애플리케이션 패키지(이미지)를 만들고, 이를 어디서나 실행할 수 있게 한다.
3.2. 도커 컨테이너의 구조

- Docker Engine: 컨테이너를 생성하고 관리하는 도커의 핵심 엔진이다.
- 컨테이너: 호스트 OS의 커널을 공유하며, 애플리케이션 실행에 필요한 최소한의 라이브러리와 바이너리만 포함한다.
- 각 컨테이너는 호스트에서는 하나의 프로세스로 동작한다.
3.3. VM vs 도커 컨테이너: 핵심 차이점
| 특징 | 가상 머신 (VM) | 도커 컨테이너 |
| 구조 | 하이퍼바이저 위에 독립적인 게스트 OS를 가짐 | 호스트 OS의 커널을 공유하며 프로세스 수준 격리 |
| 이미지 크기 | OS 포함 → 수 GB | 애플리케이션 + 라이브러리 → 수 MB ~ 수백 MB |
| 실행 속도 | OS 부팅 필요 → 수십 초~수 분 | 프로세스 시작 수준 → 즉시 실행 (밀리초) |
| 메모리 사용량 | OS마다 메모리 할당 → 큰 오버헤드 | 프로세스 단위 사용 → 매우 적은 오버헤드 |
| 격리 수준 | 완전한 하드웨어 수준 격리 | 프로세스 수준 격리 (더 가볍지만 충분히 안전) |
비유로 이해하기:
- 가상 머신: "이삿짐을 싸려고 집 전체를 통째로 옮기는 것"이다. 거대하고 무겁다.
- 도커 컨테이너: "이삿짐을 표준화된 컨테이너 박스에 담아 옮기는 것"이다. 가볍고 표준화되어 있다.
실제 컨테이너 선박처럼, 도커 컨테이너는 표준화된 방식으로 애플리케이션을 포장하고 어디서나 동일하게 실행할 수 있게 해준다.
3.4. 도커의 주요 장점
① 가볍고 빠름
OS를 따로 띄우지 않아 디스크 용량과 메모리를 획기적으로 절약한다. 실행 속도가 VM에 비해 압도적으로 빠르다.
② 환경 일관성
"내 PC에서는 되는데..." 문제를 해결한다. 개발, 테스트, 운영 환경의 차이로 인한 장애를 원천 차단한다.
③ 모듈성 및 확장성
애플리케이션을 마이크로서비스로 나누고 각각 컨테이너화하기 쉽다. 필요에 따라 특정 컨테이너만 독립적으로 확장(scale-out)할 수 있다.
④ 버전 관리와 롤백
이미지 자체가 히스토리를 포함한다. 마치 Git처럼, 문제 발생 시 이전 버전 이미지로 손쉽게 롤백할 수 있다.
4. 정리: 왜 도커인가?
지금까지 살펴본 내용을 정리하면 다음과 같다.
- 환경 불일치 문제로 인해 개발 환경과 운영 환경의 차이가 큰 문제를 야기했다.
- 가상 머신(VM) 은 이 문제를 해결했지만, 무겁고 느리며 자원 소모가 크다는 한계가 있었다.
- 도커(Docker) 는 컨테이너 기술을 기반으로 VM의 장점(환경 격리)은 유지하면서, 단점(무거움, 느림)을 획기적으로 개선했다.
도커의 등장으로 개발자들은 이제 더 이상 "서버 환경"을 걱정할 필요 없이, 애플리케이션 코드 자체에 집중할 수 있게 되었다.
'Docker' 카테고리의 다른 글
| [BASIC #6] 컨테이너 간 통신: Docker Network 이해하기 (0) | 2025.06.01 |
|---|---|
| [BASIC #5] 데이터를 영구적으로 저장하는 법: Docker Volume (0) | 2025.05.31 |
| [BASIC #4] 나만의 이미지 만들기: Dockerfile 완전 정복 (0) | 2025.05.31 |
| [BASIC #3] 밀키트 비유로 완벽 이해하는 도커 이미지와 컨테이너 (0) | 2025.05.31 |
| [BASIC #2] 도커 설치부터 첫 컨테이너 실행까지 (Hello World 실습) (0) | 2025.05.31 |
