Skip to main content

KVM



Informações importantes


Este documento foi criado usando como bases algumas fontes de conhecimento, tentei mesclar e deixar o mais claro possível para o leitor, revisando e pegando o que tinha de melhor nessas fontes de conhecimento, tentando deixar esse documento o mais prático possível, mas sem dispensar a teoria que é de extrema importância.


Todas as fontes usadas estão no final do tutorial na sessão Fontes, mas você verá que existem algumas fontes que aparecem bastante lá, isso porque além das muitas fontes da Internet que foram usadas, algumas são a base para a criação deste documento e são de extrema recomendação minha, são elas: Guia de Administração de Virtualização da RedHat e Mastering KVM Virtualization.

O documento vai se basear no uso do comando virsh, apesar de ser possível gerenciar tudo via interface gráfica, vou evitar o uso da mesma, já que no dia a dia é quase certeza que a maioria só terá a CLI para gerenciar as máquinas virtuais.



Introdução


O Kernel Virtual Machine (KVM) é uma tecnologia de virtualização open source baseada no Linux. Com o KVM, é possível transformar o Linux em um hypervisor, permitindo assim que o sistema execute vários ambientes virtuais isolados, conhecidos com guest ou máquinas virtuais.

O KVM faz parte do Linux e foi incluído na versão 2.6.20 do Kernel!


O KVM é um hypervisor híbrido, isso significa que ele é um hypervisor do Tipo 1 e do Tipo 2, embora precise de um sistema operacional Linux genérico para funcionar, é capaz de funcionar como um hypervisor perfeitamente bem, integrando-se a uma instalação do Linux em execução. As máquinas virtuais implantadas com KVM usam o daemon libvirt e utilitários de software associados para serem criados e gerenciados.


O KVM faz uso das extensões de virtualização dos processadores (HVM), sendo vmx para Intel e svm para AMD. Com o KVM vamos usar também o QEMU, Libvirt, Virt-manager entre outros utilitários.



Tipos de hypervisors


Há dois tipos de hypervisors que podem ser usados para a virtualização: são o tipo 1 e o tipo 2.

  • Tipo 1

    É comumente conhecido como hypervisor nativo ou até mesmo bare-metal, ele é executado diretamente no hardware do host para gerenciar sistemas operacionais guest. Ele ocupa o lugar de um sistema operacional host, e os recursos da máquina virtual são programados diretamente no hardware pelo hypervisor.

    Exemplos: VMware vSphere/ESXi, Microsoft Hyper-V, Oracle VM Server, Xen, KVM.


    O Sistemas Operacional nesse caso é o próprio Hypervisor.

    Este tipo de Hypervisor é mais comum em data centers pois o hardware precisa ser bastante robusto, o que é mais encontrado em servidores (quanto mais robusto mais caro será o hardware).

  • Tipo 2

    É denominado hosted e é executado em um Sistema Operacional convencional, tendo uma camada de software ou aplicação para gerenciar tanto o hypervisor quanto as máquina virtuais.


    Normalmente o gerenciamento do Hypervisor em sí é bastante tranquilo, sendo feita a instalação, configurações necessária e desse ponto em diante, todo o gerenciamento mesmo é feito em cima das máquinas virtuais somente, já que a base (hypervisor) já está solidificada no Sistema Operacional.

    Esse tipo de hypervisor é mais usado por usuários individuais que desejam executar vários sistemas operacionais em um computador pessoal para fins de testes/aprendizado, mesmo que ainda seja possível encontrar esse tipo em pequenas empresas.

    Exemplos: Oracle VirtualBox e VMWare Workstation.

O Quick Emulator ou apenas QEMU é o principal componente no quesito virtualização, é ele quem fornece uma maneira de fazer virtualização de hardware e emulação de processador.



QEMU - Quick Emulator


O Quick Emulator ou apenas QEMU é o principal componente no quesito virtualização, é ele quem fornece uma maneira de fazer virtualização de hardware e emulação. O QEMU usa o KVM apenas para fazer a virtualização de máquinas virtuais, mas pode ser usado sozinho para fazer a emulação de outros sistemas e aplicações.


Resumindo, o QEMU é responsável pela emulação de dispositivos, como redes, discos, placas de vídeo e outros componentes de hardware, que são necessários para que as máquinas virtuais funcionem corretamente. Ele fornece uma camada de abstração que permite que as máquinas virtuais acessem esses dispositivos, mesmo que eles não estejam fisicamente presentes no hardware real.


Já o KVM vai fornece recursos de virtualização de hardware, como HVM (Hardware Virtual Machine), para o QEMU. Isso permite que o QEMU execute as máquinas virtuais de forma mais eficiente, aproveitando as extensões de virtualização do processador subjacente. Com o KVM, as máquinas virtuais podem ter um desempenho melhor e um acesso mais direto aos recursos de hardware do sistema hospedeiro.


A imagem abaixo demonstra as camadas no Sistema com uso do Xen, KVM e apenas QEMU. A imagem é disponibilizada por researchgate.net.

Xen vs KVM vs QEMU


Para executar máquinas virtuais o QEMU precisa de um local para armazenar o filesystem da máquina virtual, esse local é conhecido como image, em uma curta e pobre explicação, image é o HD da máquina virtual. Podemos criar um disco virtual usando o QEMU da seguinte forma:

$ qemu-img create -f raw ubuntu.img 15G 
Formatting 'ubuntu.img', fmt=raw size=16106127360

# Para obter informações sobre a image:
$ qemu-img info ubuntu.img
image: ubuntu.img
file format: raw
virtual size: 15 GiB (16106127360 bytes)
disk size: 4 KiB

# Verificando o tamanho do "disco":
$ du -hs ubuntu.img
4,0K ubuntu.img

O qemu-img é um utilitário que permite criar, converter e modificar imagens de convidados, é espcialmente útil quando precisamos redimensionar tamanho de disco. Vamos ver abaixo os dicos mais comuns e que são suportados pelo QEMU.

Formato do discoDescrição
rawÉ o formato de imagem de disco bruto. Este é o formato padrão, é um dos formatos baseados em arquivo mais rápidos.
qcow2Este é um dos formatos com mais recursos em comparação aos demais, oferece suporte a instantâneo de VM, compactação e criptografia pelo preço de desempenho ligeiramente reduzido.
qcowEste é um formato de imagem QEMU mais antigo que suporta arquivos de backup, arquivos de imagem compactos, criptografia e compactação.
dmgEste é o formato de imagem de disco do Mac. A imagem de disco do Mac fornece proteção e compactação por senha segura e é mais comumente usada para distribuir software, em vez de executar máquinas virtuais.
nbdO dispositivo de bloco de rede, normalmente usado para acessar dispositivos de armazenamento remoto.
vdiEste formato de disco é usado pelo software Oracle VirtualBox e pode ser usado para executar máquinas virtuais em várias plataformas de CPU.
vmdkEste é o tipo de imagem de disco VMware, em que um único disco rígido virtual pode abranger vários arquivos.
vhdxo Microsoft Hyper-V usa esse formato de imagem. Ele oferece grande capacidade de armazenamento, proteção contra corrupção de dados durante falhas de energia e otimização de leitura/gravação para imagens de disco maiores.

Como podemos ver com um breve resumo, tanto a tecnologia do KVM de transformar o Linux no Hypervisor como uma ferramenta para criação de sistema virtualizados são muitos importantes e um não vive sem o outro, mesmo que sejam desenvolvidos sob o mesmo pacote.


Como disse Konstantin Ivanov (2017) em KVM Virtualization Cookbook página 89:

Os comandos QEMU são convenientes para iniciar rapidamente instâncias virtuais; no entanto, eles não fornecem uma maneira fácil e agíl de configurar e administrar o ciclo de vida das máquinas virtuais.


E aqui nasce outra ferramenta para tornar nossas um pouco mais fácil.



Storage


Vamos entender o que são pools de armazenamento, vamos recaptular o NFS, depois veremos protocolos de nível de bloco, como iSCSI e FC. Em seguida, veremos um pouco de redundância e multipathing para que possamos aumentar a disponibilidade e a largura de banda de nossos dispositivos de armazenamento.


Vamos ver como instalar e configurar quase todos os tipos de armazenamento, cada um deles tem seu próprio caso de uso, mas como boa parte das tecnologias, cabe a você escolher qual vai usar.



Storage Pools


Em poucas palavras um pool de armazenamento é um arquivo, diretório ou dispositivo de armazenamento que é gerenciado pela libvirt com a finalidade de fornecer armazenamento para máquinas virtuais convidadas.

O Pool pode ser local ou remoto.


De fato o pool de armazenamento é uma quantidade de armazenamento reservada pelo administrador de armazenamento, normalmente é um armazenamento dedicado somente para uso das máquinas virtuais convidadas. Os pools podem ser divididos em volumes de armazenamento pelo administrador de armazenamento ou pelo administrador do sistema, e os volumes são atribuídos a máquinas virtuais convidadas como dispositivos de bloco.

Simplificando, é como se os volumes de armazenamento fossem as partições e os pools de armazenamento fossem os discos.


O pool de armazenamento é um contêiner virtual limitado ao tamanho máximo permitido a ele pelo qemu-kvm e pelo tamanho do disco na máquina hospedeira.

Os pools de armazenamento não podem exceder o tamanho do disco na máquina física do host e seguem um tamanhos máximo!

  • virtio-blk = 2^63 bytes or 8 Exabytes(using raw files or disk)

  • Ext4 = ~ 16 TB (using 4 KB block size)

  • XFS = ~8 Exabytes

O libvirt usa um conjunto de armazenamento baseado em diretório, o diretório /var/lib/libvirt/images/, como o conjunto de armazenamento padrão. Esse conjunto de armazenamento padrão pode ser alterado para outro conjunto de armazenamento.



Local Storage Pools


Armazenamento local é conectado diretamente ao hospedeiro, os pools de armazenamento local incluem: diretórios locais, discos conectados diretamente, partições físicas e grupos de volumes LVM. Esses volumes de armazenamento armazenam imagens de máquinas virtuais convidadas ou são anexados a máquinas virtuais convidadas como armazenamento adicional.


Como os pools de armazenamento local são conectados diretamente ao hospedeiro, eles são úteis para desenvolvimento, teste e pequenas implantações que não exigem migração ou que necessitem ter um grande número de máquinas virtuais. Os pools de armazenamento local não são adequados para muitos ambientes de produção, pois os pools de armazenamento local não suportam a migração ao vivo.



Networked storage pools


Os pools de armazenamento na Rede incluem dispositivos de armazenamento compartilhados na Rede usando um protocolos padrão. O armazenamento em rede é necessário ao migrar máquinas virtuais entre máquinas hospedeiras com virt-manager (mas é opcional ao migrar usando o virsh). Os pools de armazenamento em rede são gerenciados pelo libvirt. Alguns dos protocolos suportados nessa modalidade são: NFS, iSCSI, Fibre Channel-based LUNs e GFS2.



Libvirt storage pools


O Libvirt gerencia seus próprios pools de armazenamento, pelo motivo do libvirt usar o que o sistema operacional subjacente suporta, ele suporta muitos tipos diferentes de pool de armazenamento, como: Diretório, Disco, FS, Gluster, iSCSI, LVM, MPATH (Multi-Path), SCI, ZFS e muitos outros.


Assim que instalado, o Libvirt já vem com um storage pool definido, sendo do tipo diretório, é onde ele armazena as imagens dos sistemas convidados.

# Verifique os pools existentes:
$ virsh pool-list
Name State Autostart
---------------------------------
teste active yes
default active yes

# Verifique a configuração desse pool:
$ virsh pool-dumpxml default
<pool type='dir'>
<name>default</name>
<uuid>6dac4e40-8cf6-4abd-8551-9766bbc240e5</uuid>
<capacity unit='bytes'>500684595200</capacity>
<allocation unit='bytes'>419733553152</allocation>
<available unit='bytes'>80951042048</available>
<source>
</source>
<target>
<path>/var/lib/libvirt/images</path>
<permissions>
<mode>0711</mode>
<owner>0</owner>
<group>0</group>
</permissions>
</target>
</pool>


Criando Storage Pools


Pools e volumes fornecem uma maneira para que o libvirt possa garantir que haverá armazenamento disponível para as máquinas virtuais, alguns administradores preferem gerenciar seu próprio armazenamento e as máquinas virtuais convidadas funcionarão corretamente sem nenhum pool ou volume, nestes casos os administradores do sistema devem garantir a disponibilidade de armazenamento para as máquinas virtuais.


Existem algumas formas de usarmos Storage Pools, cada método vai ter uma maneira de aplicação e execução diferente, não pretendo abordar todos eles aqui, mas abordarei alguns, para ter acesso a outros método veja aqui.



Storage Pools baseado em diretório


Este é o método padrão numa instalação padrão, mas podemos customizar aos montes e até selecionar outro diretório para manter nosso pool.

Os objetos no libvirt podem ser transitórios ou persistentes. Um objeto transitório existe apenas enquanto estiver em execução, ao parar essa execução esse objeto deixa de existir, enquanto que um objeto persistente existe o tempo todo.


Em outras pálavras, um objeto do tipo persistente salva sua configuração em um arquivo XML que é armazenado pelo libvirt em /etc/libvirt. Enquanto que um objeto do tipo transitório não possui configuração salva e por isso, ai parar a execução desse objeto ele deixará de existir, já que o libvirt não tem sua configuração para inicia-lo novamente.

# Primeiro crie o diretório novo:
$ sudo mkdir /libvirt-images

# Crie o pool (caso o diretório não exista, ele será criado):
$ virsh pool-define-as new_libvirt_dir --type dir --target /libvirt-images
Pool new_libvirt_dir defined

# Inicie o pool:
$ virsh pool-start new_libvirt_dir
Pool new_libvirt_dir started

# Habilite para ele iniciar no Boot:
$ virsh pool-autostart new_libvirt_dir
Pool new_libvirt_dir marked as autostarted

# Verifique se aparece no sistema:
$ virsh pool-list
Name State Autostart
---------------------------------------
default active yes
new_libvirt_dir active yes

# Verifique as informações do Pool
$ virsh pool-info new_libvirt_dir
Name: new_libvirt_dir
UUID: 5e857b9e-0f47-40a2-acb6-f3d48d573142
State: running
Persistent: yes
Autostart: yes
Capacity: 466,30 GiB
Allocation: 391,12 GiB
Available: 75,18 GiB

Perceba que ele obtém o tamanho total do disco, vamos configurar um pool que tenha um tamanho limitado, mas antes, teremos que excluir esse Pool:

# Primeiro desative o Pool, já que ele está em uso:
$ virsh pool-destroy new_libvirt_dir
Pool new_libvirt_dir destroyed

# Podemos excluir o diretório usando o comando:
$ virsh pool-delete new_libvirt_dir
Pool new_libvirt_dir deleted

# Remova a definição do pool de dentro do sistema:
$ virsh pool-undefine new_libvirt_dir
Pool new_libvirt_dir has been undefined

Vale ressaltar que esse comando pool-delete apaga o diretório também, já o comando pool-undefine somente remove o pool do sistema, mas mantém o diretório.

O comando pool-define é para ser usado diretamente com arquivos XML enquanto que o comando pool-define-as é usado diretamente na linha de comando.



Storage Pools baseado em Disco


Este método uso um disco como pool ao invés de um diretório, vamos preparar nosso disco para receber o pool:

# Primeiro vamos preparar o disco:
$ sudo parted /dev/sda
GNU Parted 3.3
Usando /dev/sda
Bem vindo ao GNU Parted! Digite 'help' para ver uma lista de comandos.
(parted) mklabel
Novo tipo de rótulo de disco? gpt
Atenção: O rótulo de disco existente em /dev/sda será destruído e todos os dados neste disco serão perdidos. Você deseja continuar?
Sim/Yes/Não/No? Sim
(parted) quit
Informação: Você pode precisar atualizar /etc/fstab.

# Crei o pool:
$ virsh pool-define-as libvirt-pool_disk --type disk --target /dev/sda --source-dev /dev/sda --source-format gpt
Pool libvirt-pool_disk defined

# Inicie o pool:
$ virsh pool-start libvirt-pool_disk
Pool libvirt-pool_disk started

# Habilite para ele iniciar no Boot:
$ virsh pool-autostart libvirt-pool_disk
Pool libvirt-pool_disk marked as autostarted

# Verifique se aparece no sistema:
$ virsh pool-list
Name State Autostart
---------------------------------------
default active yes
libvirt-pool_disk active yes

# Verifique as informações do Pool:
$ virsh pool-info libvirt-pool_disk
Name: libvirt-pool_disk
UUID: 6e61a3cf-f7af-4966-8609-bd37cf6cc1c7
State: running
Persistent: yes
Autostart: yes
Capacity: 483,80 MiB
Allocation: 0,00 B
Available: 483,79 MiB

Nesse meu caso usei um pendrive. Perceba que não é necessário criar uma partição, apenas o disco, sem partição.


Para deletar é a mesma receita de bolo, mas nesse caso sem a parte que podemos remover o diretório:

# Desativar o pool:
$ virsh pool-destroy libvirt-pool_disk

# Remover as configurações dele do sistema:
$ virsh pool-undefine libvirt-pool_disk


Storage Pools baseado em Partição


O processo é bem parecido com o uso de disco, o que mudar é que aqui vamos informar as partições que vamos usar.

# Primeiro vamos preparar o disco:
$ sudo fdisk /dev/sda

Bem-vindo ao fdisk (util-linux 2.34).
As alterações permanecerão apenas na memória, até que você decida gravá-las.
Tenha cuidado antes de usar o comando de gravação.


Comando (m para ajuda): g
Criado um novo rótulo de disco GPT (GUID: 56A34CFC-A6F0-C74E-BC6E-2EAE0850A97B).

Comando (m para ajuda): n
Número da partição (1-128, padrão 1):
Primeiro setor (2048-990831, padrão 2048):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-990831, padrão 990831):

Criada uma nova partição 1 do tipo "Linux filesystem" e de tamanho 482,8 MiB.
Partição nº 1: contém uma assinatura de vfat.

Deseja remover a assinatura? [S]im/[N]ão: s

A assinatura será removida por um comando de escrita.

Comando (m para ajuda): w
A tabela de partição foi alterada.
Chamando ioctl() para reler tabela de partição.
Sincronizando discos.

Estou usando o mesmo Pendrive de antes.


Agora com a partição criada, vamos criar o pool, a diferença aqui é o tipo de pool (fs para partição) e o --target vamos informar onde será montando a partição.

# Crie o pool:
$ virsh pool-define-as libvirt-pool_fs --type fs --target /mnt/libvirt-pool_fs --source-dev /dev/sda1 --source-format auto

# Faça o build para criar a pasta:
$ virsh pool-build libvirt-pool_fs
Pool libvirt-pool_fs built

# Inicie o pool:
$ virsh pool-start libvirt-pool_fs

# Habilite no boot:
$ virsh pool-autostart libvirt-pool_fs

# Liste os pools existentes:
$ virsh pool-list
Name State Autostart
---------------------------------------
default active yes
libvirt-pool_fs active yes

# Veja informações do pool:
$ virsh pool-info libvirt-pool_fs
Name: libvirt-pool_fs
UUID: 3467c0ec-5a18-478c-8184-fb7e0945cb3f
State: running
Persistent: yes
Autostart: yes
Capacity: 481,04 MiB
Allocation: 4,00 KiB
Available: 481,04 MiB

# Veja se a partição realmente foi montada:
$ df -h /dev/sda1
Sist. Arq. Tam. Usado Disp. Uso% Montado em
/dev/sda1 482M 4,0K 482M 1% /mnt/libvirt-pool_fs

# Desativar o pool:
$ virsh pool-destroy libvirt-pool_fs

# Remover as configurações dele do sistema:
$ virsh pool-undefine libvirt-pool_fs


Storage Pools baseado em NFS


Não vou demonstrar como subir um servidor NFS, apenas como conectar em um já existente, mas antes de tudo, é necessário instalar os pacotes do NFS client:

PacotesDistroDescrição
nfs-commonDebian likeUtilitário para o Cliente NFS.
nfs-utilsRedHat likeUtilitário para o Cliente NFS e Servidor NFS.

Crie um arquivo XML para armazenar a configuração do Pool que vamos criar:

<pool type='netfs'>
<name>NFSPool</name>
<source>
<host name='IP'/>
<dir path='Caminho'/>
<format type='auto'/>
</source>
<target>
<path>/var/lib/libvirt/images/NFSPool</path>
<permissions>
<mode>0755</mode>
<owner>0</owner>
<group>0</group>
<label>system_u:object_r:nfs_t:s0</label>
</permissions>
</target>
</pool>

Vejamos agora algumas descrições das opções acima:

OpçãoDescrição
host name='IP'Deve ser fornecido o IP do servidor NFS.
dir pathO caminho completo que foi configurado no arquivo /etc/exports do servidor NFS.
<path>...</path>O caminho de onde será montado o compartilhamento NFS.
permissionsPermissões usadas para montar o filesystem.
labelO rótulo SELinux para este diretório, isso é uma diretriz para solução de problemas na plataforma KVM.


Volumes


Os pools de armazenamento são divididos em volumes de armazenamento e são o resultado das partições físicas, volumes lógicos LVM, imagens de disco baseadas em arquivo e muitos outros tipos.


Os volumes de armazenamento são apresentados às máquinas virtuais convidadas como dispositivos de armazenamento local, independentemente do hardware subjacente.


Volumes de referência

Para referenciar um volume específico, três abordagens são possíveis:

  • O nome do volume e o conjunto de armazenamento

    Um volume pode ser referenciado pelo nome, juntamente com o identificador para o conjunto de armazenamento ao qual ele pertence. Podemos ver isso usando o comando virsh:

    # Liste as VMs:
    $ virsh list --all
    Id Name State
    --------------------------------------------
    - centos7 shut off
    - Eve-NG shut off
    - rocky shut off
    - ubuntu20.04 shut off

    # Agora liste os volumes que estão no pool default:
    $ virsh vol-list default
    Name Path
    ------------------------------------------------------------------------------------------------------------------------------------------------------------------
    centos-VAGRANTSLASH-7_vagrant_box_image_2004.01.img /var/lib/libvirt/images/centos-VAGRANTSLASH-7_vagrant_box_image_2004.01.img
    centos7.qcow2 /var/lib/libvirt/images/centos7.qcow2
    focal-live-server-amd64.iso /var/lib/libvirt/images/focal-live-server-amd64.iso
    generic-VAGRANTSLASH-ubuntu2004_vagrant_box_image_3.2.14.img /var/lib/libvirt/images/generic-VAGRANTSLASH-ubuntu2004_vagrant_box_image_3.2.14.img
    generic-VAGRANTSLASH-ubuntu2004_vagrant_box_image_4.0.2.img /var/lib/libvirt/images/generic-VAGRANTSLASH-ubuntu2004_vagrant_box_image_4.0.2.img
    generic-VAGRANTSLASH-ubuntu2004_vagrant_box_image_4.0.2_box.img /var/lib/libvirt/images/generic-VAGRANTSLASH-ubuntu2004_vagrant_box_image_4.0.2_box.img
    rocky-clone.qcow2 /var/lib/libvirt/images/rocky-clone.qcow2
    rocky.qcow2 /var/lib/libvirt/images/rocky.qcow2
    te_default.img /var/lib/libvirt/images/te_default.img
    ubuntu20.04.qcow2 /var/lib/libvirt/images/ubuntu20.04.qcow2
    Ubuntu_2004_first.qcow2 /var/lib/libvirt/images/Ubuntu_2004_first.qcow2
    ## Perceba que eu tenho volumes nos quais não pertencem a nenhuma VM, já que normalmente o volume possui o mesmo nome que a VM (mas nem sempre)!

    # Agora vamos ao que interessa, vamos verificar o volume de uma VM no pool default:
    $ virsh vol-info --pool default ubuntu20.04.qcow2
    Name: ubuntu20.04.qcow2
    Type: file
    Capacity: 15,00 GiB
    Allocation: 6,92 GiB

- **O caminho completo para o armazenamento no sistema de máquina física host**

Um volume também pode ser referenciado pelo caminho completo do arquivo no sistema, se usarmos esse método não é necessário usar o identificador de pool.

Por exemplo, o volume denominado ubuntu20.04.qcow2, é visível para o sistema do hospedeiro tendo o caminho /var/lib/libvirt/images/ubuntu20.04.qcow2, então nesse caso podemos chamar a imagem apenas referenciando o caminho completo.

$ virsh vol-info /var/lib/libvirt/images/ubuntu20.04.qcow2
Name: ubuntu20.04.qcow2
Type: file
Capacity: 15,00 GiB
Allocation: 6,92 GiB

  • A tecla de volume exclusiva

    Quando um volume é criado pela primeira vez no sistema, um identificador exclusivo é gerado para ele, esse identificador é denominado de chave de volume. O formato dessa chave varia de acordo com o armazenamento usado.

    Para ver a key do volume basta usar o comando abaixo:

    # Informando o pool ao qual o volume esta armazenado:
    $ virsh vol-key --pool default --vol rocky-clone.qcow2
    /var/lib/libvirt/images/rocky-clone.qcow2

    # Usando o caminho completo:
    $ virsh vol-key /var/lib/libvirt/images/ubuntu20.04.qcow2
    /var/lib/libvirt/images/ubuntu20.04.qcow2


Criando volumes


Agora vamos ver como criar os volumes manualmente, normalmente isso não é necessário, mas serve para os casos onde é necessário criar um disco a mais para uma VM, ou para que possa gerenciar os volumes e/ou excluir eles.

# Crie um volume chamado 'volume1' de 8GB no formato qcow2:
$ virsh vol-create-as default volume1.qcow2 8G --format qcow2 --prealloc-metadata
Vol volume1.qcow2 created

# Veja se ele foi criado no pool:
$ virsh vol-list default | sed -n '1,2p; /volume1/p'
Name Path
-------------------------------------------------------
volume1.qcow2 /var/lib/libvirt/images/volume1.qcow2


Clonando volumes


Para facilitar a vida do administrador é possível clonar um volume já existente.

# Clone o volume:
$ virsh vol-clone --pool default volume1.qcow2 clone1

# Verifique se deu certo:
$ virsh vol-list default | sed -n '1,2p; /clone1/p'
Name Path
-------------------------------------------------------
clone1 /var/lib/libvirt/images/clone1


Rezise de volumes


Vamos ver como redimensionar os volumes, isso é bastante útil para quando queremos aumentar o tamanho de um disco, vale ressaltar que ao aumentar o tamanho do disco, é necessário fazer com que o sistema da máquina virtual identifique o novo tamanho do disco e depois é preciso expandir o file system do Sistema.

# Veja o tamanho do disco antes de mudarmos:
$ virsh vol-info /var/lib/libvirt/images/vol2.qcow2
Name: vol2.qcow2
Type: file
Capacity: 20,00 GiB
Allocation: 3,32 MiB

# Agora redimensione o tamanho do disco, deixando com 25GB:
$ virsh vol-resize --pool default vol2.qcow2 25G
Size of volume 'vol2.qcow2' successfully changed to 25G

## Pode ser feito com outro comando:
$ sudo qemu-img resize /var/lib/libvirt/images/vol2.qcow2 +5G

## Também pode ser feito assim:
$ sudo virsh blockresize ubuntu20.04 /var/lib/libvirt/images/ubuntu20.04.qcow2 40G
Block device '/var/lib/libvirt/images/ubuntu20.04.qcow2' is resized

# Veja o tamanho do disco novamente:
$ virsh vol-info /var/lib/libvirt/images/vol2.qcow2
Name: vol2.qcow2
Type: file
Capacity: 25,00 GiB
Allocation: 3,32 MiB


Anexar volumes nas VMs


Existem dois tipos de volumes que podemos anexar as máquinas virtuais, um deles é o armazenamento baseado em arquivo, esse método é um arquivo armazenado na máquina hospedeira que atua como se fosse discos rígidos mas que são virtualizados para máquinas virtuais, esse é o modelo mais comum para o ambiente virtualizado.


Para adicionar um volume baseado em arquivo primeiro é necessário ter um disco que seja suportado pela VM, no nosso caso já temos, o volume1 foi criado usando o formato qcow2, o mesmo usado pelas máquinas virtuais, agora execute as etapas abaixo:

# Precisamos criar um arquivo xml para armazenar o conteúdo abaixo:

<disk type='file' device='disk'>
<driver name='qemu' type='raw'/>
<source file='/var/lib/libvirt/images/volume1.qcow2'/>
<target dev='vdb' bus='virtio'/>
</disk>

Vamos adicionar o disco na VM.

# O comando abaixo adiciona a configuração do novo disco na VM para o próximo boot:
$ virsh attach-device --config ubuntu20.04 newdisk.xml
Device attached successfully

# O comando abaixo adiciona a configuração do novo disco no momento da execução do comando:
$ virsh attach-device ubuntu20.04 newdisk.xml --current
Device attached successfully

# Anexar disco sem usar xml:
$ virsh attach-disk --current ubuntu20.04 --source /var/lib/libvirt/images/vol2.qcow2 --target vdb
Disk attached successfully

# Veja os discos da VM usando o comando abaixo:
$ virsh domblklist --domain ubuntu20.04
Target Source
-----------------------------------------------------
vda /var/lib/libvirt/images/ubuntu20.04.qcow2
vdb /var/lib/libvirt/images/ubuntu.qcow2
vdc /var/lib/libvirt/images/vol2.qcow2
sda -

Esse método adiciona o disco na VM até que ela fique inativa, depois a configuração do disco nela é perdida:

# Agora adicione a configuração do novo disco na VM:
$ virsh attach-device ubuntu20.04 newdisk.xml
Device attached successfully


Desanexar volumes nas VMs


Vamos ver como remover um volume de uma VM sem apagar esse volume:

# Veja quais discos a VM possui:
$ virsh domblklist --domain ubuntu20.04
Target Source
-----------------------------------------------------
vda /var/lib/libvirt/images/ubuntu20.04.qcow2
vdb /var/lib/libvirt/images/ubuntu.qcow2
vdc /var/lib/libvirt/images/vol2.qcow2
sda -

# Remove o disco VDB do domínio 'ubuntu20.04' (nome da VM):
$ virsh detach-disk ubuntu20.04 vdb --current
Disk detached successfully


Deletar um volume


Existem dois tipos de volumes que podemos anexar as máquinas virtuais, um deles é o armazenamento baseado em arquivo

$ virsh vol-delete --pool default volume1


Network


Vamos entender como funciona a parte do gerenciamento de Redes, tanto virtual quanto física e dar uma rápida olhada sobre virtual switching. Esse tópico é importante e se torna um pilar básico no gerencimento de máquinas virtuais, não é algo que acabará gerenciando sempre, mas com certeza é um passo fundamental quando está criando o projeto de virtualização e pode e provavelmente vai precisar revisar, adicionar ou remover alguma rede no futuro.



Redes físicas e virtuais


Tanto uma rede física quanto uma virtual funcionam com o mesmo objetivo, interconectar diferentes sistemas permitindo que eles interajam entre sí. Olhando as redes virtuais elas conectam basicamente sistemas virtualizados enquanto que as redes físicas conectam sistemas físicos, claro que para ter um sistema virtual temos que antes ter um sistema físico, mas essa é apenas uma explicação sucinta.



Switchs Virtuais


Os switchs virtuais são essenciais para conectarmos nossas máquinas virtuais neles, podendo assim interconectar diferentes máquinas virtuais. Sem um software (um virtual switch nesse caso) para ficar entre nossa rede física e nossa rede virtual nós somente poderíamos conectar uma máquina virtual no qual tivéssemos uma interface física para isso, tanto no servidor quanto no switch físico. Não vou entrar em detalhes, mas pense o quanto isso não iria consumir no quesito energético e financeiro.



Virtual Network Interface Card - vNIC


A placa de interface de rede virtual é usada para conectar a máquina virtual ao switch virtual que usa a interface de rede física da máquina hospedeira para conectar os equipamentos virtuais ao switch físico (normalmente). Cuidado com essa abordagem pois se for usado apenas uma única interface física como uplink para o virtual switch e essa interface ficar indisponível, todas as máquinas ficarão sem rede externa.


A comunicação só vai ocorrer com as máquinas diretamente conectadas no mesmo switch virtual (como se um switch físico perdesse comunicação com outro switch físico, apenas os dispositivos conectados no mesmo switch irão se comunicar, claro, sem levar em consideração a VLAN).


Para contornar esse problema, basta usar mais de um uplink para os switchs virtuais (usar mais de uma interface física), assim como é feito em redes físicas para solucionar o mesmo problema, vamos criar uma redundancia no link para evitar um problema. Veja abaixo alguns dos muitos tipos de interfaces de Rede no Linux:

TipoDescrição
BridgeInterface camada 2 que conectam máquinas virtuais a rede física.
BondUsado para combinar várias interfaces físicas numa única interface virtual; em outras palavras é um LACP.
Muito usado para balanceamento/redundância ao mesmo tempo que aumenta o bandwidth (caso configurado assim) .
TeamDiferente do bond não é criado uma interface virtual, mas ainda serve para redundância e balanceamento de carga.
MACVLANCria vários endereços MAC em uma única interface física (cria subinterfaces) na camada 2.
IPVLANAo contrário do MACVLAN, o IPVLAN usa o mesmo endereço MAC e faz multiplex na camada 3.
MACVTAP/IPVTAPSão drivers mais novo que devem simplificar a rede virtual combinando TUN, TAP e ponte como um único módulo.
VXLANÉ possível criar uma rede lógica entre máquinas virtuais em diferentes redes, ou seja, é possível conectar duas ou mais redes de camada 3 numa rede de camada 2.
Desse modo cada rede opera como se estivessem conectadas numa rede de camada 2, cada uma faz parte da sua própria rede, mas estão dentro do mesmo domínio.
GRETAP e GREProtocolos de encapsulamento de roteamento genérico para encapsular protocolos de camada 2 e camada 3, respectivamente.
GENEVEUm protocolo de convergência para rede de sobreposição de nuvem que se destina a fundir VXLAN, GRE e outros em um só.
VETHUma interface Ethernet virtual que pode ser usada de várias maneiras para encapsulamento local.


NAT Network


Uma Rede NAT é o padrão ao configurar uma rede com Libvirt, com esse tipo de rede nós temos nossa própria rede privada atrás de um ou mais endereços IP (normalmente usa-se apenas um). Isso significa que a VM recebe um IP e que ela só poderá se comunicar com dispositivos externos usando o endereço IP físico da interface física, para isso é feito uma tradução de endereçamento.


Para melhor visualização segue um diagrama do funcionamento disponibilizado pela RedHat aqui.

Virtual network switch using NAT with two guests - Picture from RedHat



Routed Network


O switch virtual se conecta à LAN física que está conectada à máquina hospedeira, o VS (virtual switch) passa todo o tráfego para frente e para trás sem ter que usar NAT. O layout é bem similar ao NAT, mas o que muda é que ao invés te ter uma tradução de endereçamento, existe um roteamento entre endereços.


O VS pode examinar todo o tráfego e usar as informações contidas nos pacotes de rede para tomar decisões de roteamento. Nesse modo todas as VMs estão em sua própria sub-rede, roteadas por meio de um comutador virtual.


Nenhuma outra máquina física na rede está ciente das VMs sem que haja uma configuração manual do roteador físico e as máquinas da rede não podem acessar as máquinas virtuais. Para melhor visualização segue um diagrama do funcionamento disponibilizado pela RedHat aqui.

Virtual Switch on Routed mode - Picture from RedHat



Isolated Network


Nesse tipo de Rede, as VM só podem se conectar umas com as outras (via switch virtual), é "criado" um switch virtual isolado e somente as VMs conectadas nele podem se comunicar, a comunicação não pode sair daqui para com outras VMs ou Redes.

É uma maneira ideal de isolar tipos específicos de tráfego para que ele nem chegue à rede física.

Muito útil por exemplo para conectar uma máquina com banco de dados a outra máquina que precisa ler esse banco e disponibilizar os dados na Internet; a máquina com o banco de dados fica na Rede isolada e a máquina que consulta possui uma interface na rede isolada (para ler os dados do banco) e outra interface na rede Routed para que as pessoas possam ter acesso a essa informação, dessa forma, a máquina/dados não são trafegados na rede, apenas o que tiver que ser exibido, esse modelo é bastante seguro. Para melhor visualização segue um diagrama do funcionamento disponibilizado pela RedHat aqui.

Virtual network switch in isolated mode - Picture from RedHat



Bridge Network


Usamos esse modo para conectar as VM na mesma rede do qual o hospedeiro está conectado, tornando possível a comunicação de dispositivos na rede com a máquina virtual. Para melhor visualização segue um diagrama do funcionamento disponibilizado pela RedHat aqui.

Virtual network switch in bridged mode - Picture from RedHat

Para ter uma rede Bridge é necessário que o host hospedeiro possua uma interface conectada na Rede e que essa interface não possua endereçamento. Depois é preciso configurar uma interface virtual como Bridge apontando para essa interface física, mais adiante vamos ver como configurar.



Open Network


Descrito em libvirt.org, 20222. Disponível em: < https://libvirt.org/formatnetwork.html#elementsConnect >.

Acesso em: 27 de jun. de 2022.

Assim como em mode='route', o tráfego de rede convidado será encaminhado para a rede física por meio da pilha de roteamento IP do host, mas não haverá regras de firewall adicionadas para habilitar ou impedir esse tráfego. Quando forward='open' está definido, o atributo dev não pode ser definido (porque o forward dev é aplicado com regras de firewall, e o propósito de forward='open' é ter um modo de encaminhamento onde libvirt não adiciona nenhuma regra de firewall ).


Este modo presume que o roteador de LAN local tenha entradas de tabela de roteamento adequadas para retornar o tráfego para esse host e que algum outro sistema de gerenciamento tenha sido usado para implementar as regras de firewall necessárias. Embora nenhuma regra de firewall seja adicionada para a rede, é claro que ainda é possível adicionar restrições para convidados específicos usando regras nwfilter nas interfaces dos convidados.).



Gerenciando as Redes


Agora que entendemos as redes que é possível criar, vamos ver algumas opções do comando virsh net-* que são usados para trabalhar com redes no KVM.

OpçõesDescrição
net-listExibe todas as redes existentes.
net-info (Nome da Rede)Mostra informações sobre uma rede.
net-destroy (Nome da Rede)Desativa a rede do sistema (ainda pode ser usada).
net-undefine (Nome da Rede)Exclui a rede do sistema (precisa do net-destroy para ter efeito imediato).
net-edit (Nome da Rede)Edita a configuração da rede.
net-autostart (Nome da Rede)Configura a rede para ser iniciada no Boot, a opção --disable pode
ser usada para não iniciar no Boot.
net-create (arquivo.xml)Cria uma rede a partir de um arquivo XML e ativa ela,
a rede não vai iniciar no Boot e não será persistente.
net-define (arquivo.xml)Cria uma rede a partir de um arquivo XML que é iniciada no Boot e é persistente,
mas não ativa ela.
net-start (Nome da Rede)Inicia uma rede inativa.
net-uuid (Nome da Rede)Converte o nome da rede para o UUID.
net-update (Nome da Rede)Atualiza parte da configuração de uma rede existente (verifique as sub-opções).
net-dhcp-leasesExibe os endereços DHCP emprestados.
net-dumpxml (Nome da Rede)Obtém toda a configuração de uma rede.
uuidgenUsado para gerar um UUID para quando formos criar uma rede.

Agora vamos ver alguns comandos na prática.

# Primeiro, vamos descobrir quais redes possuímos:
$ virsh net-list
Name State Autostart Persistent
-----------------------------------------------------
default active yes yes
network_ipv6_onl active yes yes
vagrant-libvirt active no yes

# Liste as informações da rede 'defaut':
$ virsh net-info default
Name: default
UUID: 02bc4986-4e30-4292-9c3d-9f1df159035c
Active: yes
Persistent: yes
Autostart: yes
Bridge: virbr0

# Vamos ver como é a configuração da rede 'defaut':
$ virsh net-dumpxml default
<network>
<name>default</name>
<uuid>02bc4986-4e30-4292-9c3d-9f1df159035c</uuid>
<forward mode='nat'>
<nat>
<port start='1024' end='65535'/>
</nat>
</forward>
<bridge name='virbr0' stp='on' delay='0'/>
<mac address='52:54:00:ea:b8:82'/>
<ip address='192.168.122.1' netmask='255.255.255.0'>
<dhcp>
<range start='192.168.122.2' end='192.168.122.254'/>
</dhcp>
</ip>
</network>

# Resultado de quando vemos um IP emprestado:
$ virsh net-dhcp-leases default
Expiry Time MAC address Protocol IP address Hostname Client ID or DUID
-----------------------------------------------------------------------------------------------------------
2022-06-27 11:23:56 52:54:00:da:49:69 ipv4 192.168.122.87/24 idm 01:52:54:00:da:49:69


Criando uma Rede


O processo de criação de uma rede é um tanto simples, a parte mais dificíl seria gerar um endereço MAC para usarmos na nossa rede, mas até isso foi facilitado pela Red Hat que disponibilizou um script para gerar endereços MAC.


Como o prefixo das minhas redes do KVM começam com 52:54:00, no script eu alterei 0x00, 0x16, 0x3e para 0x52, 0x54, 0x00, assim os endereços MAC gerados pelo script vão ter o mesmo prefixo já usado no meu ambiente, isso mantém o padrão e facilita saber de onde é tal endereço MAC.


Vamos criar uma rede com NAT.

# Faça um dump da Rede default:
$ virsh net-dumpxml default > TutoNewNat.xml

# Agora vamos gerar um novo UUID:
$ uuidgen
944df9a1-960c-42fd-b020-e81537d3afcf

# Gere um novo MAC:
./macgen.py
52:54:00:7c:0c:0d

# Edite o arquivo 'TutoNewNat.xml' e altere o nome da rede: <name>default</name>;
# Mude o UUID: <uuid>944df9a1-960c-42fd-b020-e81537d3afcf</uuid>;
# Mude o MAC: <mac address='52:54:00:7c:0c:0d'/>;
# Mude o nome da interface: <bridge name='virbr2' stp='on' delay='0'/>
# Mude os IPs!

# Meu arquivo ficou assim:
<network>
<name>TutoNewNat</name>
<uuid>944df9a1-960c-42fd-b020-e81537d3afcf</uuid>
<forward mode='nat'>
<nat>
<port start='1024' end='65535'/>
</nat>
</forward>
<bridge name='virbr2' stp='on' delay='0'/>
<mac address='52:54:00:7c:0c:0d'/>
<ip address='192.168.123.1' netmask='255.255.255.0'>
<dhcp>
<range start='192.168.123.2' end='192.168.123.254'/>
</dhcp>
</ip>
</network>

# Agora crie a Rede:
$ virsh net-define TutoNewNat.xml
Network TutoNewNat defined from TutoNewNat.xml

# Ative a Rede:
$ virsh net-start TutoNewNat
Network TutoNewNat started

# Habilite para subir no Boot:
$ virsh net-autostart TutoNewNat
Network TutoNewNat marked as autostarted

# Verifique as redes existentes:
$ virsh net-list
Name State Autostart Persistent
----------------------------------------------------
default active yes yes
TutoNewNat active yes yes
vagrant-libvirt active no yes

Segue exemplo de uma Rede Routed:

<network>
<name>routed</name>
<forward dev='enxa' mode='route'>
<interface dev='enxa'/>
</forward>
<bridge name='virbr5' stp='on' delay='0'/>
<domain name='routed'/>
<ip address='172.16.20.1' netmask='255.255.255.0'>
<dhcp>
<range start='172.16.20.2' end='172.16.20.254'/>
</dhcp>
</ip>
</network>

Tive que incluir configuração de Firwall adicional para fazer funcionar.


Segue exemplo de uma rede Isolated:

<network>
<name>isolated</name>
<domain name="isolated"/>
<ip address="192.168.151.1" netmask="255.255.255.0">
<dhcp>
<range start="192.168.151.2" end="192.168.151.254"/>
</dhcp>
</ip>
</network>

Exemplo de Rede Open:

<network>
<name>Salt</name>
<uuid>7e2d2faa-702d-4ac2-9dc2-aca62b390d10</uuid>
<forward mode='open'/>
<bridge name='virbr3' stp='on' delay='0'/>
<mac address='52:54:00:34:79:2e'/>
<domain name='Salt'/>
<ip address='192.168.100.1' netmask='255.255.255.0'>
</ip>
</network>

Vamos ver como configurar uma Rede em Bridge.

# Primeiro edite a configuração da Rede no host Hospedeiro:
$ sudo cat /etc/netplan/01-network-manager-all.yaml
network:
version: 2
renderer: NetworkManager
ethernets:
enxa:
dhcp4: false
bridges:
br0:
dhcp4: yes
interfaces:
- enxa
parameters:
stp: false
forward-delay: 0
version: 2
## Não se esqueça de mudar o nome da interface física 'enxa'!

# Agora crie um arquivo parecido com o abaixo:
$ cat kvmbridge.xml
<network>
<name>br0</name>
<forward mode="bridge"/>
<bridge name="br0"/>
</network>

# Crie a interface no libvirt:
$ virsh net-define kvmbridge.xml
Network br0 defined from kvmbridge.xml

# Inicie a interface:
$ virsh net-start br0
Network br0 started


Instalação


Vamos então instalar o QEMU, KVM e Libvirt para começar a usar o ambiente.

$ sudo apt install -y qemu qemu-kvm libvirt-daemon libvirt-clients bridge-utils libosinfo-bin

Se quiser instalar (e recomendo que o faça) um gerenciador gráfico para estar criando e trabalhando com as VMs, instale também o virt-manager.


Nós podemos validar as configurações de virtualização do host usando o comando abaixo:

$ virt-host-validate                                                                                                                   ↵ 1
QEMU: Checking for hardware virtualization : PASS
QEMU: Checking if device /dev/kvm exists : PASS
QEMU: Checking if device /dev/kvm is accessible : PASS
QEMU: Checking if device /dev/vhost-net exists : PASS
QEMU: Checking if device /dev/net/tun exists : PASS
QEMU: Checking for cgroup 'cpu' controller support : PASS
QEMU: Checking for cgroup 'cpuacct' controller support : PASS
QEMU: Checking for cgroup 'cpuset' controller support : PASS
QEMU: Checking for cgroup 'memory' controller support : PASS
QEMU: Checking for cgroup 'devices' controller support : PASS
QEMU: Checking for cgroup 'blkio' controller support : PASS
QEMU: Checking for device assignment IOMMU support : PASS
QEMU: Checking if IOMMU is enabled by kernel : WARN (IOMMU appears to be disabled in kernel. Add intel_iommu=on to kernel cmdline arguments)
QEMU: Checking for secure guest support : WARN (Unknown if this platform has Secure Guest support)
LXC: Checking for Linux >= 2.6.26 : PASS
LXC: Checking for namespace ipc : PASS
LXC: Checking for namespace mnt : PASS
LXC: Checking for namespace pid : PASS
LXC: Checking for namespace uts : PASS
LXC: Checking for namespace net : PASS
LXC: Checking for namespace user : PASS
LXC: Checking for cgroup 'cpu' controller support : PASS
LXC: Checking for cgroup 'cpuacct' controller support : PASS
LXC: Checking for cgroup 'cpuset' controller support : PASS
LXC: Checking for cgroup 'memory' controller support : PASS
LXC: Checking for cgroup 'devices' controller support : PASS
LXC: Checking for cgroup 'freezer' controller support : PASS
LXC: Checking for cgroup 'blkio' controller support : PASS
LXC: Checking if device /sys/fs/fuse/connections exists : PASS

Para consertar o aviso do IOMMU basta informar ao Kernel que vamos usar esse recurso, fazendo:

# Em '/etc/default/grub':
GRUB_CMDLINE_LINUX='intel_iommu=on'

# Depois aplique as configurações do grub:
$ sudo update-grub

Podemos também verificar a rede que está configurada no KVM e se temos máquinas virtuais:

# Verificando rede para serem usadas pelas VMs (já criei algumas):
$ virsh net-list
Name State Autostart Persistent
-----------------------------------------------------
default active yes yes
network_ipv6_onl active yes yes
Salt active yes yes
vagrant-libvirt active no yes

# Verificando as máquinas virtuais:
$ virsh list --all
Id Name State
-----------------------------------
- centos7 shut off
- ubuntu20.04 shut off


Nossa primeira VM


Vamos rodar nossa primeira máquina virtual. Na linha de comando, execute o comando abaixo, lembrando que você deve ter a ISO do ubuntu nesse caso baixada e copiada para /var/lib/libvirt/images:

$ virt-install --virt-type=kvm --name Ubuntu_2004_first --vcpus 2 --ram 4096 \
--os-variant=ubuntu20.04 --cdrom=/var/lib/libvirt/images/focal-live-server-amd64.iso \
--network=default --graphics vnc --disk size=16

Para saber qual é o nome que deverá usar em --os-variant=, rode o comando osinfo-query os. Esse parâmetro ajuda a melhorar o desempenhando da VM fornecendo o nome de qual sistema operacional vamos usar.



Gerenciando VM usando Libvirt


Gerenciando as máquinas virtuais via CLI.

ComandoDescrição
virsh list --allExibe todas as máquinas virtuais (sem o --all mostra só as que
estiverem em funcionamento).
virsh domrename nome1 novonome2Renomeia uma VM.
virsh start VM_NAMEInicia uma Máquina Virtual.
virsh shutdown VM_NAMEDesliga a máquina virtual, é um desligamento soft (gentil).
virsh destroy VM_NAMEDesliga a máquina virtual, é como se tirássemos o cabo de
energia do computador, é um desligamento hard (bruto).
virsh undefine VM_NAMESe a VM estiver ligada, após desligá-la ela será deletada,
se estiver desligada, será deletada de imediato. (O disco será mantido)
virsh undefine VM_NAME --remove-all-storageRemove a VM e apaga os discos.
virt-clone --original VM_NAME --name VM_NAME-Clone --auto-cloneComando para Clonar uma VM.
virt-clone --original VM_NAME --name VM_NAME-Clone --file name.qcow2Clona uma VM para usar um HD específico.
virsh domblklist --domain VM_NAMEVer os HDs de uma VM.
virsh snapshot-list --domain VM_NAMEVer os snapshots da VM.
virsh snapshot-delete --domain VM_NAME --snapshotname SNAPSHOT_NAMEDeleta um snaphost.
sudo virsh edit ubuntu20.04Edita a configuração da VM.
virsh detach-disk ubuntu20.04 vdb --configRemove o disco VDB da VM no próximo boot da VM.
virsh detach-disk ubuntu20.04 vdb --currentRemove o disco VDB da VM com ela desligada.


OVirt e Virt-Manager


Essas duas ferramentas são utilitários para gerênciar os host guests usando uma interface gráfica.

Com o Virt-Manager é possível configurar ele para se conectar num Host remoto para gerenciar as máquinas virtuais.



Outros comandos


O comando abaixo mostra algumas informações de uma VM que está em execução:

$ virsh qemu-monitor-command ubuntu20.04 info block --hmp
libvirt-2-format: /var/lib/libvirt/images/ubuntu20.04.qcow2 (qcow2)
Attached to: /machine/peripheral/virtio-disk0/virtio-backend
Cache mode: writeback

sata0-0-0: [not inserted]
Attached to: sata0-0-0
Removable device: not locked, tray closed


Fontes


https://wiki.qemu.org/Main_Page

https://sobrelinux.info/questions/5086/what-is-iommu-and-will-it-improve-my-vm-performance

https://blog.hostonnet.com/virt-install-os-variant-does-not-exist

https://www.cyberciti.biz/faq/how-to-clone-existing-kvm-virtual-machine-images-on-linux/

https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/virtualization_administration_guide/delete-lvm-storage-pool-virsh

https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/virtualization_administration_guide/chap-virtualization_administration_guide-storage_concepts

https://www.cyberciti.biz/faq/howto-linux-delete-a-running-vm-guest-on-kvm/

https://www.vmware.com/topics/glossary/content/virtual-networking.html

https://www.gta.ufrj.br/ensino/eel879/trabalhos_vf_2012_2/nvgre/vxlan.html

https://www.juniper.net/br/pt/research-topics/what-is-vxlan.html

https://docs.docker.com/network/ipvlan/

https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/virtualization_administration_guide/sub-sect-routed-mode-libvirt

https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/virtualization_administration_guide/sect-bridged-mode

https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/virtualization_administration_guide/sub-sect-iso-mode

https://jamielinux.com/docs/libvirt-networking-handbook/routed-network.html

https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/virtualization_administration_guide/chap-virtualization_administration_guide-storage_concepts#doc-wrapper

https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/virtualization_administration_guide/sect-virtualization-storage_concepts-volumes

https://stackoverflow.com/questions/41471006/virsh-difference-between-pool-define-as-and-pool-create-as

https://bgstack15.wordpress.com/2017/09/22/create-attach-detach-disk-to-vm-in-kvm-on-command-line/

# ver como migrar uma VM de um host para outro.

https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/virtualization_administration_guide/chap-virtualization_administration_guide-kvm_live_migration