하이퍼바이저
고친 사람 github-actions[bot]
하이퍼바이저는 컴퓨터 한 대를 여러 대처럼 나눠 쓰게 해 주는 소프트웨어입니다. 그 위에 운영체제를 여러 벌 올려도 저마다 기계를 따로 가진 것처럼 돕니다. 하이퍼바이저는 물리 프로세서와 메모리를 몫으로 나눠 줍니다. 그리고 서로의 몫을 넘보지 못하게 막습니다.
쉽고 빠른 이해
하이퍼바이저는 기계 한 대 위에 가상의 기계 여러 대를 만들어 돌리는 관리자입니다. 서버 한 대에 리눅스 서버 셋과 윈도우 서버 하나를 같이 띄우는 것이 이 일입니다.
운영체제는 기계 전체를 자기 것으로 알고 씁니다. 관리자 없이 둘을 올리면 같은 메모리를 서로 덮어씁니다. 그러면 기계 한 대에 운영체제 한 벌만 올릴 수 있습니다.
어떻게 도나:
- 하이퍼바이저가 운영체제보다 높은 권한을 쥐고 먼저 뜹니다
- 가상의 기계마다 프로세서와 메모리를 나눠 줍니다
- 그 안의 운영체제가 기계 전체를 건드리는 명령을 내면 하이퍼바이저가 가로채 대신 처리합니다
대가도 있습니다. 가로채고 대신 처리할 때마다 시간이 듭니다. 가상의 기계마다 운영체제를 한 벌씩 올리니 메모리를 많이 먹고 뜨는 데도 오래 걸립니다. 게스트가 모두 같은 커널로 충분하면 커널 하나를 나눠 쓰는 컨테이너를 씁니다.
상세
건전지를 뺀 리모컨을 아이에게 쥐여 준 거실을 떠올리면 됩니다. 아이가 버튼을 누르면 옆에 앉은 어른이 그것을 보고 자기 리모컨으로 같은 번호를 눌러 줍니다. 한 박자 늦게 화면이 바뀌면 아이는 자기가 텔레비전을 돌렸다고 믿습니다.
하이퍼바이저가 맡는 일
하이퍼바이저가 만들어 돌리는 기계를 가상 머신이라고 부릅니다. 줄여서 VM(Virtual Machine, 가상 머신)이라고도 합니다. 소프트웨어로 만든 기계 한 벌이라서, 그 위에 운영체제를 설치하고 켜고 끌 수 있습니다.
가상 머신 안에 올라간 운영체제를 게스트 운영체제라고 부릅니다. 하이퍼바이저가 깔린 물리 기계는 호스트입니다.
하이퍼바이저는 VMM(Virtual Machine Monitor, 가상 머신 모니터)이라고도 부릅니다. 운영체제를 프로그램들의 감독자(supervisor)라고 부르던 데서, 그 감독자 위에 하나 더 선다는 뜻으로 하이퍼바이저라는 이름이 붙었습니다.
하이퍼바이저가 맡는 일은 셋으로 갈립니다.
| 일 | 무엇을 하나 | 이 일이 없으면 |
|---|---|---|
| 나누기 | 프로세서 시간 · 메모리 · 디스크와 네트워크 장치를 가상 머신마다 나눠 줍니다 | 한 게스트가 기계를 독차지합니다 |
| 가두기 | 한 가상 머신이 다른 가상 머신의 메모리를 읽거나 쓰지 못하게 막습니다 | 한 게스트의 버그나 공격이 옆 게스트로 번집니다 |
| 흉내 내기 | 게스트가 기계를 직접 만지려는 명령을 가로채, 그 게스트에게 주어진 범위 안에서 같은 결과를 만들어 줍니다 | 게스트 둘이 같은 장치를 동시에 만져 엉킵니다 |
세 일 가운데 셋째가 하이퍼바이저를 가장 하이퍼바이저답게 만듭니다.
flowchart TD
subgraph A["가상 머신 A"]
A1["응용 프로그램"] --> A2["게스트 운영체제 · 리눅스"]
end
subgraph B["가상 머신 B"]
B1["응용 프로그램"] --> B2["게스트 운영체제 · 윈도우"]
end
A2 --> H["하이퍼바이저"]
B2 --> H
H --> W["호스트 하드웨어 · 프로세서 · 메모리 · 장치"]
그림에서 게스트 운영체제 둘은 서로를 안 거치고 곧장 하이퍼바이저에 닿습니다. 물리 하드웨어에 닿는 길은 하이퍼바이저 하나뿐입니다. 아래 소절 셋이 셋째 일인 흉내 내기를 차례로 풉니다.
운영체제보다 높은 권한
프로세서, 곧 CPU(Central Processing Unit, 중앙 처리 장치)는 코드가 도는 권한을 몇 단계로 나눕니다. 이제부터는 CPU 라고 부릅니다. 응용 프로그램은 낮은 권한에서 돕니다. 운영체제의 커널은 높은 권한에서 돕니다. 응용 프로그램이 남의 메모리를 함부로 못 건드리는 것이 이 구분 덕분입니다.
높은 권한에서만 실행되는 명령을 특권 명령이라고 합니다. 기계 전체에 영향을 주는 명령이라 아무나 못 내게 막아 둔 것입니다. 주소 표를 바꾸는 명령이 대표입니다. 주소 표는 프로그램이 보는 메모리 주소를 실제 메모리 위치로 바꿔 주는 표입니다.
인터럽트를 켜고 끄는 명령도 특권 명령입니다. 인터럽트는 타이머나 키보드 같은 장치가 CPU 에게 지금 하던 일을 멈추고 자기를 처리해 달라고 끼어드는 신호입니다. 이 신호를 끄면 기계 전체가 장치에 반응하지 않게 됩니다.
문제는 게스트 커널도 자기가 가장 높은 권한이라고 믿는다는 점입니다. 게스트 둘이 각자 주소 표를 바꾸면 서로의 메모리가 엉킵니다. 그래서 하이퍼바이저는 커널보다 한 단계 더 높은 권한에서 돕니다. 게스트 커널은 그보다 낮은 권한으로 내려서 돌립니다.
특권 명령을 가로채는 흐름
게스트 커널은 낮은 권한으로 내려와 있지만 그 사실을 모릅니다. 그래서 평소처럼 특권 명령을 냅니다. 이때 CPU 는 그 명령을 실행하지 않고 멈춘 뒤, 제어를 하이퍼바이저로 넘깁니다. 이렇게 낮은 권한의 코드가 멈추고 제어가 위로 넘어가는 일을 트랩(trap)이라고 부릅니다.
하이퍼바이저는 게스트가 무엇을 하려 했는지 봅니다. 그리고 그 게스트에게 나눠 준 메모리 안에서만 같은 결과를 만들어 줍니다. 물리 메모리를 가리키는 주소 표를 바꾸는 대신, 그 게스트용으로 따로 둔 표를 고치는 식입니다. 이 방식을 트랩과 에뮬레이션이라고 부릅니다.
sequenceDiagram
participant 게스트 as 게스트 커널
participant CPU
participant 하이퍼 as 하이퍼바이저
게스트->>CPU: 특권 명령
CPU->>하이퍼: 트랩 · 제어를 넘김
Note over 하이퍼: 이 게스트의 범위 안에서 결과를 흉내 냄
하이퍼->>CPU: 게스트로 돌려보냄
CPU-->>게스트: 다음 명령부터 이어서 실행
덧셈이나 메모리 읽기 같은 평범한 명령은 가로채지 않습니다. 물리 CPU 에서 곧장 돕니다. 그래서 게스트 코드 대부분은 가상 머신 밖과 거의 같은 속도로 돕니다. 느려지는 것은 트랩이 일어나 오갈 때입니다.
가로채기를 돕는 방법
트랩과 에뮬레이션은 특권 명령이 낮은 권한에서 반드시 멈춘다는 가정에 기댑니다. 그런데 예전 x86 CPU 에는 멈추지 않는 명령이 섞여 있었습니다. 인터럽트를 켜고 끄는 표시를 함께 바꾸는 POPF(pop flags, 플래그 꺼내기) 명령이 그렇습니다. 높은 권한에서 내면 그 표시가 바뀝니다. 낮은 권한에서 내면 오류도 트랩도 없이 그 표시만 안 바꾸고 넘어갑니다.
게스트 커널은 인터럽트를 껐다고 믿습니다. 그러나 인터럽트는 켜진 채입니다. 트랩이 없으니 하이퍼바이저는 이 일을 알아챌 수도 가로챌 수도 없습니다.
이 구멍을 메우는 방법이 셋 있습니다.
| 방법 | 어떻게 하나 | 게스트가 알아채나 |
|---|---|---|
| 이진 변환 | 게스트 코드를 실행하기 직전에 훑어서, 문제 되는 명령을 하이퍼바이저를 부르는 코드로 바꿔 끼웁니다 | 모릅니다 |
| 반가상화 | 게스트 운영체제의 소스를 고쳐, 특권 명령을 내는 대신 하이퍼바이저를 직접 부르게 합니다. 이 부름을 하이퍼콜이라고 합니다 | 압니다. 고친 운영체제만 올라갑니다 |
| 하드웨어 가상화 확장 | CPU 가 하이퍼바이저 전용 권한 모드를 따로 두고, 가로챌 명령을 하드웨어가 직접 걸러 줍니다 | 모릅니다 |
세 방법은 누가 수고를 지느냐가 다릅니다. 이진 변환은 하이퍼바이저가, 반가상화는 게스트 운영체제가, 하드웨어 가상화 확장은 CPU 가 집니다. 지금의 서버용 CPU 는 대개 하드웨어 가상화 확장을 갖추고 있어서, 하이퍼바이저도 주로 이 방법에 기댑니다.
타입 1 과 타입 2
하이퍼바이저는 무엇 위에 설치되느냐로 둘로 가릅니다. 하드웨어 바로 위에 올라가면 타입 1, 평범한 운영체제 위에 응용 프로그램처럼 설치되면 타입 2 입니다. 타입 1 을 베어메탈(bare metal), 타입 2 를 호스티드(hosted)라고도 부릅니다.
flowchart TD
subgraph T1["타입 1 · 베어메탈"]
G1["게스트 운영체제들"] --> V1["하이퍼바이저"]
V1 --> W1["하드웨어"]
end
subgraph T2["타입 2 · 호스티드"]
G2["게스트 운영체제들"] --> V2["하이퍼바이저 · 응용 프로그램"]
V2 --> O2["호스트 운영체제"]
O2 --> W2["하드웨어"]
end
타입 2 는 층이 하나 더 있습니다. 게스트의 요청이 호스트 운영체제를 한 번 더 거쳐 하드웨어에 닿습니다. 대신 이미 쓰던 노트북에 프로그램 하나 깔듯 설치할 수 있습니다.
| 타입 1 | 타입 2 | |
|---|---|---|
| 장치를 다루는 주체 | 하이퍼바이저가 직접 | 호스트 운영체제에 맡김 |
| 주로 쓰는 곳 | 데이터센터 서버 · 클라우드 | 개발자 노트북 · 데스크톱 |
| 흔히 드는 예 | Xen · VMware ESXi · Hyper-V | VirtualBox · VMware Workstation |
이 갈림이 늘 깔끔하지는 않습니다. KVM(Kernel-based Virtual Machine, 커널 기반 가상 머신)은 리눅스 커널 안에 들어가 커널 자체를 하이퍼바이저로 만듭니다. 리눅스라는 운영체제 위에 있다고 보면 타입 2 입니다. 커널이 곧 하이퍼바이저라고 보면 타입 1 입니다.
컨테이너와 가르는 선
컨테이너도 기계 한 대에서 여러 작업을 떼어 돌립니다. 둘을 가르는 것은 커널의 수입니다. 가상 머신은 저마다 자기 커널을 한 벌씩 올립니다. 컨테이너들은 호스트 커널 하나를 나눠 씁니다. 커널은 네임스페이스 같은 기능으로 서로 보이는 범위만 가립니다.
그래서 컨테이너는 가볍고 빨리 뜹니다. 운영체제를 새로 부팅하지 않기 때문입니다. 대신 컨테이너끼리 떼어 놓는 격리가 커널 하나에 기댑니다. 그 커널에 구멍이 나면 컨테이너 전부가 함께 드러납니다. 가상 머신은 그 사이에 하이퍼바이저라는 격리 벽이 하나 더 있습니다.
고르는 조건은 이렇게 갈립니다. 게스트마다 다른 운영체제나 다른 커널이 필요하면 가상 머신이 필요합니다. 리눅스 서버에서 윈도우를 돌리는 경우입니다. 같은 커널로 충분하고 작업을 빨리 많이 띄워야 하면 컨테이너를 씁니다.
둘을 겹쳐 쓰기도 합니다. 하이퍼바이저가 만든 가상 머신 안에서 컨테이너를 여럿 돌리는 식입니다.
가상 머신 안에 컨테이너를 올리는 일은 리눅스 커널이 없는 기계에서도 벌어집니다. 리눅스 컨테이너를 돌리려면 리눅스 커널부터 있어야 합니다. 그래서 Docker Desktop 은 맥이나 윈도우에서 하이퍼바이저로 작은 리눅스 가상 머신을 띄우고, 그 안에서 컨테이너를 돌립니다.
클라우드의 서버 한 대
클라우드에서 빌리는 서버 한 대는 대개 하이퍼바이저가 만든 가상 머신입니다. 사업자는 물리 서버 한 대를 여러 고객에게 나눠 빌려줍니다. 고객끼리 서로의 메모리와 디스크를 못 보게 막는 벽이 하이퍼바이저입니다.
고객이 서버 크기를 고르면, 하이퍼바이저가 그만큼의 CPU 와 메모리를 나눠 줍니다. 이때 게스트가 보는 CPU 한 개를 vCPU(virtual CPU, 가상 CPU)라고 부릅니다. vCPU 는 물리 코어가 아니라, 하이퍼바이저가 물리 코어의 실행 시간을 나눠 이어 붙인 것입니다.
자원을 나눠도 모든 것이 칼같이 나뉘지는 않습니다. 같은 물리 서버를 쓰는 옆 가상 머신이 바쁘면, CPU 캐시나 디스크를 두고 다투느라 내 가상 머신이 느려질 수 있습니다. 이 현상을 시끄러운 이웃이라고 부릅니다.
치르는 값
하이퍼바이저를 쓰면 세 가지가 나빠집니다.
- 오가는 시간. 트랩이 일어날 때마다 게스트와 하이퍼바이저 사이를 오가는 시간이 듭니다. 디스크나 네트워크처럼 장치를 자주 만지는 작업일수록 이 시간이 쌓입니다
- 메모리와 디스크. 가상 머신마다 운영체제를 한 벌씩 올리므로, 그 운영체제가 먹는 메모리와 디스크가 가상 머신 수만큼 늘어납니다
- 켜는 시간. 가상 머신을 켤 때마다 운영체제 부팅을 한 번씩 거칩니다
컨테이너는 이 값을 안 치르는 대신 격리를 커널 하나에 맡깁니다.
관련 항목
하이퍼바이저가 만들어 돌리는 대상과 역할
가상 머신 · 게스트 · 호스트 · vCPU · 가상 디바이스
하이퍼바이저가 특권 명령을 다루는 방식
트랩과 에뮬레이션 · 특권 명령 · 이진 변환 · 반가상화 · 하이퍼콜 · 하드웨어 가상화 확장 · Intel VT-x · AMD-V · 중첩 가상화
하이퍼바이저가 메모리를 나누는 데 쓰는 장치
가상 메모리 · 페이지 테이블 · 섀도 페이지 테이블 · 2단계 주소 변환 · 메모리 오버커밋
하이퍼바이저가 기대는 하드웨어와 운영체제 부품
CPU · 커널 · 인터럽트 · 사용자 공간 · 운영체제 · 디바이스 드라이버
하이퍼바이저를 구현한 제품
KVM · Xen · VMware ESXi · Hyper-V · VirtualBox · VMware Workstation · QEMU · Firecracker
하이퍼바이저의 하위 종류
타입 1 하이퍼바이저 · 타입 2 하이퍼바이저 · 마이크로VM · 에뮬레이터
하이퍼바이저와 격리 방식을 두고 견주는 기술
컨테이너 · 네임스페이스 · cgroups · 샌드박스 · 격리
하이퍼바이저를 바탕에 둔 서비스와 도구
클라우드 · Docker · 인스턴스 유형 · 머신 이미지 · 라이브 마이그레이션 · 시끄러운 이웃 · 멀티 테넌시
다른 이름: hypervisor · 가상 머신 모니터 · virtual machine monitor · VMM