가상화 메커니즘: 하이퍼바이저와 컨테이너¶
이 문서는 시스템 가상화(System Virtualization)의 핵심인 하이퍼바이저의 작동 원리와, 컨테이너 기술(Docker)과의 격리 메커니즘 차이를 상세히 설명합니다.
1. 하이퍼바이저(Hypervisor) 작동 메커니즘¶
하이퍼바이저는 물리적 하드웨어 바로 위에서 실행되는 얇은 소프트웨어 계층으로, 물리적 자원을 다중화하여 여러 가상 머신(VM)이 동시에 실행될 수 있게 합니다.
1.1 CPU 가상화 (Privilege Levels & Instructions)¶
하이퍼바이저의 핵심 역할은 각 VM에 가상 CPU(VCPU)를 제공하고 이를 물리 CPU에 스케줄링하는 것입니다. 이 과정에서 권한 수준(Privilege Levels/Rings) 관리가 중요합니다.
-
권한 레벨 조정 (Ring Deprivileging):
- 전통적인 x86 아키텍처에서 OS 커널은 가장 높은 권한인 **Ring 0**에서 실행됩니다. 하지만 가상화 환경에서는 하이퍼바이저가 하드웨어를 통제해야 하므로 Ring 0를 차지합니다.
- 따라서 게스트 OS(Guest OS)는 **Ring 1**과 같은 낮은 권한 레벨로 밀려나 실행됩니다. 애플리케이션은 기존대로 Ring 3에서 실행됩니다. (Intel VT-x 등 최신 기술은 'Root Mode'를 도입해 이 구조를 단순화합니다).
-
명령어 처리 방식 (Traps & Hypercalls):
- 특권 명령(Privileged Instructions): 게스트 OS가 하드웨어 상태를 변경하려는 명령을 내리면, 권한 부족으로 인해 **트랩(Trap)**이 발생합니다. 하이퍼바이저는 이 트랩을 가로채서 명령을 검사하고 안전하게 에뮬레이션하거나 실행합니다.
- 민감 명령(Sensitive Instructions) 처리: x86 아키텍처의 일부 명령은 트랩을 발생시키지 않아 가상화를 어렵게 만듭니다. 이를 해결하기 위해 두 가지 방식이 주로 사용됩니다.
- 전가상화(Full Virtualization): 바이너리 변환(Binary Translation) 등을 통해 모든 명령을 에뮬레이션합니다. 수정되지 않은 OS를 실행할 수 있지만 오버헤드가 큽니다.
- 반가상화(Paravirtualization): 게스트 OS 커널을 수정하여, 민감한 작업을 수행할 때 **하이퍼콜(Hypercall)**이라는 특별한 시스템 호출을 통해 하이퍼바이저에게 작업을 요청합니다. 이는 트랩 오버헤드를 줄여 성능을 높입니다.
-
스케줄링: 하이퍼바이저는 물리 CPU 시간을 VCPU들에게 분배합니다. (예: Xen의 Credit Scheduler).
1.2 메모리 가상화 (Memory Virtualization)¶
게스트 OS는 자신이 연속된 물리 메모리를 독점한다고 착각하지만, 실제로는 파편화되어 있을 수 있습니다.
-
3단계 주소 변환:
- 가상 주소 (Virtual Address): 애플리케이션이 보는 주소.
- 의사 물리 주소 (Pseudo-physical Address): 게스트 OS가 인식하는 물리 메모리 주소 (0부터 시작).
- 머신 물리 주소 (Machine Physical Address): 실제 하드웨어의 물리 메모리 주소.
-
매핑 관리:
- 게스트 OS는 가상 주소를 의사 물리 주소로 매핑하는 페이지 테이블을 관리합니다.
- 하이퍼바이저는 의사 물리 주소를 실제 머신 물리 주소로 매핑합니다.
- 섀도우 페이지 테이블(Shadow Page Tables)**이나 하드웨어 지원(**EPT/NPT)을 통해 주소 변환을 가속화합니다.
1.3 I/O 및 장치 가상화 (Split Device Drivers)¶
I/O 처리는 성능 저하가 가장 크기 때문에 효율적인 구조가 필수적입니다 (예: Xen의 분할 드라이버 모델).
-
구조:
- 프론트엔드 드라이버 (Front-end Driver): 게스트 OS 내부에 존재하며, I/O 요청을 백엔드로 전달합니다.
- 백엔드 드라이버 (Back-end Driver): 실제 하드웨어에 접근 가능한 특권 도메인(Domain 0)에 존재하며, 실제 물리 장치와 통신합니다.
-
통신 방식:
- 공유 메모리(Shared Memory): 데이터 복사 비용을 줄이기 위해 사용.
- 이벤트 채널(Event Channel): 인터럽트와 유사한 알림(Notification)을 비동기적으로 주고받음.
2. Docker(컨테이너)와 VM의 비교¶
도커(컨테이너)와 가상 머신(VM)은 **격리의 대상**과 **커널 공유 여부**에서 가장 큰 차이를 보입니다.
2.1 기본 아키텍처 차이¶
| 특성 | 가상 머신 (VM) | 도커 (Container) |
|---|---|---|
| 가상화 대상 | 하드웨어 (Hardware Virtualization) | 운영체제 (OS Virtualization) |
| 커널 | 게스트 OS마다 별도의 커널 존재 | 호스트 OS의 커널 공유 |
| 격리 수준 | 높음 (하드웨어 수준의 완전한 격리) | 낮음 (커널 공유로 인한 상대적 취약성) |
| 성능 | 오버헤드 높음 (OS 실행 비용) | 오버헤드 낮음 (베어메탈에 근접) |
| 구현 기술 | Hypervisor, VT-x/AMD-V | Namespaces, Cgroups |
2.2 가상 머신(VM)의 격리 방식¶
VM은 하이퍼바이저를 통해 하드웨어 레벨의 강력한 격리를 제공합니다. * 하이퍼바이저: 물리적 자원을 배분하고 가상 하드웨어 인터페이스 제공. * 권한 레벨: 게스트 OS 커널은 Ring 0보다 낮은 권한(또는 Non-Root Mode)에서 실행되어, 하드웨어 직접 제어가 제한됨.
2.3 도커(컨테이너)의 격리 방식¶
도커는 리눅스 커널의 기능을 활용하여 프로세스 수준에서 격리 환경을 구축합니다.
- 네임스페이스(Namespaces): 시스템 리소스의 **뷰(View)를 격리**합니다.
pid(프로세스),net(네트워크),mnt(파일시스템),ipc,user,uts등.
- Cgroups (Control Groups): **물리적 자원 사용량을 제한**합니다. (CPU, 메모리, I/O 대역폭 등)
- 계층화된 파일 시스템: 이미지는 읽기 전용 레이어들의 조합이며, 실행 시 쓰기 가능 레이어가 추가됩니다.