가상화(Virtualization): VM과 컨테이너, 그리고 Docker
가상화(Virtualization) 는 하드웨어 자원을 소프트웨어적으로 추상화해, 하나의 물리 컴퓨터를 여러 개의 독립된 시스템처럼 쓰는 기술이다. 이를 통해 하나의 물리 컴퓨터 위에서 여러 운영체제(OS) 와 여러 애플리케이션 환경 을 서로 격리된 상태로 실행할 수 있다.
1. 가상화의 두 종류: VM vs 컨테이너
| 항목 | VM (Virtual Machine) | Docker (Container) |
|---|---|---|
| OS 포함 | VM마다 Guest OS 포함 | 호스트 커널 공유, 별도 OS 없음 |
| 부팅 속도 | 느림 (분 단위) | 매우 빠름 (초 단위) |
| 성능 | 비교적 낮음 | 거의 네이티브 수준 |
| 자원 사용 | 무거움 (OS 단위로 메모리 사용) | 가벼움 (커널 공유) |
| 격리성 | 강력함 | 비교적 약함 (커널 공유) |
| 이미지 크기 | 수 GB | 수 MB ~ GB |
| 사용 사례 | 전체 OS 시뮬레이션, 강한 격리 | 마이크로서비스, CI/CD, 빠른 배포 |
전통적인 VM 구조
하드웨어 위에 하이퍼바이저(Hypervisor)를 두고, 각 VM이 Guest OS를 통째로 포함한다.
| 계층 | 내용 |
|---|---|
| 4. 가상 머신 | VM 1 / VM 2 / VM 3 — 각각 Guest OS + App + Libs |
| 3. 하이퍼바이저 | Hypervisor |
| 2. 호스트 OS | Host OS |
| 1. 물리 하드웨어 | Hardware |
각 VM이 운영체제 전체를 포함하므로 리소스가 무겁다.
컨테이너(Docker) 구조
컨테이너는 Guest OS 없이 호스트 OS의 커널을 공유하고, 애플리케이션과 라이브러리만 담는다.
| 계층 | 내용 |
|---|---|
| 4. 컨테이너 | Container 1 / 2 / 3 — 각각 App + Libs (Guest OS 없음) |
| 3. 컨테이너 엔진 | Docker Engine |
| 2. 호스트 OS | Host OS (Linux 등) |
| 1. 물리 하드웨어 | Hardware |
불필요한 OS가 없어 가볍고 빠르며, 자원을 효율적으로 쓴다.
2. 가상화가 필요한 이유
| 이유 | 설명 |
|---|---|
| 리소스 효율화 | 서버 1대를 여러 대처럼 나눠 쓰며 하드웨어 낭비를 줄인다 |
| 격리성(Isolation) | 서로 다른 환경을 완전히 분리해, 한 앱이 죽어도 다른 앱에 영향이 없다 |
| 테스트/배포 자동화 | 개발 → 테스트 → 배포까지 동일한 환경을 유지한다 (특히 Docker) |
| 보안성 | 서로 다른 사용자·프로세스를 독립적으로 운영할 수 있다 |
3. 가상화의 장점과 단점
장점
| 장점 | 설명 |
|---|---|
| 자원 효율성 | 물리 서버 하나로 여러 작업 수행 |
| 유연성 | 필요한 환경만 골라 빠르게 생성 |
| 테스트 용이 | 다양한 OS·설정을 실험 가능 |
| 격리성 보장 | 하나가 망가져도 다른 프로세스에 영향 없음 |
| 배포 자동화 | Dockerfile로 같은 환경을 어디서든 재현 |
단점
| 단점 | 설명 |
|---|---|
| 성능 오버헤드 | 특히 VM은 OS 전체를 돌려 무겁다 |
| 복잡도 증가 | 관리·설정·보안에서 신경 쓸 게 많다 |
| 네트워크/디스크 이슈 | 가상화 계층이 개입되면 속도 손해 가능성 |
| 커널 의존성 (Docker) | 호스트 커널에 의존 → 커널 레벨 취약점에 노출 |
4. C 개발에 Docker를 쓰는 이유
4-1. 개발 환경 일관성
시스템마다 컴파일러 버전·라이브러리·경로가 달라 “내 컴퓨터에선 되는데 다른 데선 안 되는” 문제가 생긴다. Dockerfile에 환경을 정의해두면 어디서든 동일한 환경에서 C 코드를 실행할 수 있다.
FROM gcc:latest
COPY . /app
WORKDIR /app
RUN gcc main.c -o main
CMD ["./main"]
이렇게 하면 어디서 빌드해도 gcc 빌드 환경이 동일해진다.
4-2. 빌드 & 테스트 자동화
Makefile, CMake 빌드 시스템을 컨테이너에 넣어두면 코드를 푸시할 때 자동으로 빌드된다. GitHub Actions, Jenkins 같은 CI/CD와도 연동이 쉽다.
4-3. 실행 환경 호환 문제 해결
리눅스에서만 도는 코드라도, 맥이나 윈도우에서 Docker로 리눅스 환경을 띄우면 그대로 실행된다. 특정 라이브러리나 커널 기능이 필요한 프로젝트도 해당 환경을 그대로 재현할 수 있다.
4-4. 강의 / 과제 제출용
실습 환경이 제각각이면 문제가 생기므로 Docker로 통일하면 편하다. 팀원이나 교수에게 “이 Dockerfile 돌리면 됩니다”라고 전달하면 끝이다.
4-5. 보안성
악성 코드 실험이나 위험한 시스템 호출도 Docker의 격리된 환경에서 안전하게 테스트할 수 있다.