Product SiteDocumentation Site

12.2. Virtualização

Virtualização é um dos maiores avanços nos anos recentes da computação. O termo cobre várias abstrações e técnicas de simulação de computadores virtuais com um grau de variabilidade de independência do hardware real. Um servidor físico pode então hospedar vários sistemas que trabalham ao mesmo tempo e em isolamento. As aplicações são muitas, e geralmente derivam a partir desse isolamento: ambientes de teste com configurações variáveis por exemplo, ou separação de serviços hospedados entre diferentes máquinas virtuais para segurança.
Existem múltiplas soluções de virtualização, cada uma com seus prós e contras. Este livro focará no Xen, LXC e KVM, mas outras implementações dignas de nota são as seguintes:

12.2.1. Xen

Xen é uma solução de “paravirtualização”. Ele introduz uma fina camada de abstração, chamada de “hypervisor”, entre o hardware e os sistemas superiores; Ele age como um árbitro que controla o acesso ao hardware feito pelas máquinas virtuais. Entretanto, ele apenas lida com algumas das instruções, o resto é executado diretamente pelo hardware em nome dos sistemas. A principal vantagem é que o desempenho não se degradada, e os sistemas rodam perto da velocidade nativa; a desvantagem é que os núcleos dos sistemas operacionais que alguém deseja usar em um "hypervisor" Xen precisam ser adaptados para rodar o Xen.
Vamos gastar algum tempo com termos. O "hypervisor" é a camada mais baixa, que roda diretamente no hardware, até mesmo abaixo do núcleo. Esse "hypervisor" pode dividir o resto do software entre vários domínios, que podem ser vistos como muitas máquinas virtuais. Um desses domínios (o primeiro que for iniciado) é conhecido como dom0, e tem um papel especial, já que apenas esse domínio pode controlar o "hypervisor" e a execução de outros domínios. Esses outros domínios são conhecidos como domU. Em outras palavras, e a partir do ponto de vista do usuário, o dom0 coincide com o “hospedeiro” de outros sistemas de virtualização, enquanto que o domU pode ser visto como um "convidado" (“guest”).
Utilizar o Xen com o Debian necessita de três componentes:
  • O "hypervisor" ele próprio. De acordo com o hardware disponível, o pacote apropriado será xen-hypervisor-4.4-amd64, xen-hypervisor-4.4-armhf, ou xen-hypervisor-4.4-arm64.
  • Um núcleo que rode nesse "hypervisor". Qualquer núcleo mais recente que o 3.0 irá servir, incluindo a versão 3.16 presente na Jessie.
  • A arquitetura i386 também requer uma biblioteca padrão com os patches apropriados para aproveitar o Xen; ela está no pacote libc6-xen.
Para evitar o aborrecimento de selecionar esses componentes manualmente, a conveniência de alguns pacotes (tais com o xen-linux-system-amd64) foram colocados a disposição; todos eles puxam, em uma boa combinação, os pacotes "hypervisor" e núcleo apropriados. O "hypervisor" também trás o xen-utils-4.4, que contém ferramentas para controlar o "hypervisor" a partir do dom0. Este, por sua vez, trás a biblioteca padrão apropriada. Durante a instalação de tudo isso, scripts de configuração também criam uma nova entrada no menu do carregador de inicialização Grub, a fim de iniciar o núcleo escolhido em um dom0 Xen. Note, contudo, que essa entrada geralmente não é definida para ser a primeira da lista, e portanto, não será selecionada por padrão. Se esse não é o comportamento desejado, os comandos a seguir irão mudar isso:
# mv /etc/grub.d/20_linux_xen /etc/grub.d/09_linux_xen
# update-grub
Uma vez que esses pré-requisitos estejam instalados, o próximo passo é testar o comportamento do próprio dom0; isso envolve uma reinicialização do "hypervisor" e do núcleo Xen. O sistema deverá inicializar da maneira usual, com algumas mensagens extras no console, durante os passo iniciais da inicialização.
Agora é o momento de realmente instalar sistemas úteis nos sistemas domU, usando as ferramentas do xen-tools. esse pacote provê o comando xen-create-image, que automatiza a tarefa em grande parte. O único parâmetro mandatório é o --hostname, dando um nome ao domU; outras opções são importantes, mas podem ser armazenadas no arquivo de configuração /etc/xen-tools/xen-tools.conf, e assim, a ausência dessas opções na linha de comando não dispara um error. É, portanto, importante ou checar o conteúdo desse arquivo antes de criar imagens, ou usar parâmetros extras na invocação do xen-create-image. Parâmetros que são importantes de notar são os seguintes:
  • --memory, para definir o quantidade de RAM dedicada para o sistema recentemente criado;
  • --size e --swap, para definir o tamanho dos "discos virtuais" disponíveis para o domU;
  • --debootstrap, para fazer com que o novo sistema seja instalado com o debootstrap; neste caso, a opção --dist irá também ser usada mais geralmente (com um nome de distribuição como a jessie).
  • --dhcp define que a configuração de rede do domU deve ser obtida por DHCP enquanto --ip permite a definição estática do endereço IP.
  • Por fim, um método de armazenamento tem que ser escolhido para as imagens a serem criadas (aquelas que serão vistas como unidades de disco rígido a partir do domU). O método mais simples, que corresponde a opção --dir, é criar um um arquivo no dom0 para cada dispositivo que o domU deveria fornecer. Para sistemas que usam o LVM, a alternativa é usar a opção --lvm, seguida pelo nome do grupo de volume; xen-create-image irá então criar um novo volume lógico dentro desse grupo, e esse volume lógico se tornará disponível para o domU como uma unidade de disco rígido.
Assim que essas escolhas são feitas, podemos criar uma imagem para o nosso futuro Xen domU:
# xen-create-image --hostname testxen --dhcp --dir /srv/testxen --size=2G --dist=jessie --role=udev

[...]
General Information
--------------------
Hostname       :  testxen
Distribution   :  jessie
Mirror         :  http://ftp.debian.org/debian/
Partitions     :  swap            128Mb (swap)
                  /               2G    (ext3)
Image type     :  sparse
Memory size    :  128Mb
Kernel path    :  /boot/vmlinuz-3.16.0-4-amd64
Initrd path    :  /boot/initrd.img-3.16.0-4-amd64
[...]
Logfile produced at:
         /var/log/xen-tools/testxen.log

Installation Summary
---------------------
Hostname        :  testxen
Distribution    :  jessie
MAC Address     :  00:16:3E:8E:67:5C
IP-Address(es)  :  dynamic
RSA Fingerprint :  0a:6e:71:98:95:46:64:ec:80:37:63:18:73:04:dd:2b
Root Password   :  adaX2jyRHNuWm8BDJS7PcEJ
Agora temos uma máquina virtual, mas atualmente não está sendo executada (e portanto somente utilizando espaço de disco do dom0). Obviamente, podemos criar mais imagens, possivelmente com parâmetros diferentes.
Antes de ligarmos essas máquinas virtuais, nós precisamos definir como elas serão acessadas. Elas podem, é claro, serem consideradas como máquinas isoladas, apenas acessadas através de seus consoles de sistema, mas isso raramente coincide com o padrão de uso. Na maioria das vezes, um domU será considerado um servidor remoto, e apenas acessado através de uma rede. No entanto, seria bem inconveniente adicionar uma placa de rede para cada; e por isso é que o Xen permite a criação de interfaces virtuais, que cada domínio possa ver e usar da forma padrão. Note que essas interfaces, mesmo que elas sejam virtuais, só serão úteis uma vez conectadas a uma rede, mesmo que virtual. O Xen tem vários modelos de rede para isso:
  • O modelo mais simples é o modelo de ponte bridge; todos as placas de rede eth0 (tanto no caso do dom0 quanto nos sistemas domU) se comportam como se fossem diretamente conectadas em um switch de rede.
  • Em seguida vem o modelo routing, onde o dom0 se comporta como um roteador que se põem entre sistemas domU e a rede (física) externa.
  • Finalmente, no modelo NAT, o dom0 novamente está entre os sistemas domU e o resto da rede, mas os sistemas domU não são diretamente acessíveis por fora, e todo o tráfego vai através de uma tradução de endereços de rede (NAT) para o dom0.
Estes três nós de rede envolvem várias interfaces com nome incomuns, tais como vif*, veth*, peth* e xenbr0. O "hypervisor" Xen organiza-os de acordo com qualquer que seja o layout definido, sob o controle das ferramentas de espaço do usuário. Como o NAT e os modelos de roteamento adaptam-se apenas a casos particulares, nós só iremos abordar o modelo de "bridging".
A configuração padrão dos pacotes Xen não altera a configuração de rede de todo o sistema. No entanto, o daemon xend é configurado para integrar interfaces de rede virtual com qualquer bridge de rede pré-existente (com xenbr0 tendo precedência se várias dessas bridges existirem). Nós temos, portanto, de definir uma bridge em /etc/network/interfaces (o que requer a instalação do pacote bridge-utils, o que explica porque o pacote xen-utils-4.4 o recomenda) para substituir a entrada eth0 existente:
auto xenbr0
iface xenbr0 inet dhcp
    bridge_ports eth0
    bridge_maxwait 0
Depois de reinicializar o computador, para termos certeza que a bridge é criada automaticamente, nós podemos agora iniciar o domU com as ferramentas de controle do Xen, em particular o comando xl. Esse comando permite diferentes manipulações nos domínios, incluindo listando-os e, iniciando/parando eles.
# xl list
Name                                        ID   Mem VCPUs      State   Time(s)
Domain-0                                     0   463     1     r-----      9.8
# xl create /etc/xen/testxen.cfg
Parsing config from /etc/xen/testxen.cfg
# xl list
Name                                        ID   Mem VCPUs      State   Time(s)
Domain-0                                     0   366     1     r-----     11.4
testxen                                      1   128     1     -b----      1.1
Note que o testxen domU usa memória real, retirada da RAM, que estaria de outra forma disponível para o dom0, não a memória simulada. Portanto, cuidados devem ser tomados quando se constrói um servidor objetivando hospedar instâncias Xen, disponibilizando a RAM física de acordo.
Voilà! Nossa máquina virtual está iniciando. Nós podemos acessá-la de uma de duas maneiras. A maneira usual é se conectar a ela “remotamente” através da rede, como nós nos conectaríamos a uma máquina real; isso geralmente irá requerer a configuração de um servidor DHCP ou alguma configuração de DNS. A outra maneira, que pode ser a única maneira se a configuração de rede estiver incorreta, é usar o console hvc0, com o comando xl console:
# xl console testxen
[...]

Debian GNU/Linux 8 testxen hvc0

testxen login: 
Então pode-se abrir uma sessão, tal como se faria caso se estivesse sentado em frente ao teclado da máquina virtual. Desconectar-se desse console é possível através da combinação de teclas Control+].
Uma vez que o domU está ativo, ele pode ser usado como qualquer outro servidor (a final de contas é um sistema GNU/Linux ). Contudo, seu status de máquina virtual permite algumas características extras. Por exemplo, um domU pode, temporariamente, ser pausado e então retomado através dos comandos xl pause e xl unpause. Note que embora um domU pausado não use qualquer recurso do processador, sua memória alocada ainda está em uso. Talvez possa ser interessante considerar os comandos xl save e xl restore: ao salvar o domU libera-se os recursos que eram usados previamente por esse domU, incluindo a RAM. Quando restaurado (ou retirado da pausa, por assim dizer), um domU não nota nada além da passagem do tempo. Se um domU estava rodando quando o dom0 é desligado,os scripts empacotados automaticamente salvam o domU, e o restaurarão na próxima inicialização. Isso irá, é claro, implicar na inconveniência padrão que ocorre quando se hiberna um computador laptop, por exemplo; em particular, se o domU é suspenso por muito tempo, as conexões de rede podem expirar. Note também que o Xen é, até agora, incompatível com uma grande parte do gerenciamento de energia do ACPI, o que impede suspensão do sistema hospedeiro (dom0).
Interromper ou reinicializar um domU pode ser feito tanto a partir de dentro do domU (com o comando shutdown) quanto a partir do dom0, com o xl shutdown ou xl reboot.

12.2.2. LXC

Mesmo que seja usado para construir “máquinas virtuais”, o LXC não é, estritamente falando, um sistema de virtualização, mas um sistema que isola grupos de processos uns dos outros mesmo que eles todos rodem na mesma máquina. Ele tira proveito de um conjunto de evoluções recentes do núcleo Linux, coletivamente conhecidas como control groups, de maneira que diferentes conjuntos de processos chamados de “groups” tem diferentes visões de certos aspectos do sistema global. Os mais notáveis dentre esses aspectos são os identificadores de processo, a configuração de rede, e os pontos de montagem. Tais grupos de processos isolados não terão qualquer acesso a outros processos do sistema, e esses acessos ao sistema de arquivos podem ser restritos a um subconjunto específico. Eles também podem ter sua própria interface de rede e tabela de roteamento, e também podem ser configurados para ver apenas um subconjunto de dispositivos disponíveis presentes no sistema.
Esses recursos podem ser combinados para isolar toda uma família de processos iniciando a partir do processo init, e o conjunto resultante se parece muito com uma máquina virtual. O nome oficial para tal configuração é um “container” (daí o apelido LXC: LinuX Containers), mas uma diferença bastante importanto com as máquinas virtuais “reais”, tais como as providas pelo Xen ou KVM é que não há um segundo núcleo; o container usa o mesmo núcleo que o sistema hospedeiro. Isso tem tanto prós quanto contras: as vantagens incluem excelente desempenho devido à total falta de sobrecarga, e o fato que o núcleo tem uma visão global de todos processos rodando no sistema, então o agendamento pode ser mais eficiente do que seria se dois núcleos independentes fossem agendar diferentes conjuntos de tarefas. Líder entre os inconvenientes está a impossibilidade de rodar um núcleo diferente em um container (seja uma versão diferente do Linux ou um sistema operacional diferente por completo).
Como nós estamos lidando com isolamento e não virtualização simples, a criação de containers LXC é mais complexa do que simplesmente rodar o debian-installer em uma máquina virtual. Nós iremos descrever alguns pré-requisitos e, em seguida, iremos para a configuração de rede; para então depois, sermos capazes de realmente criar o sistema para ser rodado no container.

12.2.2.1. Etapas Preliminares

O pacote lxc contém as ferramentas necessárias para executar o LXC, e devem portanto serem instaladas.
O LXC também necessita do sistema de configuração control groups, o qual é um sistema de arquivos virtual que é montado no /sys/fs/cgroup. Como o Debian 8 optou pelo systemd, que também faz uso de "control groups", isso agora é feito automaticamente no momento da inicialização, sem configurações adicionais.

12.2.2.2. Configuração de Rede

O objetivo de instalar o LXC é configurar máquinas virtuais; enquanto nós poderíamos, é claro, mantê-las isoladas da rede, e apenas nos comunicarmos com elas através do sistema de arquivos, a maioria dos casos de uso envolve dar, ao menos, um mínimo acesso de rede para os containers. No caso típico, cada container irá ter uma interface de rede virtual, conectada à rede real através de uma bridge. Essa interface virtual pode ser plugada tanto diretamente na interface de rede física do hospedeiro (e nesse caso o container está diretamente na rede), ou em outra interface virtual definida no hospedeiro (e o hospedeiro pode então filtrar ou rotear o tráfego). Em ambos os casos, o pacote bridge-utils será necessário.
O caso simples é a penas uma questão de editar o /etc/network/interfaces, e mover a configuração da interface física (por exemplo eth0) para a interface bridge (usualmente br0), e configurar a ligação entre elas. Por exemplo, se o arquivo de configuração da interface de rede inicialmente contém entradas como as seguintes:
auto eth0
iface eth0 inet dhcp
Devem ser desabilitados e substituídos pelo seguinte:
#auto eth0
#iface eth0 inet dhcp

auto br0
iface br0 inet dhcp
  bridge-ports eth0
O efeito dessa configuração será similar ao que seria obtido se os containers fossem máquinas plugadas na mesma rede física como o hospedeiro. A configuração “bridge” gerencia o trânsito dos quadros Ethernet entre todas as interfaces "bridged", o que inclui a eth0 física, assim como as interfaces definidas para os containers.
Em casos onde essa configuração não pode ser usada (por exemplo, se nenhum endereço IP público pode ser atribuído aos containers), uma interface virtual tap será criada e conectada à brigde. A topologia de rede equivalente torna-se então de um host com uma segunda placa de rede conectada em um switch separado, com os containers também conectados nesse switch. O host tem então que atuar como um gateway para os containers caso eles sejam feitos para se comunicar com o mundo exterior.
Em adição ao bridge-utils, essa “rica” configuração requer o pacote vde2; o arquivo /etc/network/interfaces então torna-se:
# Interface eth0 is unchanged
auto eth0
iface eth0 inet dhcp

# Virtual interface 
auto tap0
iface tap0 inet manual
  vde2-switch -t tap0

# Bridge for containers
auto br0
iface br0 inet static
  bridge-ports tap0
  address 10.0.0.1
  netmask 255.255.255.0
A rede então pode ser configurada tanto estaticamente nos contêineres, quanto dinamicamente com um servidor DHCP rodando no host. Tal servidor DHCP deverá ser configurado para responder as consultas na interface br0.

12.2.2.3. Configurando o Sistema

Deixe-nos agora configurar o sistema de arquivos a ser usado pelo container. Uma vez que essa “máquina virtual” não irá rodar diretamente no hardware, alguns ajustes são necessários quando comparados a um sistema de arquivos padrão, especialmente quando o núcleo, dispositivos e consoles estão em questão. Felizmente, o lxc inclui scripts que praticamente automatizam essa configuração. Por exemlo, os comandos a seguir (que requerem os pacotes debootstrap e rsync) irão instalar um container Debian:
root@mirwiz:~# lxc-create -n testlxc -t debian
debootstrap is /usr/sbin/debootstrap
Checking cache download in /var/cache/lxc/debian/rootfs-jessie-amd64 ... 
Downloading debian minimal ...
I: Retrieving Release 
I: Retrieving Release.gpg 
[...]
Download complete.
Copying rootfs to /var/lib/lxc/testlxc/rootfs...
[...]
Root password is 'sSiKhMzI', please change !
root@mirwiz:~# 
Note que o sistema de arquivo é inicialmente criado em /var/cache/lxc, então é movido para o seu diretório de destino. Isto proporciona a criação de contêineres idênticos mais rapidamente, já que somente um cópia é necessária.
Note que o modelo de script de criação do debian aceita uma opção --arch para especificar a arquitetura do sistema a ser instalado e uma opção --release caso você queira instalar alguma coisa a mais que a atual versão estável do Debian. Você pode também definir a variável de ambiente MIRROR para apontar para um espelho Debian local.
O sistema de arquivos recém criado agora contém um sistema Debian mínimo, e por padrão o container não tem interface de rede (além da loopback). Como isso não é realmente o que queremos, nós iremos editar o arquivo de configuração do container (/var/lib/lxc/testlxc/config) e adicionar algumas entradas lxc.network.*:
lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = br0
lxc.network.hwaddr = 4a:49:43:49:79:20
Essas entradas significam, respectivamente, que uma interface virtual será criada no container; que ela irá, automaticamente, ser levantada quando o dito container for iniciado; que ela será, automaticamente, ser conectada a brigde br0 no hospedeiro; e que seu endereço MAC será o como especificado. Caso essa última entrada estaja faltando ou desabilitada, um endereço MAC aleatório será gerado.
Outra entrada útil nesse arquivo é a configuração de uma nome para o hospedeiro:
lxc.utsname = testlxc

12.2.2.4. Inicializando o Contêiner

Agora que nossa imagem da máquina virtual está pronta, vamos inicializar o contêiner:
root@mirwiz:~# lxc-start --daemon --name=testlxc
root@mirwiz:~# lxc-console -n testlxc
Debian GNU/Linux 8 testlxc tty1

testlxc login: root
Password: 
Linux testlxc 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt11-1 (2015-05-24) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
root@testlxc:~# ps auxwf
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.2  28164  4432 ?        Ss   17:33   0:00 /sbin/init
root        20  0.0  0.1  32960  3160 ?        Ss   17:33   0:00 /lib/systemd/systemd-journald
root        82  0.0  0.3  55164  5456 ?        Ss   17:34   0:00 /usr/sbin/sshd -D
root        87  0.0  0.1  12656  1924 tty2     Ss+  17:34   0:00 /sbin/agetty --noclear tty2 linux
root        88  0.0  0.1  12656  1764 tty3     Ss+  17:34   0:00 /sbin/agetty --noclear tty3 linux
root        89  0.0  0.1  12656  1908 tty4     Ss+  17:34   0:00 /sbin/agetty --noclear tty4 linux
root        90  0.0  0.1  63300  2944 tty1     Ss   17:34   0:00 /bin/login --     
root       117  0.0  0.2  21828  3668 tty1     S    17:35   0:00  \_ -bash
root       268  0.0  0.1  19088  2572 tty1     R+   17:39   0:00      \_ ps auxfw
root        91  0.0  0.1  14228  2356 console  Ss+  17:34   0:00 /sbin/agetty --noclear --keep-baud console 115200 38400 9600 vt102
root       197  0.0  0.4  25384  7640 ?        Ss   17:38   0:00 dhclient -v -pf /run/dhclient.eth0.pid -lf /var/lib/dhcp/dhclient.e
root       266  0.0  0.1  12656  1840 ?        Ss   17:39   0:00 /sbin/agetty --noclear tty5 linux
root       267  0.0  0.1  12656  1928 ?        Ss   17:39   0:00 /sbin/agetty --noclear tty6 linux
root@testlxc:~# 
Nós agora estamos dentro do container; nosso acesso aos processos é restrito apenas aqueles que foram iniciados a partir do próprio container, e nosso acesso ao sistema de arquivos é similarmente restrito ao subconjunto do sistema de arquivos completo dedicado (/var/lib/lxc/testlxc/rootfs). Nós podemos sair do console com Control+a q.
Note que nós executamos o container como um processo em segundo plano, graças a opção --daemon do lxc-start. Nós podemos interromper o container com um comando como lxc-stop --name=testlxc.
O pacote lxc contém um script de inicialização que pode iniciar automaticamente um ou vários containers quando a máquina inicia (ele faz uso do lxc-autostart que inicia os containers que tem a opção lxc.start.auto definida como 1). Controle mais afinado da ordem de início é possível com lxc.start.order e lxc.group: por padrão, o script de inicialização primeiro inicia os containers que são parte do grupo onboot e então os containers que não fazem parte de nenhum grupo. Em ambos os casos, a ordem dentro de um grupo é definida pela opção lxc.start.order.

12.2.3. Virtualização com KVM

KVM, que significa Kernel-based Virtual Machine, é primeiro, e antes de tudo, um módulo do núcleo que fornece a maior parte da infraestrutura que pode ser usada por um virtualizador, mas não é por si só um virtualizador. O real control para a virtualização é tratado por um aplicativo com base no QEMU. Não se preocupe se essa seção menciona os comandos qemu-*: ela continua sendo sobre KVM.
Ao contrário de outros sistemas de virtualização, o KVM foi incorporado ao núcleo Linux desde o seu início. Seus desenvolvedores escolheram tirar vantagem do conjunto de instruções do processador dedicado a virtualização (Intel-VT e AMD-V), o que mantém o KVM leve, elegante e sem fome por recursos. A contraparte, claro, é que o KVM não funciona em qualquer computador, mas apenas naqueles com os processadores apropriados. Para computadores baseados em x86, você pode verificar que você tem tal processador procurando por “vmx” ou “svm” nas flags da CPU listadas em /proc/cpuinfo.
Com a Red Hat ativamente suportando seu desenvolvimento, o KVM se tornou mais ou menos a referência na virtualização do Linux.

12.2.3.1. Etapas Preliminares

Ao contrário de ferramentas como o VirtualBox, o KVM em si não inclui nenhuma interface de usuário para a criação de gerenciamento de máquinas virtuais. O pacote qemu-kvm apenas fornece um executável capaz de iniciar uma máquina virtual, assim como um script de inicialização que carrega os módulos do núcleo apropriados.
Felizmente, a Red Hat também fornece outro conjunto de ferramentas para resolver esse problema, tendo desenvolvido a biblioteca libvirt e as ferramentas do gerenciador de máquinas virtuais associadas. A libvirt permite o gerenciamento de máquinas virtuais de maneira uniforme, independentemente do sistema de virtualização envolvido nos bastidores (ela atualmente suporta QEMU, KVM, Xen, LXC, OpenVZ, VirtualBox, VMWare e UML). O virtual-manager é uma interface gráfica que usa a libvirt para criar e gerenciar máquinas virtuais.
Nós primeiro instalamos os pacotes necessários, com apt-get install qemu-kvm libvirt-bin virtinst virt-manager virt-viewer. O libvirt-bin fornece o daemon libvirtd, que permite o gerenciamento (potencialmente remoto) de máquinas virtuais rodando no host, e inicia as VMs necessárias quando o host inicializa. Além disso, esse pacote fornece a ferramenta de linha de comando virsh, que permite o controle das máquinas gerenciadas pelo libvirtd.
O pacote virtinst fornece o virt-install, o qual permite a criação de máquinas virtuais a partir da linha de comando. E finalmente, o virt-viewer que permite o acessar o console gráfico das VM's.

12.2.3.2. Configuração de Rede

Assim como no Xen e no LXC, a configuração de rede mais freqüente envolve uma brigde agrupando as intefaces de rede das máquinas virtuais (see Seção 12.2.2.2, “Configuração de Rede”).
Alternativamente, e na configuração padrão fornecida pelo KVM, um endereço privado é atribuído a máquina virtual (no intervalo 192.168.122.0/24), e o NAT é configurado para que a VM possa acessar a rede externa.
O restante desta seção assume que o host tem uma interface física eth0 e uma bridge br0, e que a primeira está conectada a última.

12.2.3.3. Instalação com virt-install

A criação de uma máquina virtual é muito similar a instalação de um sistema normal, exceto que as características da máquina virtual são descritas em uma linha de comando aparentemente interminável.
Em termos práticos, isso significa que nós iremos usar o instalador Debian, inicializando a máquina virtual pelo drive DVD-ROM virtual que é mapeado para uma imagem de DVD do Debian armazenada no sistema do host. A VM irá exportar seu console gráfico pelo protocolo VNC (see Seção 9.2.2, “Usando Ambientes Gráficos Remotamente” for details), o que irá nos permitir controlar o processo de instalação.
Nós primeiro precisamos avisar o libvirtd aonde armazenar as imagens de disco, a não ser que a localização padrão (/var/lib/libvirt/images/) seja boa.
root@mirwiz:~# mkdir /srv/kvm
root@mirwiz:~# virsh pool-create-as srv-kvm dir --target /srv/kvm
Pool srv-kvm created

root@mirwiz:~# 
Vamos agora iniciar o processo de instalação da máquina virtual, e ter um olhar mais atento nas mais importantes opções do virt-install. Esse comando registra a máquina virtual e seus parâmetros no libvirtd, e então, a inicia, para que a sua instalação possa prosseguir.
# virt-install --connect qemu:///system  1
               --virt-type kvm           2
               --name testkvm            3
               --ram 1024                4
               --disk /srv/kvm/testkvm.qcow,format=qcow2,size=10 5
               --cdrom /srv/isos/debian-8.1.0-amd64-netinst.iso  6
               --network bridge=br0      7
               --vnc                     8
               --os-type linux           9
               --os-variant debianwheezy

Starting install...
Allocating 'testkvm.qcow'             |  10 GB     00:00
Creating domain...                    |    0 B     00:00
Guest installation complete... restarting guest.

1

A opção --connect especifica o “hypervisor” a ser usado. Sua forma é a de uma URL contendo o sistema de virtualização (xen://, qemu://, lxc://, openvz://, vbox://, e assim por diante) e a máquina que deve hospedar a VM (isso pode ser deixado vazio, no caso de ser um hospedeiro local). Além disso, no caso do QEMU/KVM, cada usuário pode gerenciar máquinas virtuais trabalhando com permissões restritas, e o caminho da URL permite diferenciar máquinas do “sistema” (/system) de outras (/session).

2

Como o KVM é gerenciado da mesma maneira que o QEMU, o --virt-type kvm permite especificar o uso do KVM, mesmo que a URL se pareça com a do QEMU.

3

A opção --name define um nome (específico) para a máquina virtual.

4

A opção --ram permite especificar a quantidade de RAM (em MB) a ser alocada para a máquina virtual.

5

A --disk especifica a localização do arquivo de imagem que irá representar nosso disco rígido da máquina virtual; esse arquivo é criado, se não estiver presente, com tamanho(em GB) especificado pelo parâmetro size. O parâmetro format permite escolher, entre várias maneiras, o armazenamento do arquivo de imagem. O formato padrão (raw) é um arquivo único que corresponde exatamente ao tamanho do disco e seu conteúdo. Nós pegamos um formato mais avançado aqui, que é específico para o QEMU e permite iniciar com um pequeno arquivo que só cresce quando a máquina virtual realmente começa a usar espaço.

6

A opção --cdrom é usada para indicar aonde encontrar o disco ótico para usar na instalação. O caminho pode ser tanto um caminho local para um arquivo ISO, uma URL aonde o arquivo pode ser obtido, ou um arquivo de dispositivo de um drive físico de CD-ROM (por exemplo /dev/cdrom).

7

A --network especifica como a placa de rede virtual se integra na configuração de rede do hospedeiro. O comportamento padrão (o qual nós explicitamente forçamos em nosso exemplo) é para integrá-la em qualquer bridge de rede préexistente. Se tal bridge não existe, a máquina virtual irá apenas alcançar a rede física através de NAT, ficando em um intervalo de endereço da sub-rede privada (192.168.122.0/24).

8

--vnc determina que o console gráfico de ser disponibilizado usando o VNC. O comprotamento padrão para o servidor VNC associado é para apenas escutar na interface local; se um cliente VNC tiver que ser executado em um host diferente, para estabelecer a conexão será necessário a configuração de um túnel SSH (veja Seção 9.2.1.3, “Criando Túneis Criptografados com Encaminhamento de Porta”). Alternativamente, a --vnclisten=0.0.0.0 pode ser usada para que o servidor VNC seja acessível a partir de todas as interfaces; note que se você fizer isso, você realmente deve projetar seu firewall de maneira apropriada.

9

As opções --os-type e --os-variant permitem a otimização de alguns parâmetros de máquina virtual, com base em algumas das conhecidas características do sistema operacional ali mencionadas.
Nesse ponto, a máquina virtual está rodando, e nós precisamos nos conectar ao console gráfico para prosseguir com o processo de instalação. Se a operação prévia foi executada a partir de um ambiente gráfico, essa conexão deve ser iniciada automaticamente. Se não, ou se nós operamos remotamente, o virt-viewer pode ser rodado a partir de qualquer ambiente gráfico para abrir o console gráfico (note que a senha do root do host remoto é pedida duas vezes porque a operação requer 2 conexões SSH):
$ virt-viewer --connect qemu+ssh://root@server/system testkvm
root@server's password: 
root@server's password: 
Quando o processo de instalação terminar, a máquina virtual é reiniciada, e agora pronta para o uso.

12.2.3.4. Gerenciando Máquina com virsh

Agora que instalação está feita, vamos ver como lidar com as máquinas virtuais disponíveis. A primeira coisa a tentar é pedir ao libvirtd a lista de máquinas virtuais que ele gerencia:
# virsh -c qemu:///system list --all
 Id Name                 State
----------------------------------
  - testkvm              shut off
Vamos iniciar nossa máquina virtual de teste:
# virsh -c qemu:///system start testkvm
Domain testkvm started
Nós podemos agora pegar as instruções de conexão para o console gráfico (o visor VNC retornado pode ser dado como parâmetro para o vncviewer):
# virsh -c qemu:///system vncdisplay testkvm
:0
Outros subcomandos disponíveis para o virsh incluem:
  • reboot reinicia uma máquina virtual;
  • shutdown para ativar um desligamento limpo;
  • destroy, para parar abruptamente;
  • suspend para pausar a mesma;
  • resume para despausar a mesma;
  • autostart para habilitar (ou desabilitar, com a opção --disable) o início da máquina virtual automaticamente quando o hospedeiro é iniciado;
  • undefine para remover todos os registros de uma máquina virtual do libvirtd.
Todos esses subcomandos têm como parâmetro a identificação da máquina virtual.

12.2.3.5. Instalando um sistema baseado em RPM no Debian com o yum

Se a máquina virtual está destinada a rodar um Debian (ou um dos seus derivados), o sistema pode ser inicializado com o debootstrap, como descrito acima. Mas se a máquina virtual for para ser instalada em um sistema baseado em RPM (como o Fedora, CentOS ou Scientific Linux), a configuração terá de ser feita usando o utilitário yum (disponível pelo pacote de mesmo nome).
O procedimento necessita do uso do rpm para extrair um conjunto inicial de arquivos, incluindo, notávelmente, os arquivos configuração do yum, e então chamar o yum para extrair o conjunto de pacotes remanecentes. Mas como nós chamamos o yum a partir do lado de fora do chroot, nós precisamos fazer algumas mudanças temporárias. No exemplo abaixo, o chroot alvo é /srv/centos.
# rootdir="/srv/centos"
# mkdir -p "$rootdir" /etc/rpm
# echo "%_dbpath /var/lib/rpm" > /etc/rpm/macros.dbpath
# wget http://mirror.centos.org/centos/7/os/x86_64/Packages/centos-release-7-1.1503.el7.centos.2.8.x86_64.rpm
# rpm --nodeps --root "$rootdir" -i centos-release-7-1.1503.el7.centos.2.8.x86_64.rpm
rpm: RPM should not be used directly install RPM packages, use Alien instead!
rpm: However assuming you know what you are doing...
warning: centos-release-7-1.1503.el7.centos.2.8.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID f4a80eb5: NOKEY
# sed -i -e "s,gpgkey=file:///etc/,gpgkey=file://${rootdir}/etc/,g" $rootdir/etc/yum.repos.d/*.repo
# yum --assumeyes --installroot $rootdir groupinstall core
[...]
# sed -i -e "s,gpgkey=file://${rootdir}/etc/,gpgkey=file:///etc/,g" $rootdir/etc/yum.repos.d/*.repo