Virtualização no Linux: KVM, QEMU e libvirt
Domine a virtualização no Linux com KVM, QEMU e libvirt: criação de VMs com virt-install, virsh, discos qcow2, redes bridge e cloud-init.
InSkillCoach
Virtualização no Linux: KVM, QEMU e libvirt
O KVM é o hipervisor integrado ao kernel Linux: é ele que sustenta boa parte da nuvem mundial, do OpenStack a diversas ofertas de hospedagem. Associado ao QEMU para a emulação de hardware e ao libvirt para o gerenciamento, ele transforma qualquer máquina Linux em uma plataforma de virtualização completa, sem licença nem produto de terceiros. Neste guia, partimos da verificação do suporte de hardware até chegar a máquinas virtuais provisionadas automaticamente com cloud-init, passando por virt-install, virsh, discos qcow2 e configuração de rede.
Vamos primeiro esclarecer o papel de cada componente: o KVM é o módulo do kernel que dá acesso às instruções de virtualização do processador; o QEMU emula o hardware (discos, placas de rede, BIOS/UEFI) e se apoia no KVM para executar o código convidado em velocidade quase nativa; o libvirt é a camada de gerenciamento (API, daemon, CLI virsh) que uniformiza o controle de todo o conjunto.
1. Verificar o suporte de hardware
A virtualização por hardware exige as extensões Intel VT-x ou AMD-V, habilitadas no BIOS/UEFI.
# Contar os flags de virtualização em /proc/cpuinfo
# vmx = Intel VT-x, svm = AMD-V ; um resultado > 0 é bom sinal
grep -Ec '(vmx|svm)' /proc/cpuinfo
# No Ubuntu/Debian, a ferramenta dedicada dá um veredito claro
sudo apt install cpu-checker
kvm-ok
# Resultado esperado :
# INFO: /dev/kvm exists
# KVM acceleration can be used
# Verificar se os módulos do kernel estão carregados
lsmod | grep kvm
# kvm_intel (ou kvm_amd) e kvm devem aparecer
# Verificar o dispositivo KVM
ls -l /dev/kvm
Se o kvm-ok indicar que a virtualização está desativada, reinicie e habilite VT-x/AMD-V no firmware. Para a virtualização aninhada (uma VM dentro de uma VM, útil para laboratórios):
# Verificar o suporte à virtualização aninhada (Intel)
cat /sys/module/kvm_intel/parameters/nested
# Y ou 1 = habilitado
2. Instalar KVM, QEMU e libvirt
Debian/Ubuntu
# Instalar o hipervisor, a camada de gerenciamento e as ferramentas
sudo apt install qemu-kvm libvirt-daemon-system libvirt-clients \
virtinst bridge-utils qemu-utils
# Iniciar e habilitar o daemon libvirt
sudo systemctl enable --now libvirtd
# Adicionar seu usuário aos grupos necessários
# (logout/login necessário para que tenha efeito)
sudo usermod -aG libvirt,kvm "$USER"
Rocky Linux/Fedora
# O grupo de pacotes virtualization instala tudo o que é necessário
sudo dnf install @virtualization
sudo systemctl enable --now libvirtd
sudo usermod -aG libvirt "$USER"
Validar a instalação
# Diagnóstico completo do host de virtualização
virt-host-validate
# Todas as linhas QEMU devem estar PASS (os WARN de IOMMU são
# aceitáveis se você não faz passthrough PCI)
# Verificar a conexão com o libvirt
virsh -c qemu:///system list --all
Duas URIs de conexão coexistem: qemu:///system (VMs gerenciadas pelo daemon do sistema, recomendado para servidores) e qemu:///session (VMs do usuário, sem privilégios). Para evitar qualquer ambiguidade:
# Forçar o virsh a usar a conexão de sistema por padrão
echo 'export LIBVIRT_DEFAULT_URI=qemu:///system' >> ~/.bashrc
3. Criar uma VM com virt-install
Preparar a imagem e o armazenamento
# O diretório padrão das imagens do libvirt
ls /var/lib/libvirt/images/
# Baixar uma ISO do Debian (exemplo)
sudo wget -P /var/lib/libvirt/images/ \
https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/debian-13.1.0-amd64-netinst.iso
Instalação interativa a partir de uma ISO
# Criar uma VM : 2 vCPUs, 4 GB de RAM, disco qcow2 de 20 GB
sudo virt-install \
--name debian-test \
--memory 4096 \
--vcpus 2 \
--disk path=/var/lib/libvirt/images/debian-test.qcow2,size=20,format=qcow2 \
--cdrom /var/lib/libvirt/images/debian-13.1.0-amd64-netinst.iso \
--os-variant debian12 \
--network network=default \
--graphics vnc,listen=127.0.0.1
# Listar os identificadores de SO reconhecidos (otimiza os drivers virtio)
virt-install --osinfo list | grep -i debian
O instalador é exibido via VNC (use virt-viewer debian-test ou um túnel SSH). Para um servidor sem interface gráfica, a abordagem com cloud-init da seção 8 é bem mais eficiente.
4. Gerenciar VMs com virsh
Ciclo de vida
# Listar as VMs (ativas e paradas)
virsh list --all
# Iniciar uma VM
virsh start debian-test
# Desligamento limpo (envia um sinal ACPI, o convidado precisa tratá-lo)
virsh shutdown debian-test
# Desligamento brusco (equivalente a puxar o cabo da tomada)
virsh destroy debian-test
# Reinicialização
virsh reboot debian-test
# Inicialização automática com o host
virsh autostart debian-test
# Console serial em texto (se configurado no convidado)
virsh console debian-test
# Remover uma VM e seus discos definitivamente
virsh undefine debian-test --remove-all-storage
Inspeção e recursos
# Informações detalhadas
virsh dominfo debian-test
# Endereços IP obtidos pela VM
virsh domifaddr debian-test
# Alterar a memória a quente (dentro do limite máximo definido)
virsh setmem debian-test 2048M --live
# Editar a definição XML da VM
virsh edit debian-test
Snapshots
# Criar um snapshot antes de uma operação arriscada
virsh snapshot-create-as debian-test avant-migration \
--description "Avant montée de version PostgreSQL"
# Listar os snapshots
virsh snapshot-list debian-test
# Voltar a um snapshot
virsh snapshot-revert debian-test avant-migration
# Remover um snapshot que se tornou inútil
virsh snapshot-delete debian-test avant-migration
Os snapshots internos exigem o formato qcow2. Atenção: um snapshot não é um backup; ele vive no mesmo disco da VM e degrada levemente o desempenho se for acumulando.
5. Discos qcow2 com qemu-img
O formato qcow2 (QEMU Copy-On-Write) suporta alocação sob demanda (thin provisioning: o arquivo só cresce conforme os dados reais), snapshots internos e imagens de base.
# Criar um disco de 50 GB (ocupa apenas alguns KB no início)
qemu-img create -f qcow2 /var/lib/libvirt/images/data.qcow2 50G
# Inspecionar uma imagem : tamanho virtual vs tamanho real em disco
qemu-img info /var/lib/libvirt/images/debian-test.qcow2
# Aumentar um disco (depois será preciso estender a partição no convidado)
qemu-img resize /var/lib/libvirt/images/debian-test.qcow2 +20G
# Converter uma imagem VMware/VirtualBox para qcow2
qemu-img convert -f vmdk -O qcow2 machine.vmdk machine.qcow2
# Compactar uma imagem (VM obrigatoriamente parada)
qemu-img convert -O qcow2 ancienne.qcow2 compactee.qcow2
Imagens de base e clones leves
# Criar um clone que armazena apenas as diferenças em relação à imagem de base
qemu-img create -f qcow2 -F qcow2 \
-b /var/lib/libvirt/images/base-debian.qcow2 \
/var/lib/libvirt/images/clone-01.qcow2
# Verificar a cadeia de dependências
qemu-img info --backing-chain /var/lib/libvirt/images/clone-01.qcow2
Nunca modifique nem mova uma imagem de base enquanto houver clones que dependam dela: todos os clones seriam corrompidos.
6. Redes libvirt: NAT e Bridge
A rede NAT padrão
Na instalação, o libvirt cria a rede default: uma bridge interna virbr0 em 192.168.122.0/24 com DHCP integrado (dnsmasq). As VMs saem para a Internet via NAT, mas não são acessíveis a partir da rede física.
# Listar as redes libvirt
virsh net-list --all
# Iniciar e tornar persistente a rede padrão
virsh net-start default
virsh net-autostart default
# Ver as concessões DHCP atribuídas às VMs
virsh net-dhcp-leases default
Bridge: VMs como cidadãs da rede local
Para que as VMs obtenham um endereço IP da rede física (como máquinas de pleno direito), crie uma bridge no host. Exemplo com Netplan (Ubuntu Server), em /etc/netplan/01-bridge.yaml:
network:
version: 2
ethernets:
enp3s0:
dhcp4: false
bridges:
br0:
interfaces: [enp3s0]
dhcp4: true
# Aplicar com uma janela de reversão automática em caso de perda de conexão
sudo netplan try
# Verificar a bridge
ip addr show br0
Em seguida, conecte as VMs à bridge:
# Na criação
virt-install ... --network bridge=br0 ...
# Ou modifique uma VM existente : no virsh edit, substitua
# <source network='default'/> por <source bridge='br0'/>
| Modo | Endereço IP da VM | Acessível a partir da LAN | Caso de uso |
|---|---|---|---|
| NAT (default) | 192.168.122.x privado | Não | Ambientes de dev, labs isolados |
| Bridge (br0) | Endereço da LAN | Sim | Servidores de produção |
| Isolated | Privado, sem saída | Não | Testes de segurança, sandboxes |
7. Contêineres LXC ou máquinas virtuais?
O LXC executa contêineres de sistema: espaços isolados que compartilham o kernel do host, enquanto o KVM inicia um kernel completo por máquina. As duas abordagens frequentemente coexistem no mesmo host (o Proxmox é um exemplo disso).
| Critério | LXC (contêiner de sistema) | KVM (máquina virtual) |
|---|---|---|
| Kernel | Compartilhado com o host | Próprio de cada VM |
| Isolamento | Namespaces e cgroups | Por hardware (VT-x/AMD-V) |
| Densidade | Muito alta (centenas por host) | Limitada pela RAM dedicada |
| Inicialização | Cerca de 1 segundo | 10 a 60 segundos |
| Sobrecarga de memória | Quase nula | RAM reservada por VM |
| SO convidado | Somente Linux | Linux, Windows, BSD |
| Kernel ou módulos personalizados | Impossível | Sim |
| Segurança multilocatário | Adequada, superfície maior | Forte, referência da nuvem pública |
# Visão rápida do LXC no Ubuntu
sudo apt install lxc
sudo lxc-create -n conteneur-test -t download -- -d debian -r bookworm -a amd64
sudo lxc-start -n conteneur-test
sudo lxc-attach -n conteneur-test
Regra de decisão: LXC para muitos ambientes Linux leves em uma mesma máquina; KVM sempre que for necessário outro SO, um kernel específico ou um isolamento forte entre locatários.
8. cloud-init: automatizar o provisionamento
O cloud-init é o padrão de inicialização das imagens de nuvem: no primeiro boot, a VM lê uma configuração (usuários, chaves SSH, pacotes, comandos) e se autoconfigura. Combinado com as imagens de nuvem oficiais, ele elimina completamente a instalação manual.
Obter uma imagem de nuvem
# Imagem de nuvem Ubuntu 24.04 (qcow2 pronto para uso, cerca de 600 MB)
sudo wget -P /var/lib/libvirt/images/ \
https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img
Escrever a configuração user-data
# /tmp/user-data.yaml
#cloud-config
hostname: vm-web-01
users:
- name: admin
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bash
ssh_authorized_keys:
- ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA... admin@poste-travail
package_update: true
packages:
- nginx
- htop
runcmd:
- systemctl enable --now nginx
Criar a VM provisionada
# Criar o disco da VM a partir da imagem de nuvem (clone leve ampliado)
sudo qemu-img create -f qcow2 -F qcow2 \
-b /var/lib/libvirt/images/noble-server-cloudimg-amd64.img \
/var/lib/libvirt/images/vm-web-01.qcow2 20G
# virt-install gera a ISO do cloud-init automaticamente com --cloud-init
sudo virt-install \
--name vm-web-01 \
--memory 2048 \
--vcpus 2 \
--disk path=/var/lib/libvirt/images/vm-web-01.qcow2,format=qcow2 \
--import \
--os-variant ubuntu24.04 \
--network network=default \
--cloud-init user-data=/tmp/user-data.yaml \
--noautoconsole
# Dois minutos depois : obter o endereço IP e se conectar
virsh domifaddr vm-web-01
ssh admin@192.168.122.53
A VM inicia, cria o usuário, instala o nginx e ativa o serviço sem nenhuma intervenção. Esse processo pode ser transformado em script e depois industrializado com Terraform (provider libvirt) ou Ansible.
Boas práticas
- Execute
virt-host-validateapós qualquer instalação ou atualização do host. - Trabalhe sempre em
qemu:///systempara servidores e definaLIBVIRT_DEFAULT_URIpara evitar VMs “sumidas” criadas na conexão errada. - Sempre informe
--os-variantno virt-install: os drivers virtio selecionados fazem uma enorme diferença de desempenho. - Prefira
virsh shutdownavirsh destroy: um desligamento brusco pode corromper os sistemas de arquivos do convidado. - Trate os snapshots como pontos de retorno temporários, nunca como backups: faça backup dos arquivos qcow2 (com a VM parada ou via um snapshot externo consistente).
- Nunca mexa em uma imagem de base referenciada por clones.
- Reserve o NAT para ambientes de teste; use uma bridge para qualquer serviço que precise ser acessível.
- Padronize o provisionamento com cloud-init a partir da segunda VM: a configuração manual não escala.
- Monitore o espaço em disco de
/var/lib/libvirt/images: os qcow2 com alocação sob demanda crescem silenciosamente até encher o volume.
Conclusão
A pilha KVM, QEMU e libvirt oferece virtualização de nível de produção apenas com ferramentas do mundo livre: o KVM traz o desempenho quase nativo, o QEMU a emulação de hardware, e o libvirt uma interface de gerenciamento coerente, da estação de desenvolvimento ao cluster. Agora você sabe verificar o suporte de hardware, instalar a pilha, criar VMs com virt-install, controlá-las com virsh, gerenciar discos qcow2, escolher entre NAT e bridge, decidir entre contêineres LXC e máquinas virtuais, e automatizar o provisionamento com cloud-init.
O próximo passo é industrializar: descreva suas VMs no Terraform com o provider libvirt, configure-as com Ansible, e sua infraestrutura de virtualização se torna reproduzível, versionada e auditável como código.
Sobre InSkillCoach
Especialista em treinamento e tecnologias
Coach especializado em tecnologias avançadas e IA, apoiado pela GNeurone Inc.
Certificações:
- AWS Certified Solutions Architect – Professional
- Certificações Google Cloud
- Microsoft Certified: DevOps Engineer Expert
- Certified Kubernetes Administrator (CKA)
- CompTIA Security+
Comentários
Os comentários são alimentados pelo GitHub Discussions
Conecte-se com o GitHub para participar da discussão