[펌] libvirt 가상화 라이브러리 분석

황선욱 2011.05.24 01:58 조회 수 : 20833

스터디 도중 언급되었던 libvirt 관련 자료입니다.

 

 

libvirt 가상화 라이브러리 분석

손쉬운 Linux 가상화를 위한 API

 

요약: libvirt 라이브러리는 Linux의 가상화를 위한 Linux API로 Xen 및 KVM을 포함한 다양한 하이퍼바이저뿐만 아니라 다른 운영 체제를 위한 QEMU 및 일부 가상화 제품을 지원합니다. 이 기사에서는 libvirt와 그 사용법 및 아키텍처에 대해 설명합니다.

 

확장형 컴퓨팅(클라우드 컴퓨팅)과 관련하여 libvirt는 가장 중요한 라이브러리 중 하나이지만 많이 알려져 있지는 않다. Libvirt는 호스트에서 실행 중인 게스트 운영 체제를 안전하게 관리할 수 있는 hypervisor-agnostic API를 제공한다. Libvirt는 그 자체로 도구는 아니지만 게스트 운영 체제를 관리하는 도구를 작성하기 위한 API이다. Libvirt 자체는 추상화라는 아이디어를 바탕으로 작성되었으며 지원되는 하이퍼바이저가 구현하는 공통 기능을 위한 공통 API를 제공한다. Libvirt는 원래 Xen용 관리 API로 설계되었지만 그 이후로 수많은 하이퍼바이저를 지원하도록 확장되었다.

 

기본 아키텍처

 

My developerWorks의 그린 그룹

My developerWorks의 GReen IT Report space와 Green computing group에서 에너지, 효율성 및 환경에 대한 주제를 토의하고 리소스를 공유할 수 있다.

 

먼저 libvirt의 사용 모델을 살펴본 후 아키텍처와 사용법에 대해서도 자세히 살펴보자. Libvirt는 관리 애플리케이션에서 사용하기 위해 설계된 API 세트이다(그림 1 참조). Libvirt는 하이퍼바이저 관련 메커니즘을 통해 사용 가능한 각 하이퍼바이저와 통신하여 API 요청을 처리한다. 이 기사에서는 나중에 QEMU를 사용하여 이 작업을 수행하는 방법에 대해 설명한다.


그림 1. libvirt 비교 및 사용 모델

 

위 그림은 libvirt에 사용되는 용어를 비교해서 보여 준다. 이러한 용어는 API 이름 지정에 사용되기 때문에 중요하다. 위 그림에서 볼 수 있는 두 가지 기본적인 차이점은 libvirt에서는 물리적 호스트를 노드라고 하고, 게스트 운영 체제를 도메인이라고 한다는 것이다. 여기서 유의할 점은 libvirt(및 해당 애플리케이션)는 호스트 Linux 운영 체제(도메인 0)의 도메인에서 실행된다는 것이다.

 

제어 방법

 

libvirt에는 두 가지 구별되는 제어 방법이 있다. 첫 번째 방법은 그림 1에서 보여 주는 방법으로 관리 애플리케이션과 도메인이 같은 노드에 있는 경우이다. 이 경우에는 관리 애플리케이션이 libvirt를 통해 로컬 도메인을 제어한다. 두 번째 방법은 관리 애플리케이션과 도메인이 서로 다른 노드에 있는 경우이다. 이 경우에는 원격 통신이 필요하다(그림 2 참조). 이 모드에서는 원격 노드에서 실행되는 libvirtd라는 특수 디먼을 사용한다. 이 디먼은 libvirt가 새 노드에 설치될 때 자동으로 시작되며 로컬 하이퍼바이저를 자동으로 결정하고 해당 드라이버를 설정할 수 있다(잠시 후에 설명함). 관리 애플리케이션은 사용자 정의 프로토콜을 통해 로컬 libvirt 및 원격 libvirtd와 차례로 통신한다. QEMU의 경우에는 QEMU 모니터에서 프로토콜이 종료된다. QEMU에는 실행 중인 게스트 운영 체제를 검사하고 VM(Virtual Machine)의 다양한 특성을 제어할 수 있는 모니터 콘솔이 있다.


그림 2. libvirtd를 사용한 원격 하이퍼바이저 제어

 

하이퍼바이저 지원

 

다양한 하이퍼바이저에 대한 확장성을 지원하기 위해 libvirt에는 공통 API를 사용하여 일반적인 방식으로 여러 기본 하이퍼바이저를 지원할 수 있는 드라이버 기반 아키텍처가 구현되어 있다. 이는 곧 일부 하이퍼바이저의 특정 기능을 API에서 볼 수 없다는 것을 의미한다. 또한 일부 하이퍼바이저에는 일부 API 함수가 구현되어 있지 않을 수 있으며, 이러한 함수는 특정 드라이버 내에서 지원되지 않는 것으로 정의되어 있다. 그림 3에서는 libvirt API 및 연관된 드라이버의 계층을 보여 준다. 이 그림에서는 libvirtd가 원격 애플리케이션에서 로컬 도메인에 액세스할 수 있는 방법을 제공한다는 것도 알 수 있다.


그림 3. libvirt의 드라이버 기반 아키텍처

이 기사를 쓰던 당시 libvirt에는 표 1에 나열된 하이퍼바이저용 드라이버가 구현되어 있었으며 다른 드라이버도 곧 오픈 소스 커뮤니티에서 새 하이퍼바이저로 제공할 것으로 예상한다.


표 1. libvirt에서 지원하는 하이퍼바이저
하이퍼바이저 설명
Xen IA-32, IA-64 및 PowerPC 970 아키텍처용 하이퍼바이저
QEMU 다양한 아키텍처를 위한 플랫폼 에뮬레이터
KVM(Kernel-based Virtual Machine) Linux 플랫폼 에뮬레이터
LCX(Linux Containers) 운영 체제 가상화를 위한 Linux(경량) 컨테이너
OpenVZ Linux 커널 기반의 운영 체제 레벨 가상화
VirtualBox x86 가상화를 위한 하이퍼바이저
User Mode Linux 다양한 아키텍처를 위한 Linux 플랫폼 에뮬레이터
Test 가상 하이퍼바이저를 위한 테스트 드라이버
Storage 스토리지 풀 드라이버(로컬 디스크, 네트워크 디스크, iSCSI 볼륨)

 

Libvirt 및 가상화 쉘

 

지금까지 libvirt 아키텍처의 일부를 살펴보았다. 이제 libvirt 가상화 API를 사용하는 몇 가지 예제를 살펴보자. 여기>(가상화 쉘)라는 애플리케이션을 사용한다. 이 쉘에서는 여러 libvirt 기능을 대화식(쉘 기반)으로 사용할 수 있다. 이 섹션에서는 virsh를 사용하여 VM을 조작하는 방법을 살펴본다.

 

먼저 도메인 구성 파일을 정의한다(아래 Listing 1 참조). 이 코드에서는 도메인을 정의하는 데 필요한 모든 옵션을 지정한다. 이러한 옵션에는 하이퍼바이저(에뮬레이터), 도메인에 사용되는 리소스 및 주변 구성(예: 네트워크) 등이 포함된다. 이 구성은 매우 간단하지만 libvirt에서 지원하는 실제 속성은 훨씬 더 다양하다. 예를 들어, BIOS, 호스트 부트로더, 도메인에 사용할 리소스 및 플로피 디스크, CD-ROM, USB, PCI 장치 등과 같은 장치를 지정할 수 있다.

 

도메인 구성 파일은 이 QEMU 도메인에 사용할 일부 기본 메타데이터 즉, 도메인 이름, 최대 메모리, 초기에 사용 가능한 메모리(현재) 및 이 도메인에 사용할 수 있도록 설정할 가상 프로세서 수 등을 정의한다. UUID(Universally Unique Identifier)를 지정하지 않아도 되지만 그 대신 UUID를 지정하도록 libvirt를 설정해야 한다. 이 플랫폼에서 에뮬레이트할 시스템의 유형을 정의한다. 이 경우에는 완전 가상화된 686 프로세서(hvm)이다. 에뮬레이터의 위치(같은 유형의 에뮬레이터를 여러 개 지원해야 하는 경우)와 도메인에 대한 가상 디스크를 정의한다. 여기에서는 VMDK(Virtual Machine Disk) 형식의 ReactOS 운영 체제인 VM을 지정한다. 마지막으로 기본 네트워킹 구성을 지정하며 VNC(Virtual Network Computing)를 그래픽 작업에 사용한다.


Listing 1. 도메인 구성 파일

<xml version="1.0"?>
<domain type='qemu'>
     <name>ReactOS-on-QEMU<name> 
     <uuid<uuid> 
     <memory>131072<memory>
     <currentMemory>131072<currentMemory> 
     <vcpu>1<vcpu>
     <os> 
          <type arch='i686' machine='pc'>hvm<type>
     <os>
     <devices> 
          <emulator>usr/bin/qemu<emulator> 
          <disk type='file' device='disk'> 
               <source file='/home/mtj/libvtest/ReactOS.vmdk'/> 
               <target dev='hda'/> 
          <disk>
          <interface type='network'>
               <source network='default'/> 
          <interface>
          <graphics type='vnc' port='-1'/>
     <devices>
<domain>


이제 도메인 구성 파일이 완료되었으므로 virsh 도구를 사용하여 도메인을 시작할 차례이다. virsh 도구는 수행할 특정 작업에 대한 명령 인수를 사용한다. 새 도메인을 시작하는 경우에는 다음과 같이 create 명령과 도메인 구성 파일을 사용한다.


Listing 2. 새 도메인 시작하기

mtj@mtj-desktop:~/libvtest$ virsh create react-qemu.xml
Connecting to uri: qemu:///system
Domain ReactOS-on-QEMU created from react-qemu.xml

mtj@mtj-desktop:~/libvtest$


여기에서는 URI(Universal Resource Indicator)를 사용하여 도메인에 연결한다(qemu:///system). 이 로컬 URI는 로컬 QEMU 드라이버에 대한 시스템 모드 디먼에 연결한다. SSH(Secure Shell) 프로토콜을 통해 shinchan 호스트의 원격 QEMU 하이퍼바이저에 연결하려면 URI qemu+ssh://shinchan/을 사용한다.

 

그런 다음 virsh에서 list 명령을 사용하여 지정된 호스트의 활성 도메인을 나열할 수 있다. 이 명령을 실행하면 다음과 같이 활성 도메인, 도메인 ID 및 상태가 나열된다.


Listing 3. 활성 도메인 나열하기

mtj@mtj-desktop:~/libvtest$ virsh list
Connecting to uri: qemu:///system
Id  Name                 State
----------------------------------
1   ReactOS-on-QEMU   running

mtj@mtj-desktop:~/libvtest$


여기에 정의된 이름은 도메인 구성 파일 메타데이터에 정의한 이름이다. 이 도메인의 경우 도메인 ID가 1이고 현재 실행 중임을 알 수 있다.

또한 suspend 명령을 사용하여 도메인을 일시중단할 수도 있다. 이 명령을 실행하면 도메인에 대한 스케줄이 중지된다. 그러나 도메인은 메모리에 계속 남아 있기 때문에 빠르게 다시 시작하고, 상태를 보여 주는 목록을 나열한 후 도메인을 다시 시작하는 방법을 보여 준다.


Listing 4. 도메인 일시중단, 상태 검사 및 다시 시작

mtj@mtj-desktop:~/libvtest$ virsh suspend 1
Connecting to uri: qemu:///system
Domain 1 suspended

mtj@mtj-desktop:~/libvtest$ virsh list
Connecting to uri: qemu:///system
Id   Name                State
----------------------------------
1    ReactOS-on-QEMU   paused

mtj@mtj-desktop:~/libvtest$ virsh resume 1
Connecting to uri: qemu:///system
Domain 1 resumed

mtj@mtj-desktop:~/libvtest$


virsh 유틸리티에서는 이외에도 도메인 저장(save), 저장된 도메인 복원(restore), 도메인 다시 시동(reboot) 등을 포함한 여러 가지 명령을 지원한다. 실행 중인 도메인에서 도메인 구성 파일을 작성할 수도 있다(dumpxml).

 

지금까지 도메인을 시작하고 조작해 보았다. 하지만 실행 중인 도메인을 보기 위해 도메인에 연결하려면 어떻게 해야 할까? VNC를 사용하여 이를 수행할 수 있다. 다음과 같이 VNC를 사용하여 특정 도메인의 그래픽 데스크탑을 나타내는 창을 작성할 수 있다.


Listing 5. 도메인에 연결하기

mtj@mtj-desktop:~/libvtest$ xvnc4viewer 127.0.0.1 0


Libvirt와 Python

 

앞의 예제에서는 명령행 유틸리티 virsh를 사용하여 도메인을 제어하는 방법을 살펴보았다. 이제 Python을 사용하여 도메인을 제어하는 예제를 살펴보자. Python은 libvirt에서 지원되는 스크립팅 언어로 libvirt API에 대한 깔끔한 오브젝트 지향 인터페이스를 제공한다.

이 예제에서는 virsh 유틸리티에서 실행했던 일부 작업을 수행한다(list, suspend, resume 등). Python 예제 스크립트는 Listing 6에 있다. 이 예제에서는 먼저 libvirt 모듈을 가져온다. 그런 다음 로컬 QEMU 하이퍼바이저에 연결한다. 이제부터는 사용할 수 있는 도메인 ID를 반복하면서 도메인 ID별로 도메인 오브젝트를 작성한 후 해당 도메인을 일시중단, 다시 시작 및 삭제한다.


Listing 6. 도메인 제어를 위한 샘플 Python 스크립트(libvtest.py)

import libvirt

conn = libvirt.open('qemu:///system'
) for id in conn.listDomainsID():

dom = conn.lookupByID(id)
print "Dom %s State %s" % ( dom.name(), dom.info()[0] )

dom.suspend()
print "Dom %s State %s (after suspend)" % ( dom.name(), dom.info()[0] )

dom.resume()
print "Dom %s State %s (after resume)" % ( dom.name(), dom.info()[0] )
dom.destroy()


간단한 예제이기는 하지만 Python을 통해 제공되는 libvirt의 강력한 기능을 알 수 있다. 간단한 스크립트를 통해 모든 로컬 QEMU 도메인을 반복하고, 도메인에 대한 일부 정보를 표시한 다음 도메인을 제어할 수 있다. 이 스크립트의 출력은 Listing 7과 같다.


Listing 7. Listing 6에서 살펴본 Python 스크립트의 출력

mtj@mtj-desktop:~/libvtest$ python libvtest.py
Dom ReactOS-on-QEMU State 1
Dom ReactOS-on-QEMU State 3 (after suspend)
Dom ReactOS-on-QEMU State 1 (after resume)
mtj@mtj-desktop:~/libvtest$


API 개요

 

libvirt API는 크게 보아 하이퍼바이저 연결 API, 도메인 API, 네트워크 API, 스토리지 볼륨 API 및 스토리지 풀 API라는 5개의 API 섹션으로 나눌 수 있다.

 

모든 libvirt 통신은 지정된 하이퍼바이저에 대한 연결이 작성된 후(예를 들어, Listing 6의 open 호출 이후)에 발생한다. 이 연결은 작업에 사용할 다른 모든 API에 대한 경로를 제공한다. C API의 경우 이 동작은 virConnectOpen 호출을 통해 제공된다(인증을 위한 기타 동작 포함). 이러한 함수의 응답은 하이퍼바이저에 대한 연결을 나타내는 virConnectPtr 오브젝트이다. 이 오브젝트는 다른 모든 관리 기능의 기초로 사용되므로 지정된 하이퍼바이저에 대한 후속 API 호출의 필수 인수이다. 중요한 후속 호출로는 하이퍼바이저 및 드라이버의 기능을 리턴하는 virConnectGetCapabilities와 노드에 대한 정보를 가져오는 virNodeGetInfo가 있다. 이 정보는 구문 분석을 통해 가능한 동작을 파악할 수 있는 XML 문서로 리턴된다.

 

이제 하이퍼바이저에 대한 액세스가 준비되었으므로 API 호출 세트를 사용하여 해당 하이퍼바이저의 다양한 리소스를 반복할 수 있다. virConnectListDomains API 호출은 해당 하이퍼바이저의 활성 도메인을 나타내는 도메인 ID 목록을 리턴한다.

 

이 API는 도메인을 대상으로 하는 많은 함수를 구현한다. 도메인을 탐색하거나 관리하려면 먼저 virDomainPtr 오브젝트가 필요하다. 이 핸들은 ID, UUID 또는 도메인 이름을 사용하여 여러 가지 방법으로 가져올 수 있다. 도메인을 반복하는 예제를 계속하면 이 함수가 리턴하는 색인 목록을 사용하고 virDomainLookupByID를 호출하여 도메인 핸들을 가져올 수 있다. 도메인 핸들을 가져왔으므로 이제 도메인을 탐색하는 작업(virDomainGetUUID, virDomainGetInfo, virDomainGetXMLDesc, virDomainMemoryPeek)부터 제어하는 작업(virDomainCreate, virDomainSuspend, virDomainResume, virDomainDestroy 및 virDomainMigrate)을 포함한 수많은 작업을 수행할 수 있다.

 

또한 이 API를 사용하여 가상 네트워크 및 스토리지 리소스를 관리하고 검사할 수도 있다. API 모델에 따라 virNetworkPtr 오브젝트는 가상 네트워크를 관리 및 검사하는 데 필요하며 virStoragePoolPtr(스토리지 풀) 또는 virStorageVolPtr(볼륨) 오브젝트는 이러한 리소스를 관리하는 데 필요하다.

 

이 API는 또한 특정 이벤트(예: 도메인 시동, 일시중단, 다시 시작 또는 중지)를 알리기 위해 등록할 수 있는 이벤트 메커니즘도 지원한다.

 

언어 바인딩

 

libvirt 라이브러리는 C(C++ 지원)로 구현되었으며 Python에 대한 직접 지원을 포함한다. 하지만 수많은 언어 바인딩도 지원한다. 바인딩은 Ruby, Java™ 언어, Perl 및 OCaml용으로 구현되었다. 또한 C#에서도 libvirt를 호출할 수 있다. Libvirt는 대부분의 유명한 시스템 프로그래밍 언어(C 및 C++), 다양한 스크립팅 언어 및 통합 함수형 언어(Objective caml)를 지원한다. 따라서 사용 중인 언어에서 중점을 두는 부분이 무엇이든지 간에 libvirt를 사용하여 도메인을 제어할 수 있다.

 

libvirt를 사용하는 애플리케이션

 

이 기사에서 살펴본 몇 가지 기능만으로도 libvirt의 강력함을 알 수 있을 것이다. 또한 예상한 대로 libvirt를 기반으로 성공적으로 작성된 수많은 애플리케이션이 있다. 흥미로운 애플리케이션 중 하나가 바로 이 기사에서 살펴본 가상화 쉘인 virsh이다. 그리고 운영 체제 분배에서 새 도메인을 제공하는 데 사용할 수 있는 virt-install도 있다. virt-clone 유틸리티를 사용하면 VM을 다른 VM으로 복제할 수 있다(운영 체제 및 디스크 복제 포함). 상위 레벨 애플리케이션으로는 범용 데스크탑 관리 도구인 virt-manager와 VM의 그래픽 콘솔에 안전하게 연결하는 기능을 제공하는 경량 도구인 virt-viewer가 있다.

 

oVirt는 libvirt를 기반으로 하는 가장 중요한 도구 중 하나이다. oVirt VM 관리 애플리케이션은 단일 노드에 있는 단일 VM 또는 수백 개의 호스트에 있는 수천 개의 VM을 관리하기 위해 설계되었다. 이 도구는 많은 수의 호스트 및 VM을 단순화하는 작업뿐만 아니라 클러스터링 및 로드 밸런싱과 플랫폼 및 아키텍처 간의 작업을 자동화하는 데도 사용할 수 있다.

 

추가 주제

 

이 짧은 기사에서 볼 수 있듯이 libvirt는 대규모 시스템 네트워크에 있는 여러 다양한 하이퍼바이저 환경의 도메인을 관리하는 애플리케이션을 작성하는 데 매우 유용한 라이브러리이다. 클라우드 컴퓨팅의 인기가 지속적으로 성장한다면 libvirt도 분명 함께 성장하면서 새로운 애플리케이션과 사용자를 찾게 될 것이다. 이 기사를 쓰던 당시까지 4년밖에 되지 않은 libvirt는 확장성 높은 컴퓨팅 환경에서 비교적 새로운 기술이기에 분명 더 큰 발전을 보여 줄 것이다.

 

번호 제목 글쓴이 날짜 조회 수
공지 [공지] 하이퍼바이져 스터디 관련 Q&A 게시판 입니다. woos 2016.04.09 236
215 __attribute__ ((pure)) [1] 백창우 2008.04.12 82281
214 20101023일자 xen 소스 빌드 중 toos/libxl/libxl.c의 에러 발생되는 문제 해결 법 [2] 이상철 2010.10.23 45976
213 IO 가상화 참고 소스 [1] 백창우 2008.05.06 40694
212 e820.c 컴파일 오류 나네요. [2] 백창우 2008.05.17 27048
» [펌] libvirt 가상화 라이브러리 분석 황선욱 2011.05.24 20833
210 kvm 의 내부구조 요약 정리 [3] file 최용석 2012.04.17 19541
209 credit 관련 던랩 메일링 리스트 포스팅 문대혁 2011.01.08 15299
208 그 게임 해킹 사이트 이름이 뭐였죠?? [2] 정성욱 2008.06.16 12432
207 Xen 스터디 종료하겠습니다. 백창우 2009.04.28 12248
206 Hypervisor Detailed Design (작성중 문서) [3] file 백창우 2008.04.16 12187
205 윈도우 레지스트리 가상화 [4] 박세율 2008.09.02 12042
204 TVMM 한글 PPT file 박세율 2008.05.15 11925
203 [발표자료] [2008.04.11] Hypervisor 개발 프로젝트 시작.ppt 백창우 2008.04.29 11737
202 [질문] 메모리 할당관련 [3] 박은병 2008.05.05 11597
201 xen security 관련 자료 박세율 2008.08.28 11309
200 Hypervisor 아키텍쳐 디자인 백창우 2008.04.14 11156
199 Hypervisor 개발 프로젝트 문닫겠습니다. :) 백창우 2008.12.08 11094
198 x86 시뮬레이터 & 에뮬레이터 조사 [1] 백창우 2008.05.02 10924
197 지금까지 조사해본바에 의하면 [1] 백창우 2008.05.06 10905
196 나가기 전에 적습니다. [2] 백창우 2008.05.10 10824
XE Login