Anatomia da biblioteca de virtualização libvirt

Uma API para facilitar a virtualização Linux

A biblioteca libvirt é uma API Linux relacionada aos recursos de virtualização do Linux que suporta diversos hypervisores, incluindo Xen e KVM, bem como QEMU e alguns produtos de virtualização para outros sistemas operacionais. Este artigo explora a biblioteca libvirt, seu uso e sua arquitetura.

Compartilhe seu conhecimento:  Como você gerencia Sistemas Operacionais convidados em seu ambiente virtual? Você acredita que a biblioteca libvirt poderá ajudar? Inclua seus comentários abaixo.

Mr. M. Tim Jones, Independent author, IBM

M. Tim Jones é arquiteto de firmware integrado e autor das obras Artificial Intelligence: A Systems Approach, GNU/Linux Application Programming (agora, na segunda edição), AI Application Programming (na segunda edição) e BSD Sockets Programming from a Multilanguage Perspective. Sua experiência em engenharia vai desde o desenvolvimento de kernels para espaçonaves geossíncronas até a arquitetura de sistemas integrados e o desenvolvimento de protocolos de rede. Tim é engenheiro consultor da Emulex Corp. em Longmont, Colorado.



05/Jan/2010

Entre em contato com Tim

Tim é um de nossos autores mais conhecidos e produtivos. Procure todos os artigos de Tim no developerWorks. Confira o perfil de Tim e entre em contato com ele, com outros autores e leitores no My developerWorks.

Quando se trata de computação escalável (como computação em nuvem), a biblioteca libvirt pode ser uma das mais importantes de que você já ouviu falar. A libvirt oferece uma API agnóstica de hypervisores para gerenciar, de forma segura, sistemas operacionais convidados que estejam sendo executados em um host. A biblioteca libvirt não é uma ferramenta em si, mas uma API para construir ferramentas a fim de gerenciar sistemas operacionais convidados. É construída sobre a ideia de abstração. A biblioteca oferece uma API comum para a funcionalidade comum implementada pelos hypervisores suportados. A libvirt foi originalmente criada como uma API de gerenciamento para Xen mas, desde então, foi ampliada para suportar diversos hypervisores.

Arquitetura básica

Participe dos grupos ecológicos no My developerWorks

Discuta tópicos e compartilhe recursos sobre energia, eficiência e meio ambiente no espaço GReen IT Report e no Grupo de computação ecológica do My developerWorks.

Vamos começar nossa discussão sobre a libvirt com uma visão do modelo de uso e, em seguida, compreender sua arquitetura e uso. A libvirt existe como um conjunto de APIs projetadas para serem usadas como um aplicativo de gerenciamento (consulte a Figura 1). Por meio de um mecanismo específico de hypervisores, a libvirt comunica-se com um hypervisor disponível para executar as solicitações da API. Irei explorar como isso é feito com QEMU mais adiante neste artigo.

Figura 1. Comparação e modelo de uso da libvirt
Comparação e modelo de uso da libvirt

Também é mostrada uma comparação da terminologia usada pela libvirt. Esta terminologia é importante pois esses termos são usados na nomenclatura da API. As duas diferenças fundamentais são que a libvirt chama o host físico de nó, e que o sistema operacional convidado é chamado de domínio. Observe aqui que a libvirt (e seu aplicativo) é executada no domínio do sistema operacional convidado Linux (domínio 0).

Meios de controle

Com a libvirt, você terá dois meios de controle distintos. O primeiro é demonstrado na Figura 1, em que o aplicativo de gerenciamento e os domínios existem no mesmo nó. Nesse caso, o aplicativo de gerenciamento trabalha por meio da biblioteca libvirt para controlar os domínios locais. Os outros meios de controle existem quando o aplicativo de gerenciamento e os domínios estão em nós separados. Aqui é necessária a comunicação remota (consulte a Figura 2). Este modo usa um daemon especial chamado libvirtd que é executado em nós remotos. Este daemon é iniciado automaticamente quando a libvirt é instalada em um novo nó e pode determinar, de forma automática, os hypervisores locais e configurar drivers para eles (isso será tratado em breve). O aplicativo de gerenciamento se comunica por meio da libvirt local com o libvirtd remoto através de um protocolo customizado. Para o QEMU, o protocolo termina no monitor QEMU. O QEMU inclui um console do monitor que permite inspecionar um sistema operacional convidado em execução, bem como controlar vários aspectos da máquina virtual (VM).

Figura 2. Controle de hypervisores remotos com o libvirtd
Controle de hypervisores remotos com o libvirtd

Suporte a hypervisor

Para suportar a extensibilidade para uma ampla gama de hypervisores, a libvirt implementa uma arquitetura baseada em driver, que permite que uma API comum atenda vários hypervisores subjacentes de maneira comum. Isso significa que determinadas funcionalidades especializadas de alguns hypervisores não são visíveis por meio da API. Alem disso, alguns hypervisores podem não implementar todas as funções da API, que então são definidas como não suportadas no driver específico. A Figura 3 ilustra as camadas da API libvirt e os drivers associados. Observe também que aqui o libvirtd oferece meios de acessar domínios locais a partir de aplicativos remotos.

Figura 3. Arquitetura baseada em driver da libvirt
Arquitetura baseada em driver da libvirt

Na data da criação deste artigo, a libvirt implementava drivers para os hypervisores listados na Tabela 1. Sem dúvida, outros drivers estarão disponíveis conforme novos hypervisores surgirem nas comunidades de software livre.

Tabela 1. Hypervisores suportados pela libvirt
HypervisorDescrição
XenHypervisor para as arquiteturas IA-32, IA-64 e PowerPC 970
QEMUEmulador de plataforma para várias arquiteturas
Máquina Virtual (VM) baseada em kernelEmulador de plataforma Linux
Contêineres Linux (LXC)Contêineres Linux (leves) para a virtualização do sistema operacional
OpenVZVirtualização no nível do sistema operacional baseada no kernel Linux
VirtualBoxHypervisor para virtualização x86
Linux no espaço do usuárioEmulador de plataforma Linux para várias arquiteturas
TesteDriver de teste para um hypervisor falso
ArmazenamentoDrivers do conjunto de armazenamento (disco local, disco de rede, volume iSCSI)

Libvirt e o shell de virtualização

Agora que abrangemos um pouco da arquitetura da libvirt, vamos ver alguns exemplos do uso da API de virtualização libvirt. Começo usando um aplicativo chamado virsh (shell de virtualização), que é construído sobre a libvirt. Este shell permite usar grande parte da funcionalidade da libvirt, mas de uma maneira interativa (baseada no shell). Nesta seção, demonstro alguns dos aspectos da manipulação da VM usando virsh.

A primeira etapa é definir o arquivo de configuração do domínio (mostrado na Listagem 1, abaixo). Este código especifica todas as opções necessárias para a definição de um domínio — do hypervisor (emulador) para os recursos usados pelo domínio e a configuração periférica (como a rede). Observe que se trata de uma configuração muito simples: os atributos reais que a libvirt suporta têm uma diversidade muito maior. Por exemplo, é possível especificar um BIOS e um loader de boot do host, recursos a serem usados pelo domínio, e dispositivos a serem usados — desde disquetes e CD-ROMs até dispositivos USB e PCI.

O arquivo de configuração do domínio define alguns dos metadados básicos a serem usados para este domínio QEMU, incluindo o nome do domínio, memória máxima e memória inicialmente disponível (atual), bem como o número de processadores virtuais a serem disponibilizados para este domínio. Não é possível atribuir um Universally Unique Identifier (UUID), em vez disso, permita que a libvirt atribua um. Defina o tipo de máquina a ser emulada para esta plataforma — neste caso, um processador 686 que é totalmente virtualizado (hvm). Defina a localização do emulador (caso precise de suporte a vários do mesmo tipo) e o disco virtual para o domínio. Observe aqui que é necessário indicar a VM, que é um sistema operacional ReactOS, no formato Virtual Machine Disk (VMDK). Por fim, especifique a configuração de rede padrão e use Virtual Network Computing (VNC) para a parte gráfica.

Listagem 1. Arquivo de configuração do domínio
<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> <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>

Agora, com o arquivo de configuração do domínio concluído, vamos iniciar um domínio com a ferramenta virsh. A ferramenta virsh usa o argumento de um comando para a ação específica a ser tomada. Caso esteja iniciando um novo domínio, use o comando create e o arquivo de configuração do domínio:

Listagem 2. Iniciando um novo domínio
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$

Observe o Universal Resource Indicator (URI) usado para conexão ao domínio (qemu:///system). Este URI local conecta-se ao daemon do modo do sistema para o driver QEMU local. Para conectar-se a um hypervisor QEMU remoto pelo protocolo Secure Shell (SSH) no host shinchan, é possível usar o URI qemu+ssh://shinchan/.

Em seguida, é possível listar os domínios ativos em determinado host usando o comando list no virsh. Essa ação lista os domínios ativos, os IDs de seus domínios e seu estado, conforme mostrado abaixo:

Listagem 3. Listando domínios ativos
mtj@mtj-desktop:~/libvtest$ virsh list
Connecting to uri: qemu:///system
 Id Name                 State
34+
  1 ReactOS-on-QEMU      running

mtj@mtj-desktop:~/libvtest$

O nome definido aqui é o nome que você definiu nos metadados do arquivo de configuração do seu domínio. É possível ver que este domínio tem um ID de domínio 1 e está em execução no momento.

Também é possível suspender um domínio com o comando suspend. Este comando interrompe o planejamento do domínio, mas o domínio continua residindo na memória e pode ser rapidamente retomado. O exemplo a seguir ilustra a suspensão do domínio, a execução de uma lista para visualização do status e a reinicialização do domínio:

Listagem 4. Suspendendo um domínio, verificando o status e reinicializando
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
34+
  1 ReactOS-on-QEMU      paused

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

mtj@mtj-desktop:~/libvtest$            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$

O utilitário virsh também suporta vários outros comandos, como salvar um domínio (save), restaurar um domínio salvo (restore), reinicializar um domínio (reboot) e muitos outros. Também é possível criar um arquivo de configuração do domínio a partir de um domínio em execução (dumpxml).

Até agora, você iniciou e manipulou um domínio. O que você acha de conectar-se ao domínio para vê-lo funcionando? Para isso, use VNC. Para criar uma janela representando o desktop gráfico do domínio específico, use VNC como:

Listagem 5. Conectando-se ao domínio
mtj@mtj-desktop:~/libvtest$ xvnc4viewer 127.0.0.1 0

Libvirt e Python

O exemplo anterior ilustrou o controle de domínios usando o utilitário virsh de linha de comandos. Vamos ver agora um exemplo de controle de domínio usando Python. Python é a linguagem de script suportada pela libvirt e oferece uma interface limpa e orientada a objetos para a API libvirt.

Neste exemplo, exploro algumas das mesmas operações que demonstrei com o utilitário virsh (list, suspend, resume e assim por diante). O exemplo de script Python é fornecido na Listagem 6. Neste exemplo, comece importando o módulo libvirt. Em seguida, conecte-se ao hypervisor QEMU local. A partir daqui, execute a iteração por meio dos IDs de domínio disponíveis; para cada um, crie um objeto de domínio e, em seguida, suspenda, retome e por fim destrua o domínio.

Listagem 6. Script Python de exemplo para o controle de domínio (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() 
	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()

Embora este seja um exemplo simples, é possível ver o poder que a biblioteca libvirt oferece por meio da linguagem Python. Por meio de um script simples, será possível executar a iteração através de todos os domínios QEMU locais, emitir algumas informações sobre o domínio e, em seguida, controlar o domínio. A saída deste script é mostrada na Listagem 7.

Listagem 7. Saída do script Python na Listagem 6
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$
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$

Visão geral da API

Em um nível superior, a API libvirt pode ser dividida em cinco seções da API: a API de conexão do hypervisor, a API do domínio, a API de rede, a API do volume de armazenamento e, finalmente, a API do conjunto de armazenamento.

Toda a comunicação da libvirt ocorre após a criação de uma conexão com um determinado hypervisor (por exemplo, conforme mostrado com a chamada open na Listagem 6). A conexão fornece um caminho para a conclusão de todas as outras APIs. Na API C, este comportamento é fornecido por meio da chamada virConnectOpen (bem como outras chamadas para autenticação). A resposta dessas funções é um objeto virConnectPtr, que representa uma conexão a um hypervisor. Este objeto atua como base para todas as outras funcionalidades de gerenciamento e, por isso, é um argumento necessário para as chamadas de API subsequentes para um determinado hypervisor. As chamadas subsequentes importantes são virConnectGetCapabilities, que retorna os recursos do hypervisor e do driver, e virNodeGetInfo, que recupera informações sobre o nó. Essas informações são retornadas como um documento XML que pode ser analisado para compreender quais comportamentos são possíveis.

Agora, tendo acesso a um hypervisor, é possível executar a iteração por meio de vários recursos nesse hypervisor com um conjunto de chamadas de API. A chamada de API virConnectListDomains retorna uma lista de identificadores de domínio que representam domínios ativos nesse hypervisor.

A API implementa um grande número de funções orientadas aos domínios. Para explorar ou gerenciar um domínio, primeiro é necessário um objeto virDomainPtr. É possível obter esse identificador de diversas formas (usando ID, UUID ou nome do domínio). Continuando com o exemplo de iteração dos domínios, use a lista de índice retornada por essa função e chame virDomainLookupByID para obter o identificador do domínio. Com o identificador do domínio em mãos, é possível executar várias operações, desde explorar o domínio (virDomainGetUUID, virDomainGetInfo, virDomainGetXMLDesc, virDomainMemoryPeek) até controlá-lo (virDomainCreate, virDomainSuspend, virDomainResume, virDomainDestroy, e virDomainMigrate).

Também é possível usar a API para gerenciar e inspecionar redes virtuais e recursos de armazenamento. Seguindo o modelo da API, um objeto virNetworkPtr é necessário para gerenciar e inspecionar redes virtuais, e um objeto virStoragePoolPtr (conjunto de armazenamento) ou virStorageVolPtr (volume) é necessário para gerenciar esses recursos.

A API suporta também um mecanismo de eventos no qual é possível registrar-se para ser avisado sobre eventos específicos (como o domínio sendo inicializado, suspendido, retomado ou interrompido).


Ligações de linguagem

A biblioteca libvirt foi implementada em C (suportando C++) e inclui suporte direto para Python. No entanto, também há suporte para diversas ligações de linguagem. As ligações foram implementadas para Ruby, a linguagem Java™, Perl e OCaml. Também foi realizado o trabalho de chamar a biblioteca libvirt a partir de C#. A libvirt suporta as linguagens de programação de sistema mais conhecidas (C e C++), diversas linguagens de script e até mesmo uma linguagem funcional unificada (Objective caml). Por isso, seja qual for seu foco de linguagem, a libvirt fornece um caminho para o controle de seus domínios.


Aplicativos usando libvirt

Considerando apenas o pequeno número de recursos que demonstrei neste artigo, é possível ver o poder da biblioteca libvirt. E, como você talvez já suspeite, existem vários aplicativos que estão sendo construídos com êxito usando a libvirt. Um dos aplicativos mais interessantes é o virsh (demonstrado aqui), que é um shell de virtualização. Há também o virt-install, que pode seu usado para fornecer novos domínios de distribuições do sistema operacional. O utilitário virt-clone pode ser usado para clonar uma VM a partir de outra VM (abrangendo tanto o sistema operacional como a replicação de disco). Alguns aplicativos de nível superior incluem o virt-manager, que é uma ferramenta de gerenciamento de desktop para finalidades gerais, e o virt-viewer, uma ferramenta leve para a conexão segura ao console gráfico de VMs.

Uma das ferramentas mais importantes construídas sobre a libvirt é chamada de oVirt. O aplicativo de gerenciamento de VMs, oVirt, foi projetado para gerenciar uma única VM em um único nó ou milhares de VMs em centenas de hosts. Além de simplificar o gerenciamento de grandes quantidades de hosts e VMs, o aplicativo pode ser usado para automatizar o armazenamento em cluster e o balanceamento de carga e funciona com diversas plataformas e arquiteturas.


Indo além

Como é possível ver a partir deste breve artigo, a libvirt é uma excelente biblioteca para a construção de aplicativos que gerenciam domínios em diversos ambientes de hypervisores em grandes redes de sistemas. Considerando-se a crescente popularidade da computação em nuvem, não há dúvidas de que a libvirt crescerá junto com ela, descobrindo novos aplicativos e usuários. Na data deste artigo, a libvirt tinha apenas quatro anos, de forma que é relativamente nova no espaço significativamente escalável da computação. É muito provável que há mais por vir.

Recursos

Aprender

Obter produtos e tecnologias

  • A plataforma aberta de gerenciamento de VM oVirt da Red Hat é uma usuária da libvirt e demonstra que tipos de aplicativos podem ser construídos. É possível usar o oVirt para gerenciar grandes quantidades de hosts, e a plataforma é facilmente ampliável para suportar milhares de VMs.
  • Neste artigo, você usou o ReactOS como forma de demonstrar um domínio no QEMU. Este artigo fornece mais informações sobre o ReactOS (um clone gratuito do Windows®), que é facilmente executável na plataforma QEMU.
  • Com o software de teste IBM, disponível para download diretamente no developerWorks, faça seu próximo projeto de desenvolvimento em Linux.

Discutir

  • Envolva-se na comunidade My developerWorks. Entre em contato com outros usuários do developerWorks enquanto explora os blogs, fóruns, grupos e wikis destinados aos desenvolvedores.

Comentários

developerWorks: Conecte-se

Los campos obligatorios están marcados con un asterisco (*).


Precisa de um ID IBM?
Esqueceu seu ID IBM?


Esqueceu sua senha?
Alterar sua senha

Ao clicar em Enviar, você concorda com os termos e condições do developerWorks.

 


A primeira vez que você entrar no developerWorks, um perfil é criado para você. Informações no seu perfil (seu nome, país / região, e nome da empresa) é apresentado ao público e vai acompanhar qualquer conteúdo que você postar, a menos que você opte por esconder o nome da empresa. Você pode atualizar sua conta IBM a qualquer momento.

Todas as informações enviadas são seguras.

Elija su nombre para mostrar



Ao se conectar ao developerWorks pela primeira vez, é criado um perfil para você e é necessário selecionar um nome de exibição. O nome de exibição acompanhará o conteúdo que você postar no developerWorks.

Escolha um nome de exibição de 3 - 31 caracteres. Seu nome de exibição deve ser exclusivo na comunidade do developerWorks e não deve ser o seu endereço de email por motivo de privacidade.

Los campos obligatorios están marcados con un asterisco (*).

(Escolha um nome de exibição de 3 - 31 caracteres.)

Ao clicar em Enviar, você concorda com os termos e condições do developerWorks.

 


Todas as informações enviadas são seguras.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=80
Zone=Linux, Cloud computing
ArticleID=469629
ArticleTitle=Anatomia da biblioteca de virtualização libvirt
publish-date=01052010