가상화와 QEMU/KVM · 하이퍼바이저 타입과 KVM 이 빠른 이유 · 이론
KVM 은 왜 네이티브에 가까운가
한 줄 요약
가상화 성능은 게스트가 커널 모드로 빠져나오는 횟수(VM Exit) 로 결정된다. 하드웨어 지원과 virtio 는 둘 다 그 횟수를 줄이는 기술이다.
왜 이게 필요했나
x86 은 원래 가상화하기 나쁜 아키텍처였다. 특권 명령 중 일부가 비특권 모드에서 실행해도 예외를 일으키지 않고 조용히 다른 값을 돌려주는 것들이 있었기 때문이다(이른바 "가상화 불가능 명령"). 그래서 초기 가상화는 두 갈래로 갈렸다.
- 전가상화(Full virtualization) — 게스트 코드를 실행 직전에 검사·재작성한다(바이너리 변환). 게스트 OS 를 고칠 필요가 없지만 느리다.
- 반가상화(Paravirtualization) — 게스트 OS 를 고쳐서 특권 명령 대신 하이퍼바이저를 직접 호출(hypercall)하게 한다. 빠르지만 게스트를 수정해야 한다.
여기에 인텔 VT-x / AMD-V 가 등장하면서 판이 바뀌었다. CPU 에 게스트 전용 실행 모드를 추가한 것이다.
어떻게 동작하나
하드웨어 지원 가상화
VT-x 는 CPU 에 두 개의 새 모드를 만든다. VMX root(하이퍼바이저)와 VMX non-root(게스트). 게스트는 자기 링 0 에서 그대로 돌지만, 하이퍼바이저가 정한 특정 사건이 일어나면 자동으로 root 모드로 빠져나온다. 이것이 VM Exit 다.
메모리도 하드웨어가 돕는다. EPT(Intel) / NPT(AMD)는 게스트 물리 주소 → 호스트 물리 주소 변환을 하드웨어 페이지 테이블로 처리한다. 이게 없던 시절에는 하이퍼바이저가 섀도 페이지 테이블을 소프트웨어로 유지해야 했고, 그게 성능의 큰 부분을 먹었다.
KVM 의 위치
KVM 은 별도의 하이퍼바이저가 아니라 리눅스 커널 모듈이다. 로드되는 순간 리눅스 커널 자체가 하이퍼바이저가 된다. 그래서 KVM 은 타입 1(베어메탈)과 타입 2(호스트형)의 경계에 있다 — 호스트 OS 위에서 돌지만 그 호스트 OS 가 곧 하이퍼바이저다.
실행 흐름은 이렇다.
QEMU (유저 공간) ├─ ioctl(KVM_RUN) ↓KVM 모듈 (커널) ├─ VMLAUNCH / VMRESUME ↓게스트 (VMX non-root) ├─ VM Exit 발생 ↓KVM 이 처리 가능하면 여기서 끝 (빠름)KVM 이 못 하면 QEMU 로 반환 (느림)KVM 이 커널에서 바로 처리하는 것: 대부분의 MSR 접근, 간단한 I/O 포트, EPT 위반, 외부 인터럽트.
QEMU 까지 올라가는 것: 복잡한 디바이스 I/O, MMIO, 일부 CPUID.
그래서 성능 튜닝의 방향이 정해진다. QEMU 까지 올라가는 Exit 를 줄여라.
QEMU 의 역할
QEMU 는 디바이스 모델이다. 게스트가 보는 가상 NIC, 디스크 컨트롤러, 타이머를 소프트웨어로 만들어 준다. KVM 없이 QEMU 만 쓰면 CPU 명령까지 전부 소프트웨어로 번역하는데, 그 엔진이 TCG(Tiny Code Generator) 다.
TCG 는 게스트 명령을 기본 블록 단위로 잘라 TCG IR 로 바꾸고, 다시 호스트 명령으로 번역해 캐시한다(Translation Block). 캐시와 체이닝 덕분에 순수 인터프리터보다는 훨씬 빠르지만, KVM 대비로는 여전히 10~100배 느리다.
| 항목 | 네이티브 | QEMU+KVM | QEMU(TCG) |
| --- | --- | --- | --- |
| CPU 연산 | 100% | 약 98% | 약 25% |
| 디스크 I/O (virtio) | 100% | 약 90% | 약 30% |
| 네트워크 (vhost-net) | 100% | 약 95% | 약 25% |
이 실습 환경에는 /dev/kvm 이 없다. 컨테이너에 그 장치를 넣어 주지 않았기 때문이다. 그래서 QEMU 는 -accel tcg 로 돈다. 부팅이 느린 것은 환경 탓이지 설정 실수가 아니다.
virtio — 반가상화의 귀환
에뮬레이트된 e1000 NIC 는 게스트가 레지스터를 건드릴 때마다 VM Exit 를 일으킨다. virtio 는 게스트와 호스트가 공유 메모리 링 버퍼로 소통하게 해서 Exit 를 극적으로 줄인다. 게스트에 virtio 드라이버가 필요하지만, 요즘 리눅스에는 기본으로 들어 있다.
| 장치 | 대비 성능 |
| --- | --- |
| virtio-net | e1000 대비 10배 이상 |
| virtio-blk | IDE 에뮬레이션 대비 2~5배 |
| virtio-scsi | 디스크 다수 연결에 유리 |
| vhost-net | 링 버퍼 처리를 커널에서 → 추가 향상 |
성능 문제로 신고가 들어오면 가장 먼저 물어볼 것이 "virtio 를 쓰고 있나" 다. 템플릿을 잘못 골라 IDE 로 돌고 있는 VM 이 의외로 많다.
현장에서 만나는 모습
중첩 가상화의 함정. 클라우드 VM 안에서 다시 KVM 을 쓰려면 중첩 가상화가 켜져 있어야 한다. 안 켜져 있으면 조용히 TCG 로 폴백해서 "왜 이렇게 느리지" 가 된다. /dev/kvm 존재 여부와 qemu-system-x86_64 -accel help 출력으로 확인한다.
CPU 모델을 host-passthrough 로 안 해서 성능이 안 나오는 경우. 기본 CPU 모델은 호환성을 위해 최신 명령어 확장을 감춘다. AVX 를 쓰는 워크로드라면 큰 차이가 난다. 대신 라이브 마이그레이션 호환성이 깨지므로 트레이드오프다.
다음 확인에서 볼 것
이어지는 퀴즈에서는 KVM 가속과 TCG 폴백, virtio 장치, CPU 모델의 성능·이식성
조건을 먼저 구분한다. 그 판단을 확인한 뒤 다음 모듈부터 qcow2 백킹 파일과
스냅샷, QEMU 시리얼 콘솔·모니터 소켓을 실습한다.