[네이버클라우드 기술&경험] 가상화 개념 이해하기#1, QEMU vs KVM
이번 시간을 포함해 총 2회차에 걸쳐 가상화 기술에 대해 탐구해 보겠습니다.
Part.1에서는 QEMU와 KVM을 비교함으로써 가상화에 대한 기본 개념을 이해하고 추가적으로 I/O 가상화의 작동 원리를 간략히 알아보고,
Part. 2에서는 Part. 1 후반부에 언급한 I/O 가상화의 성능을 높이기 위한 솔루션인 SPDK에 대해 알아보는 시간을 가져보도록 하겠습니다.
목차
1. QEMU, KVM Overview
1.1. 하이퍼바이저 (Hypervisor)
1.2. 에뮬레이션 vs 시뮬레이션 (Emulation vs Simulation)
1.3. 전 가상화 vs 반 가상화 (Full-Virtualization vs Para-Virtualization)
1.4. QEMU vs KVM
2. I/O 가상화
2.1. I/O Full-virtualization
2.2. I/O Para-virtualization
2.3. vhost
1. QEMU-KVM Overview
1.1 하이퍼바이저
QEMU와 KVM은 수많은 Hypervisor 중 하나입니다. Hypervisor는 서로 다른 복수 개의 OS를 단일 물리 머신 위에서 스케줄링 할 수 있는 소프트웨어이며 이는 [그림 1]과 같이 두 개의 타입으로 나누어집니다.
[그림 1]의 Type1의 경우, 운영체제 없이 바로 Hypervisor가 설치되며, 해당 머신은 오직 Hypervisor로만 사용할 수 있습니다. Native type이라고도 불리며 XEN, VMware의 ESXi와 같은 것들이 여기에 해당됩니다.
반면 Type2의 경우 운영체제를 설치하고, 그 위에 Hypervisor가 실행되는 형태로써 Hypervisor 외에 다른 프로세스들도 띄울 수 있는 장점이 있습니다. Hosted type이라고도 불리며 KVM, QEMU, Virtualbox가 이 유형에 해당합니다. 상용 여부, Live Migration, Network 등을 정리하면 아래 [그림 2]와 같이 나타낼 수 있습니다.
1.2 에뮬레이션 vs 시뮬레이션 (Emulation vs Simulation)
QEMU와 KVM의 차이를 이해하기 위해서는 에뮬레이션과 시뮬레이션의 차이를 먼저 알아야 합니다.
“Emulation”
에뮬레이션은 호스트 머신에 존재하지 않는 하드웨어 및 아키텍처를 가상머신에게 제공하는 것입니다. 윈도우 데스크탑 머신에서 동작하는 오락실 게임, x86 머신에서 동작하는 ARM 기반 Android OS가 그 예입니다.
[그림 3]과 같이 오락실 게임을 동작시키기 위해서는 오락실에 있는 게임기와 같은 하드웨어가 있어야 하지만 실제로 윈도우 데스크탑엔 그런 하드웨어가 없죠. 그렇지만 게임이 동작하는 이유는 소프트웨어로 모든 하드웨어의 동작을 ‘에뮬레이션’했기 때문입니다. QEMU는 대표적인 에뮬레이터 중 하나로써 매우 다양한 종류의 하드웨어를 소프트웨어로 구현해둔 Hypervisor입니다.
또한 모바일 기기에 들어가는 CPU 아키텍처는 대부분 ARM 프로세서 기반인데, 이것을 x86 머신 위에서 돌린다면 이 또한 에뮬레이션입니다. 이를 위해 QEMU는 가상머신에서 생성된 ARM 기반의 명령어를 x86 기반 명령어로 번역을 해서 처리합니다. 이것을 Binary Translation이라고 부릅니다. 에뮬레이터는 이렇듯 물리 장치를 소프트웨어로 구현하고, Binary Translation을 수행함으로써 가상머신으로 하여금 마치 그러한 물리적인 환경이 존재하는 것처럼 보이게 해줍니다.
하지만 물리 장치의 동작을 소프트웨어로 동작시키기 때문에 상대적으로 매우 느릴 수밖에 없습니다. 오락실 게임을 윈도우 데스크탑에서 동작시킬 때 오락실처럼 반응이 빠르지 않고 버벅거리는 현상을 떠올리면 이해하기 쉽습니다.
“Simulation”
시뮬레이션은 호스트 머신에 존재하는 하드웨어 및 아키텍처를 이용하여 가상머신에 제공하는 것입니다.
즉, 위에서 설명드린 에뮬레이션의 Binary Translation을 수행하지 않으며, 호스트 머신에 존재하는 하드웨어만을 기반으로 가상 머신의 환경을 꾸밀 수 있습니다. 가령 8코어 Xeon x86 서버에 설치된 Ubuntu에서 동작하는 1 코어 x86 기반 CentOS가 그 예입니다.
이 경우 가상 머신에서 생성된 명령어를 번역할 필요가 없으므로 명령어를 호스트 머신이 직접 처리하게 되고, QEMU에 비해 성능을 대폭 향상시킬 수 있습니다. 보통 QEMU로 가상머신을 생성할 때, 호스트 머신과 같은 종류의 CPU라면 KVM 옵션을 Enable 하게 됩니다. (e.g., -enable-kvm).
이를 통해 가상 머신은 순수 QEMU에 비해 훨씬 더 빠르게 동작할 수 있게 됩니다. 아래 [그림 4]의 Performance Criteria를 보시면 해당 내용을 확인할 수 있습니다.
1.3 전 가상화(Full Virtualization) vs 반 가상화(Para Virtualization)
다음으로 알아볼 개념은 전 가상화와 반 가상화의 차이입니다. 에뮬레이션, 시뮬레이션과 자주 혼동되는 개념이므로 주의하셔야 합니다. 먼저 전 가상화입니다.
“Full Virtualizaion”
전 가상화는 가상 머신이 구동할 OS 혹은 Device Driver (이하 DD)에 특별한 수정을 하지 않고 그대로 사용할 수 있는 경우를 말합니다. 이 경우 물리 환경에서 동작하는 운영체제와 장치의 드라이버들을 그대로 가상 머신에서 사용할 수 있게 됩니다.
가령 사용자는 QEMU나 KVM을 이용해서 가상 머신을 생성할 때 통신이 필요한 경우 Network driver를 선택해야 할 것입니다. 이때 사용자가 e1000이라는 인텔의 1G NIC Driver를 선택할 경우 이것은 Network DD를 전 가상화해서 사용한다고 얘기할 수 있습니다. 반 가상화에 비해 상대적으로 속도는 느리지만 가상 머신 입장에서는 실제와 동일한 장치 드라이버가 설치된 것으로 인식하게 됩니다.
“Para Virtualization”
반 가상화는 위의 전 가상화의 단점을 해결하기 위해 수정된 Guest OS, 혹은 DD를 사용하는 경우를 말합니다. 대표적으로 Xen의 경우 가상화 환경을 최적화하기 위해 Hyper Call을 활용하고 있는데 이는 반 가상화에 해당합니다.
또한 NIC의 경우 QEMU, KVM은 VirtIO라는 반 가상화 인터페이스를 통해 e1000과 같은 전 가상화 NIC 인터페이스의 성능을 대폭 향상시키는 방법을 제공해 줍니다.
1.4 QEMU vs KVM
지금까지 알아본 개념으로 QEMU와 KVM의 차이를 정리해 보겠습니다.
QEMU는 에뮬레이션이 가능한 Hypervisor로써 호스트 머신과 독립적으로 가상화된 하드웨어 및 아키텍처를 동작 시킬 수 있습니다. 하지만 폭넓은 가상화 옵션에 비해 성능이 떨어지는 단점이 있습니다. [그림 5]와 같이 커널을 컴파일하는데 걸리는 시간을 비교해보면 KVM에 비해 현저히 오랜 시간이 소요되는 것을 볼 수 있습니다.
KVM은 같은 종류의 CPU 아키텍처만 가상화할 수 있는 Hypervisor입니다.
QEMU처럼 Binary Translation을 수행하지 않기 때문에 가상머신이 생성한 명령어를 호스트 머신이 직접 처리하고, 성능이 대폭 향상됩니다. KVM은 커널 모듈로 동작하며 VirtIO와 같은 반 가상화 인터페이스를 Linux, FreeBSD, Windows 등과 같이 다양한 OS에 대해 지원함으로써 DD의 전 가상화로 인해 발생하는 성능 감소를 해결할 수 있습니다.
[그림 6]과 같이 QEMU와 KVM은 서로의 단점을 보완하며 같은 호스트 머신상에서 필요에 따라 함께 사용할 수 있습니다. 예를 들면 CPU는 호스트 머신과 게스트 머신을 동일한 아키텍처로 가져가면서 KVM을 통해 가속화하고, DD는 QEMU의 도움을 받아 e1000과 같은 드라이버로 에뮬레이션 하여 게스트 머신이 구동할 Guest OS와 Guest DD의 수정 없이 전 가상화를 할 수 있을 것입니다.
I/O 가상화
2.1 I/O Full-virtualization
I/O 전 가상화는 앞서 “Full Virtualization” 파트에서 설명드린 내용처럼 I/O를 위해 사용되는 DD를 가상 머신용으로 특별히 수정하지 않고 Guest OS에서 사용하는 경우를 말합니다.
DD에 대한 에뮬레이션은 QEMU가 수행하게 되며 호출 순서는 [그림 7]과 같습니다. Guest Kernel에서 I/O Event를 발생시키면 호스트 머신의 Kernel에서 동작하던 KVM 모듈이 1차적으로 요청을 전달받고 QEMU의 I/O 에뮬레이션을 호출합니다.
이것이 호스트 머신의 DD를 통해 실제 물리 장치에 접근한 다음 해당 정보는 QEMU, KVM module을 통해 Guest OS의 가상 IRQ (Interrupt Request Line)로 전달됩니다.
이 방식은 가상화 수준이 높고 직관적이지만 I/O의 성능은 크게 낮아집니다. 주요한 원인으로는 Kernel Space에서 동작하는 KVM Module과 User Space의 QEMU Emulator 사이의 Mode Transition Overhead입니다. KVM과 QEMU이 서로를 호출하며 I/O 요청 하나하나를 처리하기 때문에 처리 속도가 느려지는 것입니다.
2.2 I/O Para-virtualization
I/O 전 가상화의 문제를 해결하기 위해 등장한 반 가상화 I/O 인터페이스가 바로 VirtIO입니다. VirtIO Driver의 Frontend는 가상머신 내의 커널에서 구동되며, [그림 8]과 같이 호스트 머신의 QEMU와 공유하는 메모리 공간인 Virtqueue를 통해 Device Backend와 연결되어 있습니다.
이를 통해 불필요한 Memory Copy, Mode Transition을 감소시켜 성능을 대폭 향상시킬 수 있습니다. VirtIO는 네트워크 통신을 위한 virtio-net, 저장 장치를 위한 virtio-blk, virtio-scsi 등이 있습니다.
2.3 vhost
마지막으로 설명드릴 개념은 vhost입니다. 이는 아래 [그림 9]와 같이 QEMU Emulator에 구현되어 있던 VirtIO backend를 커널에서 직접 수행함으로써 성능을 더욱 향상시킨 모듈입니다.
Vhost는 다양한 게스트 머신이 호출하는 I/O가 QEMU Emulator로 Serialize 되는 것을 막아주어 Global Mutex를 벗어날 수 있게 함으로써 성능의 Scalability를 보장할 수 있습니다. Vhost의 종류에는 vhost-net, vhost-scsi, vhost-blk 등이 있습니다.
이상으로 QEMU, KVM을 중심으로 가상화에 대한 개념들을 살펴보았습니다.
컴퓨팅, 네트워크, 스토리지의 가상화 기술은 긴 시간 동안 꾸준히 발전되어 왔으며 최근까지도 다양한 요구 사항들을 해결하기 위해 계속해서 변화하고 발전하는 분야입니다. 다음 시간에는 이러한 가상화 기술 중 최근 다양한 논문과 연구결과가 쏟아지고 있는 스토리지 가상화에 대한 최신 동향을 중점적으로 다루어 보도록 하도록 하겠습니다.
감사합니다.