enchufado
   RSS
#
Laboratorio con KVM (Virtualización) 2021-10-16 10:53:03

En éste post vamos a ver cómo montar un laboratorio de hosts virtuales (guests) con KVM que compartan la misma red (el mismo rango/direccionamiento) que el hipervisor (host). El propósito es que a nivel de red, estén de igual a igual tanto con el hipervisor como con otros hosts físicos (o virtuales) de la propia red. Ésto es interesante para realizar pruebas (p.ej. montar un cluster de algo) sin tener que disponer de varias máquinas físicas y, por tanto, cuando se tiene/quiere destinar poco presupuesto (y evitar cacharrear con hardware).

Ya en el pasado he abordado parte del tema y voy a tratar de no repetirme demasiado, además de ser distinto en el sentido que:

  • Es más completo/actualizado.
  • Vamos a trabajar únicamente por consola/CLI.
  • Y adicionalmente se van a mencionar una serie de comandos de referencia/utilidad de KVM.

Vamos a usar (cómo no) nuestra amada Debian GNU/Linux en su versión 11 (bullseye), a usar sólo herramientas CLI y a tratar de instalar lo básico e imprescindible del lado del host que hará de hipervisor porque vamos a suponer que tenemos un presupuesto limitado. En mi caso es más que una suposición porque estoy hablando de un miniPC con un Intel Atom x5-Z8350, 4GB de RAM y 64GB de almacenamiento eMMC, así que aplicando ésta receta a éste host es garantia de funcionamiento con un "low powered PC". ¡Vamos allá!

Instalación de un setup KVM básico

Queremos los paquetes estrictamente necesarios para evitar bloatware en la medida de lo posible:

$ apt-get install --no-install-recommends qemu-system libvirt-clients libvirt-daemon-system virtinst bridge-utils

Crear una interficie de tipo bridge público

La idea es que el bridge sea quien pase a tener la dirección ip que hasta ahora tenia la interfície de red física:

$ vi /etc/network/interfaces

# Make sure we don't get addresses on our raw device (change 'static' to 'manual')
iface enp1s0 inet manual

# Comment out the rest of the info of the primary network interface
#auto enp1s0
#iface enp1s0 inet static
#       address 192.168.2.8
#       netmask 255.255.255.0
#       gateway 192.168.2.1

# Bridge will become the primary network interface owning the ip
auto br0
iface br0 inet static
        address 192.168.2.8
        netmask 255.255.255.0
        network 192.168.2.0
        broadcast 192.168.2.255
        gateway 192.168.2.1
        bridge_ports enp1s0
        bridge_stp off
        bridge_fd 0
        bridge_maxwait 0
        dns-nameservers 8.8.8.8
:wq

$ reboot

Después del reinicio, deberiamos tener red en el host hipervisor y tanto la interfície física como el bridge levantados, siendo éste último el que tenga asociada la ip:

root@bt3:~# ifconfig 
br0: flags=4163  mtu 1500
        inet 192.168.2.8  netmask 255.255.255.0  broadcast 192.168.2.255
        inet6 fe80::6436:60ff:fec8:8215  prefixlen 64  scopeid 0x20
        ether 66:36:60:c8:82:15  txqueuelen 1000  (Ethernet)
        RX packets 3402  bytes 319121 (311.6 KiB)
        RX errors 0  dropped 1890  overruns 0  frame 0
        TX packets 363  bytes 31256 (30.5 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

enp1s0: flags=4163  mtu 1500
        ether 84:39:be:74:66:67  txqueuelen 1000  (Ethernet)
        RX packets 4643  bytes 917990 (896.4 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 361  bytes 31148 (30.4 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

Deshabilitamos el firewall en la interficie bridge

Así evitamos interferencias, al menos en las pruebas:

# Disable netfilter for the bridge to allow all traffic to be forwarded to it,
# and therefore to the virtual machines they are connected to
$ vi /etc/sysctl.d/99-netfilter-bridge.conf
net.bridge.bridge-nf-call-ip6tables = 0
net.bridge.bridge-nf-call-iptables = 0
net.bridge.bridge-nf-call-arptables = 0
:wq
$ modprobe br_netfilter
$ echo br_netfilter > /etc/modules-load.d/br_netfilter.conf
$ sysctl -p /etc/sysctl.d/99-netfilter-bridge.conf

Mapeamos ese bridge en KVM

Éste punto es imprescindible y a veces olvidado:

# Create a new virtual network
$ vi bridged-network.xml
<network>
    <name>bridged-network</name>
    <forward mode="bridge" />
    <bridge name="br0" />
</network>
:wq
$ virsh net-define bridged-network.xml
$ virsh net-start bridged-network
$ virsh net-autostart bridged-network
$ virsh net-list --all

Instalamos la/s VM

En éste punto instalamos el paquete libosinfo-bin, que nos permitirá conocer las "variantes" para indicar en el parámetro os-variant a Qemu/KVM. Uno de los puntos importantes es el de la red. Con el parámetro --network le indicamos la recién creada/mapeada a KVM:

$ apt install libosinfo-bin
$ osinfo-query os # Run it (and grep it!) to know the correct os-variant
$ virt-install --name vn_name --ram 1024 --vcpus 1 \
--disk path=/var/lib/libvirt/images/vm_name-vm.qcow2,size=10 \
--os-type linux --os-variant debian10 --network network=bridged-network \
--graphics none --console pty,target_type=serial \
--location 'http://ftp.debian.org/debian/dists/bullseye/main/installer-amd64/' \
--extra-args 'console=ttyS0,115200n8 serial'

En éste punto ya estamos ante una instalación normal y corriente de una Debian. Asignamos a la VM una dirección ip libre del mismo rango de red que el host hipervisor (p.ej. la 192.168.2.9) y comprobamos la conectividad. Haciendo p.ej. un ping al hipervisor o al gateway, deberiamos tener visibilidad.

Si queremos crear una nueva VM a imagen y semejanza de la que acabamos de crear, podemos clonarla (ver abajo VM clone) para ahorrar tiempo y esfuerzos. Os dejo a continuación el cheatsheet de lo que me parece más útil e interesante de conocer de Qemu/KVM, no sin antes comentaros que los comandos siempre hablan de domain para referirse a VM/máquina virtual ya que el término viene de la jerga Xen:

# Basic ops
$ virsh list
$ virsh list --all # Also show stopped VMs
$ virsh start|reboot|shutdown|destroy # Destroy forces stop
$ virsh undefine vm_name --remove-all-storage # Delete VM definition + data
or
$ virsh undefine vm_name (delete VM definition) # Delete VM definition
$ rm -f /var/lib/libvirt/images/vm_name-vm.qcow2 # Delete disc manually
or
$ virsh pool-list (list storage pools)
$ virsh pool-refresh pool_name
$ virsh vol-delete --pool images vm_name-vm.qcow2 # Delete disk from pool

# Attach to VM virsh console
$ virsh console vm_name
# Detach from VM virsh console
Ctrl+]+5

# View VM info
$ virsh dominfo vm_name
# Set autostart on a VM
$ virsh autostart vm_name

# Create additional volume/disk
$ virsh vol-create-as images test_vol.qcow2 2G
# List volumes
$ virsh vol-list --pool images
# Attach volume/disk to VM
$ virsh attach-disk --domain vm_name --source /var/lib/libvirt/images/test_vol.qcow2 --persistent --target vdb
# Detach volume/disk from VM
$ virsh detach-disk --domain vm_name --persistent --live --target vdb
# Delete a volume/disk
$ virsh vol-delete test_vol.qcow2 --pool images
# Resize a volume/disk
$ qemu-img resize /var/lib/libvirt/images/test.qcow2 +1G

# Edit a guest virtual machine's XML
$ virsh edit vm_name

# VM clone
$ virsh shutdown vm_name
$ virt-clone --original vm_name --name vm_name2 --file /var/lib/libvirt/images/vm_name2-vm.qcow2
(We will need to start it up later and change hostname and network info)

# Snapshot creation
$ virsh shutdowm vm_name
$ virsh snapshot-create-as --domain vm_name --name mysnapshot --description "preupdate snapshot"
# List snapshots
$ virsh snapshot-list vm_name
# Snapshot reversion
$ virsh snapshot-revert --domain vm_name --snapshotname mysnapshot --running
# Delete snapshots
$ virsh snapshot-delete --domain vm_name --snapshotname mysnapshot

# Backup creation
$ virsh shutdown vm_name
$ virsh dumpxml vm_name > /opt/kvm_backup/vm_name_config.xml (configuration)
$ virsh domblklist vm_name
$ cp /var/lib/libvirt/images/vm_name.qcow2 /opt/kvm_backup/ (data)
# Backup restore
$ cp /opt/kvm_backup/vm_name.qcow2 /var/lib/libvirt/images/
$ virsh define --file /opt/kvm_backup/vm_name.xml

Comentarios (0)


Volver al indice

login, admin, form, register