Libvirt Overview 2013-02-13

2013. 10. 23. 21:03Cloud/멀티클라우드

1. Libvirt소개

Libvirt는 가상화 플랫폼을 관리하는 오픈소스 API이다. LIbvirt는 KVM, Xen, Vmware ESX등 다양한 가상화 기술에 사용할 수 있다. Libvirt는 C언어로 된 라이브러리이지만, 파이썬, 펄, OCaml, 루비, 자바 PHP언어에 바인딩 할 수 있다.

보통 경우에 따라 여러 종류의 하이퍼바이저를 통해 가상 머신을 생성하거나 관리해야 할 때도 있다. Libvirt는 이런 다양한 종류의 하이퍼바이저를 통합적으로 관리하기 위해 만든 API이다.

예를 들어 가상 머신의 운행을 중지하고 싶다면 해당 가상 머신의 하이퍼바이저가 제공하는 API나 명령을 이용하여 운행을 중지해야 한다. 하지만 서로 다른 하이퍼바이저를 사용하는 가상 머신이 여러대 있다고 가정하면, 이상황에서 현재 운행중인 가상 머신을 모두 중지하려하면 일일이 별도의 명령을 실행해야 한다. 다행이도 libvirt는 하이퍼바이저의 종류에 상관없이 하나의 API로 원하는 명령을 내릴 수 있도록 지원한다.

따라서 하이퍼바이저의 의존성을 없애고 여러 타입의 가상머신을 마이그레이션하거나 전체적인 관리기능을 만드는데 큰 도움이 된다.

2. 구조

Libvirt는 API이기 때문에 그 자체만으로는 도구가 될 수 없다. 따라서 libvirt가 제공하는 API를 사용하여 하이퍼바이저를 관리하는 도구를 만들거나 Virsh명령으로 이용할 수 있다. Libvirt의 구조는 다음과 같다.

그림처럼 관리도구는 Libvirt API를 기반으로 만들며 libvirt는 하이퍼바이저에 연동된다. 그림에서 도메인은 가상 머신을 의미한다. 물론 위와 같이 하나의 호스트 장비에서 여러 가상 머신을 관리할 수도 있으나, 원격에 있는 가상 머신을 관리할 수도 있다. 이때 libvirt는 libvirtd를 제공한다. 관리 도구는 로컬의 libvirt와 원격의 libvirtd가 서로 통신하여 원격에 있는 가상 머신에 관리 명령을 전달한다.

Libvirtd는 Libvirt가 새 노드에 설치 될 때 자동으로 시작되는 데몬 프로세스며 관리도구와 통신하여 원격 도메인의 명령을 전달하는 역할을 한다. 또한 앞서 말한 것과 같이 libvirt는 다양한 하이퍼바이저를 지원하므로 각 하이퍼바이저마다 연동할 드라이버를 둔다.

 

 

 

 

 

3. 사용방법

Libvirt는 Connction API, Guest Domain API를 기본적으로 제공한다.

Connection API – 하이퍼바이저 연결

Connection API는 하이퍼바이저에 대한 연결을 끊는 등의 작업을 처리한다. Libvirt를 사용한 모든 작업은 하이퍼바이저에 대한 연결을 설정하고 이를 통해 얻은 핸들을 이용하여 작업을 수행하는 것이다. 일반적으로 libvirt는 다음과 같은 작업 단계로 사용된다.

1) 하이퍼바이저 연결 설정

2) 하이퍼바이저 핸들을 통한 작업 수행

3) 하이퍼바이저 연결 해제

연결 설정을 위해 가장먼저 VirConnectOpen() 함수를 호출한다. VirConnectOpen()함수 호출이 성공적으로 이뤄지면 시스템에 명령을 전달할 때 사용되는 하이퍼바이저 핸들 포인터를 얻을 수 있다. 다음은 VirConnectOpen()함수의 원형이다.

VirConnectPtr virConnectOpen(const char*name)

파라미터 Const char*name 파라미터에 다음과 같은 URL값을 입력한다.

Driver[+transport]://[username@][hostname][:port]/[path][?extraparameters]

각 URL의 항목에 대한 설명은 다음과 같다.

Driver – 하이퍼바이저 타입에 따른 드라이버이름을 입력한다. 지원하는 드라이버는 다음과 같다.

드라이버

설명

Qemu

Qemu와 kvm 타입 지원

Xen

Xen 3.1버전 이하 타입 지원

Xenapi

새로운 xen타입 지원

Uml

UML 타입 지원

Lxc

리눅스 컨테이너 타입 지원

Vbox

버추얼박스 타입 지원

Openvz

Openvz 컨테이너 타입 지원

Esx

VMware ESX 타입 지원

One

Opennebula 타입 지원

Phyp

파워 하이퍼바이저 지원

 

Transport – 전송 방식을 지정한다. tls,tcp,unix,ssh,ext 방식을 지원한다. 이중 로컬 하이퍼바이저에 대한 접근은 unix(운영체제 유닉스가 아니라 전송 방식 이름임) 방식을 기본으로 사용하며, 원격 하이퍼바이저에 대한 접근은 TLS(transport layer security)방식을 사용한다.

UserName – SSH 전송 방식을 사용하는 경우 사용자를 입력한다.

Hostname – 접속할 호스트 이름

Port – 자동으로 설정되므로 거의 사용하지 않음, 임의의 포트를 지정할 때만 사용

Path – 하이퍼바이저의 로컬 URI다 Xen일때는 "/"를 Qemu(KVM)일 때는 "/system"을 사용한다.

Extraparameters – 원격 접속 설정에 대한 추가적인 옵션을 입력할 수 있다.

다음은 URI 사용의 다양한 예이다.

-로컬 하이퍼바이저 접근 URI – Xen

Xen:///

Xen+unix///

-로컬 하이퍼바이저 접근 URI – Qemu(kvm)

Qemu:///system

Qemu+unix///system

-원격 호스트의 하이퍼바이저 접근

Xen://node.example.com/

-SSH를 이용한 원격 호스트의 하이퍼바이저 접근

Xen+ssh://root@node.example.com/

URI를 사용하여 연결 설정이 성립되면 다른 libvirt API를 사용하여 호스트나 가상 머신에 대한 작업을 처리 할 수 있다. 수행하려는 작업을 모두 완료하고 난 후에 반드시 Virconnectclose()함수를 사용하여 연결 설정을 닫는다. libvirt함수를 사용하여 호스트를 제어 할 때 virConnectOpen() 함수와 virConnectClose() 함수로 끝을 내야한다.

호스트에 대한 연결을 설정했다면 기본적으로 호스트에 대한 호스트 이름, CPU 메모리정보등을 확인 할 수 있다.

Guest Domain API – 가상 머신 `관리

하이퍼바이저에 대한 연결이 완료되면 이제 가상 머신을 관리할 수 있다. 가상머신은 하이퍼바이저가 생성한 가상 머신을 일컫는다. 가상 머신은 다음과 같은 라이프 사이클을 갖는다.

< 가상머신 라이프 사이클 >

가상 머신을 생성하려면 가상 머신이 사용할 볼륨을 생성해야 한다.

#include <stdio.h>

#include <stdlib.h>    

#include <libvirt/libvirt.h>

 

int main(int argc, char*argv[]){

 

virConnectptr conn;

virStoragePoolPtr ptrPool;

virStorageVolPtr ptrVol;

 

Const Char *confPool = "<pool type='dir'><name>test-pool</name><target><path>/var

/lib/xen/images</path></target></pool>";

 

Const char *confVol = "<volume><name>test-Volume.img</name><allocation>5</allocation><capacity unit='G'>1</capacity><target><path>/var/lib/xen/images

/test-volume.img</path></target></volume>";

 

conn = virConnectOpen("Xen:///");

if(Conn == NULL) {

fprintf(stderr, "failed to open Connection to Xen:///\n");

return -1;

}

 

ptrPool = virStoragePoolCreateXML(conn, confPool, 0);

if(ptrPool == NULL){

fprintf(stderr, "Failed to Create Pool \n");

return -1;

}

 

ptrVol = virStorageVolCreateXML(ptrPool, confvol, 0);

if(ptrVol == NULL) {

fprinf(stderr, "failed to create volume \n");

return -1;

}

 

fprinf(stderr, "volum %s has been created\n", virStorageVolGetName(ptrVol));

VirConnectClose(Conn);

return 0;

}

~

이렇게 생성한 볼륨을 이용하여 가상 머신을 생성한다.

VirDomainDefineXML() 함수와 VirDomainCreate()함수를 사용하여 가상 머신을 생성할 수 있다. VirDomainDefineXML()함수는 XML데이터의 설정을 파일로 저장한다. 저장한 설정 파일을통해 해당 도메인을 계속 사용할 수 있다. VirDomainCreate()함수는 파라미터로 입력된 설정에 따라 가상 머신을 생성한다.

가상 머신을 생성해두면 나중에 실행중인 가상 머신의 목록을 통해 상태를 확인하거나 가상 머신을 관리 할 수있다. 이를 위해 가상 머신을 식별하는 식별자를 정리하면 다음과 같다

ID

호스트에서 동작하는 가상 머신을 식별하는 양의 정수다. 정지된 가상머신은 ID가 없다. 가상 머신의 ID가 0이면 호스트의 OS를 지칭한다. 해당 호스트에 가상 머신이 추가될 때마다 1씩 증가하여 ID가 부여된다.

Name

가상 머신에 할당한 문자열이다. 영문자와 숫자 하이픈 언더스코어로 이름을 지정할 수 있다. 가상 머신이 정지되더라도 이름을 유지한다. 또한 가상 머신에 대한 설정값을 저장할 때 이 이름을 사용한다

UUID

유니버셜 고유 식별자(혹은 GUID,전역 고유 식별자)를 사용하여 가상머신을 식별한 값으로 호스트에 관계없이 가상머신을 식별한다.

 

생성한 가상머신이 이미 동작중이라면 VirConnectNumOfDomains()함수를 사용하여 현재 실행중인 가상머신의 수를 파악할 수 있다. 또한 동작중인 도메인의 ID값을 확인할 수 있다.

 

생성한 가상머신 상태를 저장하고 다시 불러오는 방법은 우선 저장할 이미지 파일을 결정하고, 가상 머신의 핸들포인터와 저장할 이미지 파일명을 VirDomainSave()함수의 파라미터로 입력하여 가상 머신을 저장할 수 있다. 이미지 파일은 하이퍼바이저가 동작하는 호스트의 파일 시스템에 저장된다. 로컬에서 Libvirt를 사용하는 경우 차이가 없으나, 원격으로 libvirt를 사용하는 경우에는 이미지 파일이 원격에 위치한 호스트에 생성된다.

<가상 머신 저장하기 예>

#include <stdio.h>

#include <stdlib.h>

#include <libvirt/libvirt.h>

 

int main(int argc, char *argc[]) {

virConnectPtr conn;

virDomainPtr dom;

virDomainInfoPtr info;

const char *filename = "/var/ib/libvirt/save/test-guest.img";

 

conn = virConnectOpen("xen:///");

if(conn == Null) {

fprinf(stderr, "Failed to open Connection to Xen:///\n");

return -1;

}

dom = virDomainLooKupByName(conn, "test-guest");

if(!dom){

fprintf(stderr, "Cannot find guest to saved");

return -1;

}

 

 

if(virDomainGetInfo(dom, &info) < 0 ) {

fprintf(stderr, "Cannot check guest state");

return -1;

}

 

if(info.state == VIR_DOMAIN_SHUTOFF) {

fprintf(stderr, " Not Saving guest that isn't Running");

return -1;

}

 

if(virDomainSave(dom, filename) < 0 ) {

fprintf(stderr, "Unable to save guest to %s", filename);

return -1;

}

 

fprinf(stderr, "guest state save to %s", filename);

virConnectClose(conn);

return 0;

}

이를 실행 하면 /var/lib/llibvirt/save/guest.img 파일에 가상 머신의 현재 상태를 저장한다.

또한 가상머신은 나중에 virDomainRestore()함수를 사용하여 저장했던 상태 그대로 재 실행할 수 있다 VirDomainRestore()함수를 실행하면 해당 가상 머신의 식별자가 반환된다.

 

4. 총평

지금까지 libvirt가 제공하는 API를 사용하여 하이퍼바이저 접속 및 간단한 가상머신 조작에 대해 알아보았다. CPU나 메모리, 스토리지, 네트워크 자원 할당에 관련된 내용을 앞으로 Libvirt API Referen(http://libvirt.org/html/libvirt-libvirt.html) 를 통하여 공부할 예정이다. 또한 Libvirt API를 바탕으로 만든 Virsh(virtual shell)을 사용해보려고 한다.

'Cloud > 멀티클라우드' 카테고리의 다른 글

[Paper Review] Metacloud - Wind of Change: From Vendor Lock-in to the Meta Cloud  (0) 2013.10.23
Jcloud  (0) 2013.10.23
Deltacloud 2013-02-21  (0) 2013.10.23
Libcloud 2013-02-14  (0) 2013.10.23
Libcloud와Libvirt 2013-02-13  (1) 2013.10.23