LabHub
배우기 러닝패스 코스

仮想化とQEMU/KVM

KVMはなぜネイティブに近いのか

LabHub 에서 이어서 보기

한국어 원문으로 표시합니다.

한 줄 요약

가상화 성능은 게스트가 커널 모드로 빠져나오는 횟수(VM Exit) 로 결정된다. 하드웨어 지원과 virtio 는 둘 다 그 횟수를 줄이는 기술이다.

概念マップ: 게스트가 커널 모드로 빠져나오는 횟수(VM Exit)・비특권 모드에서 실행해도 예외를 일으키지 않고 조용히 다른 값을 돌려주는・전가상화(Full virtualization)・반가상화(Paravirtualization)

왜 이게 필요했나

x86 은 원래 가상화하기 나쁜 아키텍처였다. 특권 명령 중 일부가 비특권 모드에서 실행해도 예외를 일으키지 않고 조용히 다른 값을 돌려주는 것들이 있었기 때문이다(이른바 "가상화 불가능 명령"). 그래서 초기 가상화는 두 갈래로 갈렸다.

여기에 인텔 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 시리얼 콘솔·모니터 소켓을 실습한다.