9.2.2.1.2.2.1. Creación

Nos centraremos en crear y gestionar máquinas con las herramientas CLI, porque la interfaz gráfica, una vez que se entiende el funcionamiento general de la aplicación no tiene excesivos secretos e, incluso, guarda ciertas semejanzas con la de Virtualbox.

Hay dos órdenes fundamentales:

  • virt-install, que nos permite definir la máquina virtual y el anfitrión que se alojará en ella.

  • virsh, que nos permitirá consultarla, gestionarla y modificarla.

Nota

Este epigrafe se centra exclusivamente en cómo crear máquinas virtuales y no en cómo comprobar que se han creado y cómo se arrancan. Probar y consultar las máquinas se hará bajo el próximo epígrafe.

Para crear (e instalar) una máquina podemos empezar haciendo lo siguiente:

$ virt-install --osinfo debian11 -n bullseye --metadata title="Debian Bullseye" --memory 1024 --vcpus 2 \
   --network user --disk disco.qcw,size=4,format=qcow2 --cdrom debian-11.6.0-amd64.iso

La orden creará una máquina de nombre «Bullseye» con sistema Debian 11 (--osinfo)[1], una memoria de 1GiB, 2 procesadores y red de usuario. El disco será disco.qcw y es nuevo porque junto a la ruta especificamos su tamaño y su formato. La orden nos obliga a indicar el método de instalación, así que añadimos un disco de instalación con --cdrom. Crear una máquina se traduce en generar un XML con las características de la máquina virtual (ya veremos dónde) que con sólo referir su nombre permitirá arrancarla en el futuro conservando tales caracterísicas (ya veremos cómo). Ahora, sin embargo, tendrá por efecto abrir una ventana gráfica dentro de la que veremos el huésped y podremos realizar la instalación.

Podemos variar la creación introduciendo variantes a esta orden que afectan a distintos aspectos:

9.2.2.1.2.2.1.1. Punto de partida

Un primer aspecto es el punto de partida, esto es, de qué partimos cuando creamos la máquina virtual. El ejemplo anterior presenta un punto en el que no disponemos de nada, de ahí que la orden cree el disco y haya que facilitarle los parámetros mínimos (tamaño y formato). Hay otras variantes:

  • Que el disco, aunque creado (p.e. con qemu-img create), esté vacío. En ese caso, la orden será exactamente la misma, pero sin incluir tamaño y formato.

  • Que el disco ya contenga un sistema, por lo que no necesita proceso de instalación. En tal caso, sobrará la opción --cdrom a cambio de la cual habrá que incluir un par más:

    $ virt-install --osinfo debian11 -n bullseye --metadata title="Debian Bullseye" --memory 1024 --vcpus 2 \
       --network user --disk disco.qcw --import --noreboot --autoconsole none
    

    --import advierte de que importamos un disco ya preparado, --noreboot impide que arranque la máquina (por lo que sólo se creará el XML que la define), y --autoconsole none no abrirá el visor virt-viewer.

  • Que dispongamos del disco y el XML de configuración (p.e. porque los trajimos de otro anfitrión). En este caso, primero debimos haber obtenido el XML, lo cual se consigue con:

    $ virsh dumpxml bullseye > bullseye.xml
    

    En el nuevo anfitrión deberemos copiar disco.qcw y bullseye.xml, quizás editar este último para adecuar la ruta donde se encuentre el disco e importar el XML:

    $ vim /tmp/bullseye.xml  # Ajustamos la ruta a donde hemos copiado disco.qcw
    $ virsh define bullseye.xml
    

    El resultado será una máquina con exactamente la misma definición en el nuevo anfitrión.

  • Que queramos directamente clonar una máquina para crear otra:

    $ virt-clone -o bullseye --auto-clone
    

    que creará una nueva máquina llamada «bullseye-clone» con un disco que compartirá ruta con el original pero añadirá -clone a su nombre. Si se quiere afinar un poco más:

    $ virt-clone -o bullseye -n nuevabulls.eye -f nuevodisco.qcw
    

    orden a la que se le pueden seguir añadiendo más características para modificar las originales (véase virt-clone).

9.2.2.1.2.2.1.2. Hipervisor

Ya se ha apuntado que libvirt es capaz de servir para la gestión de varios hipervisores, aunque nosotros nos centraremos en el caso de que sea QEmu. Para expresar qué hipervisor queremos utilizar, las órdenes (virt-install, virsh) tienen una opción --connect a la que hay que indicar el hipervisor en forma de URI:

qemu:///session
qemu:///system
vbox:///session
lxc:///
etc…

La diferencia entre las dos variantes de QEmu presentes es que la primera no gozará de permisos extraordinarios al del propio usuario, con lo que puede haber acciones que no se puedan hacer. Por ejemplo, no se podrán crear interfaces de red adicionales[2]. Además, la primera almacenará la configuración de las máquinas en el directorio de usuario ~/.config/libvirt/qemu mientras que la segunda en el global /etc/libvirt/qemu.

Si no se especifica ninguno expresamente, se tomará qemu:///session (al menos en mi sistema Debian):

$ virsh uri
qemu:///session

pero este valor prefijado se puede manipular por dos vías: o definiendo la variable de ambiente LIBVIRT_DEFAULT_URI. o añadiendo la definición al archivo ~/.config/libvirt/libvirt.cont:

$ echo "uri_default = qemu:///system" >> ${XDG_CONFIG_HOME:-~/.config}/libvirt/libvirt.conf

En cualquier caso, la orden de creación podríamos haberla escrito así:

$ virt-install --conect 'qemu:///system' --osinfo debian11 -n bullseye --metadata title="Debian Bullseye" \
   --memory 1024 --vcpus 2 --network user --disk disco.qcw,size=4,format=qcow2 --cdrom debian-11.6.0-amd64.iso

Téngase presente que esto también es aplicable a virsh y virt-clone, de modo que la clonación deberíamos haberla hecho así:

$ virt-clone --connect 'qemu:///system' -o bullseye -n nuevabulls.eye -f nuevodisco.qcw

porque de lo contrario no se habría podido encontrar la máquina «bullseye».

9.2.2.1.2.2.1.3. Firmware

Como no se ha indicado nada al respecto la máquina usará un firmware BIOS. Para EFI bastará con añadir --boot uefi:

$ virt-install --osinfo debian11 -n bullseye --metadata title="Debian Bullseye" --memory 1024 --vcpus 2 \
   --network user --disk disco.qcw,size=4,format=qcow2 --cdrom debian-11.6.0-amd64.iso --boot uefi

9.2.2.1.2.2.1.4. Acceso al huésped

A los huésped anteriores, tal como los hemos definido, se tendrá acceso a través de una ventana gráfica como la descrita cuando tratamos QEmu. Es posible, no obstante, definir accesos distintos utilizando la opción --graphics:

VNC

Para definir un acceso mediante una conexión VNC podemos añadir:

$ virt-install --osinfo debian11 -n bullseye --metadata title="Debian Bullseye" --memory 1024 --vcpus 2 \
   --network user --disk disco.qcw,size=4,format=qcow2 --cdrom debian-11.6.0-amd64.iso --graphics vnc
Spice

En este caso el añadido debe ser el siguiente:

$ virt-install --osinfo debian11 -n bullseye --metadata title="Debian Bullseye" --memory 1024 --vcpus 2 \
   --network user --disk disco.qcw,size=4,format=qcow2 --cdrom debian-11.6.0-amd64.iso \
   --graphics spice --video qxl --channel spicevmc
Texto

Para un huésped sin entorno gráfico es interesante, simplemente, no definir salida gráfica y ofrecer una consola a través del puerto serie. En este caso, el huésped debemos prepararlo tal como se explica para QEmu y la máquina deberá definirse así:

$ virt-install --osinfo debian11 -n bullseye --metadata title="Debian Bullseye" --memory 1024 --vcpus 2 \
   --network user --disk disco.qcw,size=4,format=qcow2 --cdrom debian-11.6.0-amd64.iso \
   --graphics none --console pty,target.type=virtio --serial pty

9.2.2.1.2.2.1.5. Red

libvirt ofrece cuatro alternativas para la red definida a través de --network (forma larga) o -w (forma corta):

none (-w none)

esto es, no definir ninguna interfaz, porque de forma predeterminada se crea una.

Red de usuario (-w user)

Equivalente a la red de usuario de QEmu. Es la que hemos utilizado en los ejemplo con virt-install, aunque su expresión sobraba, porque es la que se usa cuando el hipervisor es qemu:///session en caso de que no se haya manipulado la configuración de la red.

Nota

No parece haber una forma nativa de redirigir puertos al huésped con esta modalidad (p.e. para el acceso al servidor SSH). La única posibilidad consiste en no definir red (none) y editar el XML para añadir expresamente los argumentos de QEmu que definen la red de usuario (véase esta respuesta en stackexchange.com).

Puente (-w bridge=nombre_interfaz_puente)

Consiste en incorporar la interfaz de red de la máquina virtual a una interfaz puente preexistente en el anfitrión y es equivalente al puente que se trató con QEmu. La interfaz puente no se crea al crear la máquina o arrancarla, sino que debe crearse antes manualmente o bien definirse como una red con nombre al configurar la red[3]. Obviamente, esta segunda forma es más limpia y la preferible y permite expresar la red mediante el nombre que se le dé en vez de mediante el nombre de la interfaz puente: -w network=nombre:

$ virt-install --osinfo debian11 -n bullseye --metadata title="Debian Bullseye" --memory 1024 --vcpus 2 \
   --network network=interna1 --disk disco.qcw,size=4,format=qcow2 --cdrom debian-11.6.0-amd64.iso

supuesto que se hubiera creado previamente una red de nombre «interna1». Para el hipervisor qemu:///system existe ya una red predefinida (»default») que usa una interfaz puente llamada virbr0 y es a esta red a la que se pertenecerá la interfaz del anfitrión si no expresa red al crear la máquina con virt-install.

Directa (-w direct,source=interfaz_fisca)

Equivalente al puente con interfaz macvtap de QEmu, por lo que es aplicable todo lo que se explicó entonces: si el anfitrión usa la propia interfaz física, será incapaz de comunicar con el huésped. No necesita preparación previa, a diferencia del anterior, porque la interfaz macvtap se creará (o destruirá) ex profeso al arrancar (o parar) la máquina virtual:

$ virt-install --osinfo debian11 -n bullseye --metadata title="Debian Bullseye" --memory 1024 --vcpus 2 \
   --network direct,source=eth0 --disk disco.qcw,size=4,format=qcow2 --cdrom debian-11.6.0-amd64.iso

Deberá usarse qemu:///system, porque con qemu:///session no se tendrán permisos suficientes.

Notas al pie