Product SiteDocumentation Site

12.2. Virtualización

La virtualización es uno de los avances más grandes de la informática en los últimos años. El término abarca varias abstracciones y técnicas de simulación de equipos virtuales con un grado variable de independencia de hardware real. Un servidor físico puede almacenar varios sistemas que funcionan de forma simultánea y aislada. Sus aplicaciones son muchas y generalmente surgen de este aislamiento: entornos de prueba con diferentes configuraciones o separar los servicios provistos entre diferentes máquinas virtuales por seguridad.
Hay múltiples soluciones de virtualización, cada una con sus ventajas y desventajas. Este libro se concentrará en Xen, LXC y KVM; pero otras implementaciones notables incluyen las siguientes:

12.2.1. Xen

Xen es una solución de «paravirtualización». Introduce una fina capa de abstracción, llamada «hypervisor», entre el hardware y los sistemas superiores; ésta actúa como árbitro controlando el acceso al hardware desde las máquinas virtuales. Sin embargo, sólo gestiona unas pocas instrucciones, las demás se ejecutan directamente en el hardware en nombre de los sistemas. La principal ventaja es que no se degrada el rendimiento y los sistemas ejecutan a velocidades cercanas a la nativa; la desventaja es que el núcleo de los sistemas operativos que uno desee utilizar en un hypervisor Xen necesita ser adaptado para ejecutar sobre Xen.
Pasemos un poco de tiempo en los términos. El hypervisor es la capa más baja que ejecuta directamente en el hardware, inclusive debajo del núcleo. Este hypervisor puede dividir el resto del software entre varios dominios («domains»), pueden interpretarse como máquinas virtuales. Se conoce a uno de estos dominios (el primero en iniciar) como dom0 y tiene un rol especial ya que sólo este dominio puede controlar al hypervisor y la ejecución de otros dominios. Se conocen a los otros dominios como domU. En otras palabras, desde el punto de vista del usuario, el dom0 es el «anfitrión» de los demás sistemas de virtualización, mientras que los domU son sus «invitados».
Utilizar Xen en Debian requiere tres componentes:
  • El mismo hipervisor. Según el hardware disponible, el paquete apropiado que proporciona xen-hypervisor será xen-hypervisor-4.14-amd64, xen-hypervisor-4.14-armhf, o xen-hypervisor-4.14-arm64.
  • Un núcleo que ejecuta sobre dicho hipervisor. Cualquier núcleo posterior a 3.0 funcionará, incluyendo la versión 5.10 presente en Bullseye.
  • La arquitectura i386 también necesita una biblioteca estándar con los parches apropiados para aprovechar Xen; ésta se encuentra en el paquete libc6-xen.
El hipervisor también incluirá xen-utils-4.11, que contiene las herramientas para controlar el hipervisor desde el dom0. A su vez, éste incluirá la biblioteca estándar apropiada. Durante la instalación de todo esto, los scripts de configuración también crearán un nuevo elemento en el menú del gestor de arranque GRUB, para iniciar el núcleo elegido en un dom0 Xen. Nota, esta entrada sin embargo, generalmente no será la primera en la lista, pero estará seleccionada de forma predeterminada.
Una vez que instaló estos prerequisitos, el siguiente paso es probar el comportamiento del dom0 en sí mismo; esto incluye reiniciar para utilizar el hypervisor y núcleo Xen. El sistema debería iniciar como siempre, con unos pocos mensajes adicionales en la consola durante los primeros pasos de inicialización.
Ahora es el momento de instalar sistemas útiles en los sistemas domU, utilizando las herramientas en xen-tools. Este paquete provee el programa xen-create-image, que automatiza en gran parte esta tarea. El único parámetro obligatorio es --hostname, que le da un nombre al domU; otras opciones son importantes, pero puede guardarlas en el archivo de configuración /etc/xen-tools/xen-tools.conf y si no las especifica no generará ningún error. Por lo tanto es importante revisar el contenido de este archivo antes de crear imágenes o utilizar los parámetros adicionales en la invocación de xen-create-image. Los parámetros importantes a saber incluyen los siguientes:
  • --memory para especificar la cantidad de RAM dedicada a este nuevo sistema creado;
  • --size y --swap para definir el tamaño de los «discos virtuales» disponibles al domU;
  • --debootstrap-cmd para especificar que orden de debootstrap utilizar. La predeterminada es debootstrap si debootstrap y cdebootstrap están instalados. En tal caso, generalmente también utilizará la opción --dist (con el nombre de una distribución como bullseye).
  • --dhcp indica que el domU debe obtener su configuración de red a través de DHCP, mientras que --ip permite definir una dirección IP estática.
  • Por último, debe elegir un método de almacenamiento para las imágenes a crear (que el domU verá como discos duros). El método más simple, que corresponde a la opción --dir, es crear un archivo en el dom0 para cada dispositivo que se le provee al domU. La alternativa en sistemas que utilizan LVM es la opción --lvm seguida del nombre de un grupo de volúmenes; xen-create-image luego creará un nuevo volumen lógico dentro de dicho grupo y éste estará disponible en el domU como un disco duro.
Una vez que realizó esta elección, puede crear la imagen para nuestro futuro domU Xen:
# 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
Ahora tenemos una máquina virtual, pero no está ejecutando (por lo tanto sólo utiliza espacio en el disco duro del dom0). Por supuesto, podemos crear más imágenes, posiblemente con diferentes parámetros.
Antes de encender estas máquinas virtuales, necesitamos definir cómo accederemos a ellas. Por supuesto, podemos considerarlas máquinas aisladas a las que sólo podemos acceder a través de su consola de sistema, pero rara vez esto coincide con el patrón de uso. La mayoría de las veces, consideraremos un domU como un servidor remoto al que sólo podemos acceder a través de la red. Sin embargo, sería un gran inconveniente agregar una tarjeta de red para cada domU; es por esto que Xen permite crear interfaces virtuales que cada dominio puede ver y utilizar de la forma estándar. Sepa que estas tarjetas, aunque sean virtuales, sólo serán útiles cuando estén conectadas a una red, inclusive una virtual. Xen tiene varios modelos de red para esto:
  • El modelo más simple es el modelo puente («bridge»); todas las tarjetas de red eth0 (tanto en los sistemas domU como en el dom0) se comportarán como si estuvieran conectadas directamente a un switch Ethernet.
  • Luego está el modelo enrutamiento («routing») en el que el dom0 se comporta como el router entre los sistemas domU y la red (física) externa.
  • Finalmente, en el modelo NAT, nuevamente el dom0 se encuentra entre los sistemas domU y el resto de la red, pero no se puede acceder a los sistemas domU directamente desde afuera y el tráfico atraviesa una traducción de direcciones de red en el dom0.
Estos tres modos de red involucran una cantidad de interfaces con nombres inusuales, como vif*, veth*, peth* y xenbr0. El hypervisor Xen los acomoda en la distribución definida bajo el control de las herramientas en espacio de usuario. Debido a que los modelos NAT y de enrutamiento sólo se adaptan a casos particulares sólo discutiremos el modelo de puente.
La configuración estándar de los paquetes Xen no modifica la configuración de red del sistema. Sin embargo, se configura el demonio xend para integrar las interfaces de red virtuales en un puente de red preexistente (xenbr0 tiene precedencia si existen varios de ellos). Por lo tanto, debemos configurar un puente en /etc/network/interfaces (lo que requiere que instalemos el paquete bridge-utils, razón por la que lo recomienda el paquete xen-utils) para reemplazar la entrada existente eth0, (hay que tener cuidado y utilizar el nombre correcto del dispositivo de red):
auto xenbr0
iface xenbr0 inet dhcp
    bridge_ports eth0
    bridge_maxwait 0
Luego de reiniciar para asegurarse que se crea el puente automáticamente, podemos iniciar el domU con las herramientas de control de Xen, en particular el programa xl. Este programa permite varias manipulaciones de los dominios, entre ellas: enumerarlos, iniciarlos y detenerlos. Puede que tenga que aumentar la memoria predeterminada editando la variable memory en el archivo de configuración (en este caso, /etc/xen/testxen.cfg). Aquí le hemos asignado 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
Sepa que el domU testxen utiliza memoria real - no simulada - de la RAM que, de lo contrario, estaría disponible en el dom0. Debe tener cuidado al construir un servidor para instancias Xen, asegurándose de incluir suficente RAM física.
¡Voilà! Nuestra máquina virtual está iniciando. Podemos acceder a ella de dos formas. La forma usual es conectarnos «remotamente» a través de la red, como lo haríamos con una máquina real; esto usualmente requerirá configurar un servidor DHCP o alguna configuración de DNS. La otra forma, que puede ser la única forma si la configuración de red era incorrecta, es utilizar la consola hvc0 ejecutando xl console:
# xl console testxen
[...]

Debian GNU/Linux 11 testxen hvc0

testxen login: 
Uno puede abrir una sesión, tal como si estuviera sentado frente al teclado de la máquina virtual. Puede desconectarse de esta consola con la combinación de teclas Control+].
Una vez que el domU está ejecutando, puede utilizarlo como cualquier otro servidor (al fin y al cabo es un sistema GNU/Linux). Sin embargo, su existencia como máquina virtual permite cierta funcionalidad adicional. Por ejemplo, puede pausar y resumir temporalmente un domU, ejecutando xl pause y xl unpause. Sepa que aunque un domU pausado no utiliza el procesador, la memoria reservada a él sigue en uso. Puede ser interesante considerar las órdenes xl save y xl restore: guardar un domU libera los recursos utilizados por este domU, incluyendo la RAM. Cuando restaure (o resuma) un domU, éste no notará nada a excepción del paso del tiempo. Si un domU está ejecutando cuando se apague el dom0, los scripts empaquetados automáticamente guardarán el domU y lo restaurarán cuando vuelva a iniciar. Esto, por supuesto, tiene los mismos inconvenientes estándar que cuando hiberna un equipo portátil, por ejemplo; en particular, si se suspende por demasiado tiempo al domU, pueden expirar las conexiones de red. Sepa también que, hasta el momento, Xen es incompatible con gran parte de la gestión de energía ACPI, lo que evita que pueda suspender el sistema anfitrión (dom0).
Puede apagar o reiniciar un domU tanto desde dentro del domU (con el programa shutdown) como también desde el dom0, ejecutando xm shutdown o xl reboot.
La mayoría de las subórdenes de xl esperan uno o más parámetros, generalmente el nombre de un domU. Se describen en detalle estos parámetros en la página de manual xl(1).

12.2.2. LXC

Aún cuando es utilizado para crear «máquinas virtuales», LXC no es, estrictamente hablando, un sistema de virtualización sino un sistema para aislar grupos de procesos entre sí aún cuando estos ejecutan en el mismo equipo. Aprovecha un conjunto de evoluciones recientes del núcleo Linux, conocidos colectivamente como grupos de control («control groups»), mediante los que diferentes conjuntos de procesos llamados «grupos» tienen diferentes visiones de ciertos aspectos de todo el sistema. Entre estos aspectos, los más notables son los identificadores de procesos, la configuración de red y los puntos de montaje. Un grupo de procesos aislados no podrá acceder a otros procesos en el sistema y puede restringir su acceso al sistema de archivos a un subconjunto específico. También puede tener su propia interfaz de red y tabla de enrutamiento y puede configurarlo para que sólo pueda ver un subconjunto de los dispositivos disponibles que están presentes en el sistema.
Puede combinar estas funcionalidades para aislar una familia de procesos completa que inicia desde el proceso init, y el conjunto resultante es muy similar a una máquina virtual. El nombre oficial de esta configuración es «contenedor» (de allí LXC: contenedores Linux, «LinuX Containers»), pero una diferencia importante con máquinas virtuales «reales» como aquellas provistas por Xen o KVM es que no hay un segundo núcleo; el contenedor utiliza el mismo núcleo que el sistema anfitrión. Esto tiene tanto ventajas como desventajas: las ventajas incluyen un rendimiento excelente debido a una falta completa de sobrecarga y el hecho de que el núcleo tiene una visión global de todos los procesos que ejecutan en el sistema por lo que la gestión de procesos puede ser más eficiente que si existieran dos núcleos independientes administrando conjuntos de tareas. La mayor de las desventajas es la imposibilidad de ejecutar un núcleo diferente en un contenedor (sea una versión diferente de Linux o directamente un sistema operativo distinto).
Debido a que estamos trabajando con aislamiento en lugar de virtualización, configurar contenedores LXC es más complejo que simplemente ejecutar debian-installer en una máquina virtual. Describiremos unos pocos prerequisitos y luego continuaremos con la configuración de red; finalmente podremos crear realmente el sistema a ejecutar en el contenedor.

12.2.2.1. Pasos preliminares

El paquete lxc contiene las herramientas necesarias para utilizar LXC, por lo tanto debe instalarlo.
LXC también necesita del sistema de configuración de grupos de control («control groups»), que es un sistema de archivos virtual montado en /sys/fs/cgroup. Desde que Debian 8 se ha cambiado a systemd, el cual confía tambien en los grupos de control, eso ya se ha hecho automáticamente en el momento de arranque sin necesidad de configuraciones adicionales.

12.2.2.2. Configuración de red

El objetivo de instalar LXC es configurar máquinas virtuales; si bien podríamos mantenerlas aisladas de la red, y sólo comunicarnos con ellas a través del sistema de archivos, la mayoría de los casos de uso involucran proveer a los contenedores al menos un acceso mínimo a la red. En el caso típico, cada contenedor obtendrá una interfaz de red virtual, conectada a la red real a través de un puente. Esta interfaz virtual puede conectarse directamente a la interfaz de red física del anfitrión (en cuyo caso el contenedor se encuentra en la red directamente) o a otra interfaz virtual definida en el anfitrión (y en la que éste puede filtrar o enrutar tráfico). En ambos casos, necesitará el paquete bridge-utils.
El caso más simple es sólo cuestión de editar /etc/network/interfaces, moviendo la configuración de la interfaz física (por ejemplo, eth0 o enp1s0) a una interfaz de puente (generalmente br0) y configurar un enlace entre ellos. Por ejemplo, si el archivo de configuración de la interfaz de red inicialmente contiene elementos como los siguientes:
auto eth0
iface eth0 inet dhcp
Debería desactivarlas y reemplazarlas con lo siguiente:
auto br0
iface br0 inet dhcp
    bridge-ports eth0
El efecto de esta configuración será similar a lo que podría obtener si los controladores fueran máquinas conectadas a la misma red física que el anfitrión. La configuración del «puente» gestiona el tránsito de tramas Ethernet entre todas las interfaces en él, lo que incluye la interfaz física eth0 así como también las interfaces definidas para los contenedores.
En casos en los que no pueda utilizar esta configuración (por ejemplo, si no puede asignarle una IP pública a los contenedores), crearemos una sola interfaz virtual tap y la conectaremos al puente. La topología de red equivalente sería aquella de un equipo con una segunda tarjeta de red conectada a un switch independiente al que también están conectados los contenedores. El anfitrión deberá actuar como puerta de enlace para los contenedores si éstos deben comunicarse con el mundo exterior.
Además de bridge-utils, esta configuración «enriquecida» necesita el paquete vde2; el archivo /etc/network/interfaces se convierte entonces en:
# 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
Luego puede configurar la red en los contenedores de forma estática o dinámica con un servidor DHCP ejecutando en el anfitrión. Deberá configurar este servidor DHCP para que responda a pedidos en la interfaz br0.

12.2.2.3. Configuración del sistema

Configuremos ahora el sistema que utilizará el contenedor. Debido a que esta «máquina virtual» no se ejecutará directamente sobre el hardware, son necesarios algunos ajustes comparados con un sistema de archivos estándar, especialmente en aquello que involucra al núcleo, los dispositivos y las consolas. Afortunadamente, el paquete lxc incluye scripts que automatizan la mayoría de esta configuración. Por ejemplo, las siguientes órdenes (que requieren los paquetes debootstrap y rsync) instalarán un contenedor Debian:
# 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...
[...]
# 
Sepa que inicialmente se crea el sistema de archivos en /var/cache/lxc y luego es mudado a su directorio de destino. Esto permite crear contenedores idénticos mucho más rápido ya que luego sólo necesita copiarlo.
Tenga en cuenat que el script de creación de plantillas de Debian acepta la opción --arch para especificar la arquitectura del sistema a instalar y la opción --release si desea instalar algo diferente a la versión estable actual de Debian. También puede definir la variable de entorno MIRROR apuntando a una réplica Debian local.
El paquete lxc crea además una interfaz puente lxcbr0, que es utilizado por defecto por todos los contenedores recién creados a través de /etc/lxc/default.conf y el servicio lxc-net:
lxc.net.0.type = veth
lxc.net.0.link = lxcbr0
lxc.net.0.flags = up
Estas líneas significan, respectivamente, que se creará una interfaz virtual en cada contenedor nuevo; que se iniciará automáticamente cuando se inicie el contenedor; y se conectará automáticamente al puente lxcbr0 en el anfitrión. En caso que esta última línea no exista o esté desactivada, se generará una dirección MAC aleatoria. Encontrarás estos ajustes en la configuración del contenedor creado (/var/lib/lxc/testlxc/config), donde también se especifica la dirección MAC del dispositivo en lxc.net.0.hwaddr. Si no se encuentra esta última entrada o está desactivada, se generará una dirección MAC aleatoria.
Otro elemento útil en dicho archivo es la configuración del nombre del equipo:
lxc.uts.name = testlxc
El sistema de archivos recién creado ahora contiene un sistema Debian mínimo y una interfaz de red.

12.2.2.4. Inicio del contenedor

Ahora que la imagen de nuestra máquina virtual está lista, iniciemos el contenedor con lxc-start --daemon --name=testlxc.
En publicaciones de LXC posteriores a la 2.0.8, las contraseñas del superusuario por defecto no están asignadas. Si queremos, podemos asignar una ejecutando lxc-attach -n testlxc contraseña.. Ahora podemos acceder con:
# 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:~# 
Ahora estamos dentro del contenedor; nuestro acceso a los procesos está restringido a aquellos iniciados dentro del mismo contenedor y nuestro acceso al sistema de archivos está limitado de forma similar al subconjunto dedicado del sistema de archivos completo (/var/lib/lxc/testlxc/rootfs). Podemos salir a la consola con Control+a q.
Tenga en cuenta que ejecutamos el contenedor como un proceso en segundo plano gracias a lxc-start que usa la opción --daemon por defecto. Podemos interrumpir el contenedor ejecutando lxc-stop --name=testlxc.
El paquete lxc contiene un script de inicialización que puede automatizar el inicio de uno o más contenedores cuando el sistema principal arranca (confía en el comando lxc-autostart el cual inicia los contenedores que tienen la opción lxc.start.auto configurada a 1). Se puede obtener un control más detallado del orden de inicio con lxc.start.order y lxc.group: por defecto, el script de inicialización inicia los contenedores que son parte del grupo onboot y luego los contenedores que no forman parte de este grupo. En ambos casos el orden dentro de un grupo es definido por la opción lxc.start.order.

12.2.3. Virtualización con KVM

KVM, acrónimo de máquina virtual basada en el núcleo («Kernel-based Virtual Machine»), es primero que nada un módulo del núcleo que provee la mayor parte de la infraestructura que puede usar un virtualizador, pero no es un virtualizador en sí mismo. El control real de la virtualización es gestionado por una aplicación basada en QEMU. No se preocupe si esta sección menciona programas qemu-*, continúa hablando sobre KVM.
A diferencia de otros sistemas de virtualización, se integró KVM al núcleo Linux desde el comienzo. Sus desarrolladores eligieron aprovechar el conjunto de instrucciones de procesador dedicados a la virtualización (Intel-VT y AMD-V), lo que mantiene a KVM liviano, elegante y no muy hambriento de recursos. La contraparte, obviamente, es que KVM no funciona en ordenadores con procesadores distintos a estos. Para los ordenadores basados en i386 y amd64, puede verificar si tiene uno de estos procesadores si encuentra a «vmx» o «svm» entre las opciones de CPU («flags») enumeradas en /proc/cpuinfo.
Con Red Hat respaldando activamente su desarrollo, KVM parece haberse convertido en la referencia de virtualización en Linux.

12.2.3.1. Pasos 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.
Afortunadamente, Red Hat también provee otro conjunto de herramientas para solucionar este problema con el desarrollo de la biblioteca libvirt y las herramientas gestor de máquina virtual («virtual machine manager») asociadas. libvirt permite administrar máquinas virtuales de manera uniforme e independiente del sistema de virtualización subyacente (actualmente es compatible con QEMU, KVM, Xen, LXC, OpenVZ, VirtualBox, VMWare y UML). virtual-manager es una interfaz gráfica que utiliza libvirt para crear y administrar máquinas virtuales.
Primero instalaremos los paquetes necesarios con apt-get install libvirt-clients libvirt-daemon-system qemu-kvm virtinst virt-manager virt-viewer. libvirt-daemon-system provee el demonio libvirtd, que permite la gestión (posiblemente remota) de máquinas virtuales ejecutando en el equipo e inicia las VMs necesarias cuando éste inicia. libvirt-clients provee la herramienta de consola virsh que permite controlar los equipos administrados con libvirtd.
El paquete virtinst provee virt-install, que permite crear máquinas virtuales desde una consola. Finalmente, virt-viewer permite acceder a la consola gráfica de una VM.

12.2.3.2. Configuración de red

De la misma forma que en Xen y LXC, la configuración de red más frecuente involucra un puente que agrupa las interfaces de red de las máquinas virtuales (revise la Sección 12.2.2.2, “Configuración de red”).
Alternativamente, y de forma predeterminada en la configuración de KVM, se le asigna una dirección privada (en el rango 192.168.122.0/24) a la máquina virtual y se configura NAT para que la VM pueda acceder a la red externa.
El resto de esta sección asume que el anfitrión posee una interfaz física eth0 y un puente br0 que está conectado a la primera interfaz.

12.2.3.3. Instalación con virt-install

Crear una máquina virtual es muy similar a instalar un sistema normal, excepto que describirá las características de la máquina virtual en una línea que parecerá infinita.
En la práctica, esto significa que utilizaremos el instalador de Debian, iniciando la máquina virtual en un dispositivo DVD-ROM virtual que está asociado con la imagen del DVD Debian almacenado en el sistema anfitrión. La VM exportará su consola gráfica sobre el protocolo VNC (revise la Sección 9.2.2, “Utilización de escritorios gráficos remotos” para más detalles), lo que nos permitirá controlar el proceso de instalación.
Primero necesitaremos indicarle a libvirtd dónde almacenar las imágenes de disco, a menos que la ubicación predeterminada (/var/lib/libvirt/images) sea adecuada.
# mkdir /srv/kvm
# virsh pool-create-as srv-kvm dir --target /srv/kvm
Pool srv-kvm created

# 
Ahora iniciaremos el proceso de instalación para la máquina virtual y veremos en más detalle las opciones más importantes de virt-install. Este programa registra en libvirtd la máquina virtual y sus parámetros y luego la inicia para continuar el proceso de instalación.
# 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

La opción --connect especifica el «hypervisor» a utilizar. En forma de una URL que contiene un sistema de virtualización (xen://, qemu://, lxc://, openvz://, vbox://, etc.) y el equipo que alojará la VM (puede dejarlo vacío si es el equipo local). Además, y en el caso de QEMU/KVM, cada usuario puede administrar máquinas virtuales con permisos restringidos, y la ruta de la URL permite diferenciar equipos de «sistema» (/system) de los demás (/session).

2

Debido a que se administra KVM de la misma forma que QEMU, la opción --virt-type kvm permite especificar que se utilice KVM aunque la URL parezca una de QEMU.

3

La opción --name define un nombre (único) para la máquina virtual.

4

La opción --memory permite especificar la cantidad de RAM (en MB) que reservar para la máquina virtual.

5

La opción --disk especifica la ubicación del archivo de imagen que representará el disco duro de nuestra máquina virtual; se creará este archivo, a menos que ya exista, de un tamaño (en GB) especificado por el parámetro size. El parámetro format permite elegir entre las diferentes formas de almacenar el archivo de imagen. El formato predeterminado (cow2) permite iniciar con un archivo pequeño que sólo crece cuando la máquina virtual realmente utiliza el espacio.

6

Utilizamos la opción --cdrom para indicar dónde encontrar el disco óptico a utilizar para la instalación. La ruta puede ser una ruta local para un archivo ISO, una URL donde se puede obtener el archivo o el archivo de dispositivo de un CD-ROM físico (es decir: /dev/cdrom).

7

La opción --network especifica cómo se integra la tarjeta de red virtual a la configuración de red del anfitrión. El comportamiento predeterminado (que forzamos explícitamente en nuestro ejemplo) es integrarla en un puente de red preexistente. Si no existe dicho puente, la máquina virtual sólo llegará a la red física mediante NAT, por lo que se asignará una dirección en el rango de subredes privadas (192.168.122.0/24).
La configuración de red por defecto, que contiene la definición de una interfaz puente virbr0, se puede editar usando virsh net-edit default e iniciarse mediante virsh net-start default si no se ha hecho ya automáticamente durante el arranque del sistema.

8

--graphics vnc indica que debe estar disponible la consola gráfica a través de VNC. El comportamiento predeterminado para el servidor VNC es sólo escuchar en la interfaz local; si debe ejecutar el cliente VNC en otro equipo, necesitará establecer un túnel SSH (revise la Sección 9.2.1.4, “Creación de túneles cifrados con redirección de puertos”) para poder establecer una conexión. Alternativamente, puede utilizar --graphics vnc,listen=0.0.0.0 para poder acceder al servidor VNC desde todas las interfaces; sepa que si hace esto, realmente debe diseñar su firewall de forma acorde.

9

Las opciones --os-type y --os-variant permiten optimizar unos pocos parámetros de la máquina virtual basado en características conocidas del sistema operativo mencionado en ellas.
Se puede mostrar la lista completa de tipos de SO con el comando osinfo-query os del paquete libosinfo-bin.
En este punto, la máquina virtual está ejecutando y necesitaremos conectarnos a la consola gráfica para continuar con el proceso de instalación. Si realizó la operación anterior de un entorno de escritorio gráfico, esta conexión debería iniciar automáticamente. De lo contrario, o si estamos trabajando de forma remota, puede ejecutar virt-viewer desde cualquier entorno gráfico para abrir la consola gráfica (sepa que le pedirá la contraseña de root del equipo remoto dos veces ya que esta operación necesita dos conexiones SSH):
$ virt-viewer --connect qemu+ssh://root@servidor/system testkvm
root@servidor password: 
root@servidor's password: 
Conexión a la sesión del instalador mediante virt-viewer

Figura 12.1. Conexión a la sesión del instalador mediante virt-viewer

Cuando finaliza el proceso de instalación, se reinicia la máquina virtual y está lista para que la utilice.

12.2.3.4. Administración de máquinas con virsh

Ahora que finalizó la instalación, veamos como gestionar las máquinas virtuales disponibles. Lo primero a intentar es pedirle a libvirtd la lista de máquinas virtuales que administra:
# virsh -c qemu:///system list --all
 Id Name                 State
----------------------------------
  8 testkvm              shut off
Iniciemos nuestra máquina virtual de pruebas:
# virsh -c qemu:///system start testkvm
Domain testkvm started
Ahora podemos obtener las instrucciones de conexión para la consola gráfica (puede pasar como parámetro de vncviewer la pantalla VNC devuelta):
# virsh -c qemu:///system vncdisplay testkvm
127.0.0.1:0
Entre otras subórdenes disponibles en virsh encontraremos:
  • reboot para reiniciar una máquina virtual;
  • shutdown para apagarla de forma segura;
  • destroy, para detenerla brutalmente;
  • suspend para pausarla;
  • resume para continuar su ejecución;
  • autostart para activar (o desactivar con la opción --disable) que se inicie la máquina virtual automáticamente cuando inicia el anfitrión;
  • undefine para eliminar todo rastro de la máquina virtual en libvirtd.
Todas estas subórdenes aceptan un identificador de máquina virtual como parámetro.