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:
  • The hypervisor itself. According to the available hardware, the appropriate package providing xen-hypervisor will be either xen-hypervisor-4.14-amd64, xen-hypervisor-4.14-armhf, or xen-hypervisor-4.14-arm64.
  • A kernel that runs on that hypervisor. Any kernel more recent than 3.0 will do, including the 5.10 version present in Bullseye.
  • A arquitetura i386 também requer uma biblioteca padrão com os patches apropriados para aproveitar o Xen; ela está no pacote libc6-xen.
The hypervisor also brings xen-utils-4.14, which contains tools to control the hypervisor from the dom0. This in turn brings the appropriate standard library. During the installation of all that, configuration scripts also create a new entry in the GRUB bootloader menu, so as to start the chosen kernel in a Xen dom0. Note, however, that this entry is not usually set to be the first one in the list, but it will be selected by default.
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-cmd, to specify the which debootstrap command is used. The default is debootstrap if debootstrap and cdebootstrap are installed. In that case, the --dist option will also most often be used (with a distribution name such as bullseye).
  • --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 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=bullseye --role=udev

General Information
--------------------
Hostname       :  testxen
Distribution   :  bullseye
Mirror         :  http://deb.debian.org/debian
Partitions     :  swap            512M  (swap)
                  /               2G    (ext4)
Image type     :  sparse
Memory size    :  256M
Bootloader     :  pygrub

[...]
Logfile produced at:
	 /var/log/xen-tools/testxen.log

Installation Summary
---------------------
Hostname        :  testxen
Distribution    :  bullseye
MAC Address     :  00:16:3E:C2:07:EE
IP Address(es)  :  dynamic
SSH Fingerprint :  SHA256:K+0QjpGzZOacLZ3jX4gBwp0mCESt5ceN5HCJZSKWS1A (DSA)
SSH Fingerprint :  SHA256:9PnovvGRuTw6dUcEVzzPKTITO0+3Ki1Gs7wu4ke+4co (ECDSA)
SSH Fingerprint :  SHA256:X5z84raKBajUkWBQA6MVuanV1OcV2YIeD0NoCLLo90k (ED25519)
SSH Fingerprint :  SHA256:VXu6l4tsrCoRsXOqAwvgt57sMRj2qArEbOzHeydvV34 (RSA)
Root Password   :  FS7CUxsY3xkusv7EkbT9yae
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".
The standard configuration of the Xen packages does not change the system-wide network configuration. However, the xend daemon is configured to integrate virtual network interfaces into any pre-existing network bridge (with xenbr0 taking precedence if several such bridges exist). We must therefore set up a bridge in /etc/network/interfaces (which requires installing the bridge-utils package, which is why the xen-utils package recommends it) to replace the existing eth0 entry (be careful to use the correct network device name):
auto xenbr0
iface xenbr0 inet dhcp
    bridge_ports eth0
    bridge_maxwait 0
Após reinicializar para termos certeza de que a bridge é criada automaticamente, nós podemos 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 listá-los e iniciá-los/pará-los. Você talvez precise aumentar a memória padrão, editando a variável de memória do arquivo de configuração (neste caso, /etc/xen/testxen.cfg). Aqui nós definimos para 1024 (megabytes).
# xl list
Name                                        ID   Mem VCPUs	State	Time(s)
Domain-0                                     0  3918     2     r-----      35.1
# 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  2757     2     r-----      45.2
testxen                                      3  1024     1     r-----       1.3
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 11 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.
A maioria dos subcomandos xl esperam um ou mais argumentos, muitas vezes um nome domU. Esses argumentos estão bem descritos na página de manual xl(1).

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 grupos de controle, de maneira que diferentes conjuntos de processos chamados de “grupos” têm 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 importante 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. O principal inconvenientes está na 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; nós poderíamos, é claro, mantê-las isoladas da rede e apenas nos comunicarmos com elas através do sistema de arquivos, mas a maioria dos casos de uso envolve oferecer acesso mínimo de rede para os contêineres. No caso típico, cada contêiner terá uma interface de rede virtual conectada à rede real através de uma bridge. Essa interface virtual pode ser conectada tanto diretamente na interface de rede física do hospedeiro (e nesse caso o contêiner 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.
The simple case is just a matter of editing /etc/network/interfaces, moving the configuration for the physical interface (for instance, eth0 or enp1s0) to a bridge interface (usually br0), and configuring the link between them. For instance, if the network interface configuration file initially contains entries such as the following:
auto eth0
iface eth0 inet dhcp
Devem ser desabilitados e substituídos pelo seguinte:
auto br0
iface br0 inet dhcp
    bridge-ports eth0
O efeito dessa configuração será similar ao que seria obtido se os contêineres fossem máquinas conectadas na mesma rede física que a do hospedeiro. A configuração “bridge” gerencia o trânsito dos quadros Ethernet entre todas as interfaces em bridge, o que inclui a eth0 física, assim como as interfaces definidas para os contêineres.
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

Let us now set up the filesystem to be used by the container. Since this “virtual machine” will not run directly on the hardware, some tweaks are required when compared to a standard filesystem, especially as far as the kernel, devices and consoles are concerned. Fortunately, the lxc package includes scripts that mostly automate this configuration. For instance, the following commands (which require the debootstrap and rsync packages) will install a Debian container:
# lxc-create -n testlxc -t debian
debootstrap is /usr/sbin/debootstrap
Checking cache download in /var/cache/lxc/debian/rootfs-stable-amd64 ... 
Downloading debian minimal ...
I: Retrieving Release 
I: Retrieving Release.gpg 
[...]
Download complete.
Copying rootfs to /var/lib/lxc/testlxc/rootfs...
[...]
# 
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 script de criação de modelo 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.
The lxc package further creates a bridge interface lxcbr0, which by default is used by all newly created containers via /etc/lxc/default.conf and the lxc-net service:
lxc.net.0.type = veth
lxc.net.0.link = lxcbr0
lxc.net.0.flags = up
These entries mean, respectively, that a virtual interface will be created in every new container; that it will automatically be brought up when said container is started; and that it will be automatically connected to the lxcbr0 bridge on the host. You will find these settings in the created container's configuration (/var/lib/lxc/testlxc/config), where also the device' MAC address will be specified in lxc.net.0.hwaddr. Should this last entry be missing or disabled, a random MAC address will be generated.
Outra entrada útil nesse arquivo é a configuração de uma nome para o hospedeiro:
lxc.uts.name = testlxc
The newly-created filesystem now contains a minimal Debian system and a network interface.

12.2.2.4. Inicializando o Contêiner

Now that our virtual machine image is ready, let's start the container with lxc-start --name=testlxc.
In LXC releases following 2.0.8, root passwords are not set by default. We can set one running lxc-attach -n testlxc passwd if we want. We can login with:
# lxc-console -n testlxc
Connected to tty 1
Type <Ctrl+a q> to exit the console, <Ctrl+a Ctrl+a> to enter Ctrl+a itself

Debian GNU/Linux 11 testlxc tty1

testlxc login: root
Password: 
Linux testlxc 5.10.0-11-amd64 #1 SMP Debian 5.10.92-1 (2022-01-18) 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.
Last login: Wed Mar  9 01:45:21 UTC 2022 on console
root@testlxc:~# ps auxwf
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root           1  0.0  0.2  18964 11464 ?        Ss   01:36   0:00 /sbin/init
root          45  0.0  0.2  31940 10396 ?        Ss   01:37   0:00 /lib/systemd/systemd-journald
root          71  0.0  0.1  99800  5724 ?        Ssl  01:37   0:00 /sbin/dhclient -4 -v -i -pf /run/dhclient.eth0.pid [..]
root          97  0.0  0.1  13276  6980 ?        Ss   01:37   0:00 sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups
root         160  0.0  0.0   6276  3928 pts/0    Ss   01:46   0:00 /bin/login -p --
root         169  0.0  0.0   7100  3824 pts/0    S    01:51   0:00  \_ -bash
root         172  0.0  0.0   9672  3348 pts/0    R+   01:51   0:00      \_ ps auxwf
root         164  0.0  0.0   5416  2128 pts/1    Ss+  01:49   0:00 /sbin/agetty -o -p -- \u --noclear [...]
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 that we ran the container as a background process, thanks to lxc-start starting using the --daemon option by default. We can interrupt the container with a command such as 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 um virtualizador em si mesmo. O controle real para 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

Unlike such tools as VirtualBox, KVM itself doesn't include any user-interface for creating and managing virtual machines. The virtual qemu-kvm package only provides an executable able to start a virtual machine, as well as an initialization script that loads the appropriate kernel modules.
Fortunately, Red Hat also provides another set of tools to address that problem, by developing the libvirt library and the associated virtual machine manager tools. libvirt allows managing virtual machines in a uniform way, independently of the virtualization system involved behind the scenes (it currently supports QEMU, KVM, Xen, LXC, OpenVZ, VirtualBox, VMWare, and UML). virt-manager is a graphical interface that uses libvirt to create and manage virtual machines.
Nós primeiro instalamos os pacotes necessários, com apt-get install libvirt-clients libvirt-daemon-system qemu-kvm virtinst virt-manager virt-viewer. O libvirt-daemon-system 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. O pacote libvirt-clients 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 frequente envolve uma bridge agrupando as interfaces de rede das máquinas virtuais (veja 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.
We first need to tell libvirtd where to store the disk images, unless the default location (/var/lib/libvirt/images/) is fine.
# mkdir /srv/kvm
# virsh pool-create-as srv-kvm dir --target /srv/kvm
Pool srv-kvm created

# 
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
               --memory 2048             4
               --disk /srv/kvm/testkvm.qcow,format=qcow2,size=10  5
               --cdrom /srv/isos/debian-11.2.0-amd64-netinst.iso  6
               --network bridge=virbr0   7
               --graphics vnc            8
               --os-type linux           9
               --os-variant debiantesting


Starting install...
Allocating 'testkvm.qcow'

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 --memory 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 as várias maneiras de se armazenar o arquivo de imagem. O formato padrão (qcow2) 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).
The default network configuration, which contains the definition for a virbr0 bridge interface, can be edited using virsh net-edit default and started via virsh net-start default if not already done automatically during system start.

8

--vnc determina que o console gráfico de ser disponibilizado usando o VNC. O comportamento 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.4, “Criando Túneis Criptografados com Encaminhamento de Porta”). Alternativamente, --graphics 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.
The full list of OS types can be shown using the osinfo-query os command from the libosinfo-bin package.
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: 
Connecting to installer session using virt-viewer

Figura 12.1. Connecting to installer session using virt-viewer

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
----------------------------------
  8 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
127.0.0.1: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.