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 hipervisor en sí mismo. Según el hardware disponible, el paquete apropiado será xen-hypervisor-4.11-amd64, xen-hypervisor-4.11-armhf o xen-hypervisor-4.11-arm64.
  • Un núcleo que ejecuta sobre dicho hipervisor. Cualquier núcleo posterior a 3.0 funcionará, incluyendo la versión 4.19 presente en Buster.
  • 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 hypervisor también incluirá xen-utils-4.11, que contien las herramientas para controlar el hypervisor 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. Sepa, sin embargo, que generalmente este no será el primero en la lista, pero estará seleccionado 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 buster).
  • --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=buster --role=udev

[...]
General Information
--------------------
Hostname       :  testxen
Distribution   :  buster
Mirror         :  http://deb.debian.org/debian
Partitions     :  swap            512M  (swap)
                  /               2G    (ext4)
Image type     :  sparse
Memory size    :  256M
Kernel path    :  /boot/vmlinuz-4.19.0-5-amd64
Initrd path    :  /boot/initrd.img-4.19.0-5-amd64
[...]
Logfile produced at:
         /var/log/xen-tools/testxen.log

Installation Summary
---------------------
Hostname        :  testxen
Distribution    :  buster
MAC Address     :  00:16:3E:0C:74:2F
IP Address(es)  :  dynamic
SSH Fingerprint :  SHA256:PuAGX4/4S07Xzh1u0Cl2tL04EL5udf9ajvvbufBrfvU (DSA)
SSH Fingerprint :  SHA256:ajFTX54eakzolyzmZku/ihq/BK6KYsz5MewJ98BM5co (ECDSA)
SSH Fingerprint :  SHA256:/sFov86b+rD/bRSJoHKbiMqzGFiwgZulEwpzsiw6aSc (ED25519)
SSH Fingerprint :  SHA256:/NJg/CcoVj+OLE/cL3yyJINStnla7YkHKe3/xEdVGqc (RSA)
Root Password   :  EwmQMHtywY9zsRBpqQuxZTb
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-4.11) para reemplazar el elemento eth0 existente:
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  1894     2     r-----      63.5
# 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  1505     2     r-----     100.0
testxen                                     13  1024     0     --p---       0.0
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 10 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.

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) a la interfaz bridge (generalmente br0) y configurar un enlace entre ellas. 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 eth0
#iface eth0 inet dhcp

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:
# Interfaz eth0 sin cambios
auto eth0
iface eth0 inet dhcp

# Interfaz virtual
auto tap0
iface tap0 inet manual
  vde2-switch -t tap0

# Puente para los contenedores
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 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á un contenedor Debian:
root@mirwiz:~# 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...
[...]
root@mirwiz:~# 
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 sistema de archivos recientemente creado ahora contiene un sistema Debian mínimo y, de forma predeterminada, el contenedor no tendrá interfaz de red (con el permiso de la interfaz local de loopback). Debido a que esta no es la configuración deseada, editaremos el archivo de configuración del contenedor (/var/lib/lxc/testlxc/config) y agregar algunos elementos lxc.network.*:
lxc.net.0.type = veth
lxc.net.0.flags = up
lxc.net.0.link = br0
lxc.net.0.hwaddr = 4a:49:43:49:79:20
Estas líneas significan, respectivamente, que se creará una interfaz virtual en el contenedor; que será iniciada automáticamente cuando inicie el contenedor; que será conectada automáticamente al puente br0 en el anfitrión; y que su dirección MAC será la especificada. En caso que esta última línea no exista 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

12.2.2.4. Inicio del contenedor

Ahora que 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. Podemos asignar una ejecutando lxc-attach -n testlxc contraseña.. Ahora podemos acceder:
root@mirwiz:~# lxc-console -n testlxc
Debian GNU/Linux 9 testlxc console	

testlxc login: root
Password: 
Linux testlxc 4.19.0-5-amd64 #1 SMP Debian 4.19.37-5 (2019-06-19) 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.
root@testlxc:~# ps auxwf
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.2  56736  6608 ?        Ss   09:28   0:00 /sbin/init
root        32  0.0  0.1  46096  4680 ?        Ss   09:28   0:00 /lib/systemd/systemd-journald
root        75  0.0  0.1  67068  3328 console  Ss   09:28   0:00 /bin/login --
root        82  0.0  0.1  19812  3664 console  S    09:30   0:00  \_ -bash
root        88  0.0  0.1  38308  3176 console  R+   09:31   0:00      \_ ps auxwf
root        76  0.0  0.1  69956  5636 ?        Ss   09:28   0:00 /usr/sbin/sshd -D
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 la opción --daemon de lxc-start. 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

A diferencia de herramientas como VirtualBox, KVM por sí mismo no incluye ninguna interfaz de usuario para crear y administrar máquinas virtuales. El paquete qemu-kvm sólo provee un ejecutable para iniciar máquinas virtuales así como el script de inicialización que carga los módulos de núcleo apropiados.
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 al 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.
root@mirwiz:~# mkdir /srv/kvm
root@mirwiz:~# virsh pool-create-as srv-kvm dir --target /srv/kvm
Pool srv-kvm created

root@mirwiz:~# 
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 1024             4
               --disk /srv/kvm/testkvm.qcow,format=qcow2,size=10  5
               --cdrom /srv/isos/debian-10.2.0-amd64-netinst.iso  6
               --network bridge=virbr0   7
               --graphics vnc            8
               --os-type linux           9
               --os-variant debian10

Empezando la instalación...
Asignando 'testkvm2.qcow'                                   |  10 GB  00:00

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).

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.3, “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.
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: 
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.

12.2.3.5. Instalación de un sistema basado en RPM sobre Debian con yum

Si pretende que la máquina virtual ejecute Debian (o uno de sus derivados), puede inicializar el sistema con debootstrap como se describió anteriormente. Pero desea instalar un sistema basado en RMP en la máquina virtual (como Fedora, CentOS o Scientific Linux), necesita realizar la configuración con la aplicación yum (disponible en el paquete del mismo nombre).
El procedimiento require usar rpm para extraer un conjunto inicial de archivos, incluyendo probablemente bastantes archivos de configuración de yum, y luego ejecutar el comando yum para descomprimir el conjunto de paquetes restantes. Pero desde que podemos llamar a yum desde fuera de una jaula chroot, necesitaremos algunos cambios provisionales. En los ejemplos siguientes, el destino de chroot es /src/centos.
# rootdir="/srv/centos"
# mkdir -p "$rootdir" /etc/rpm
# echo "%_dbpath /var/lib/rpm" > /etc/rpm/macros.dbpath
# wget http://mirror.centos.org/centos/7/os/x86_64/Packages/centos-release-7-6.1810.2.el7.centos.x86_64.rpm
# rpm --nodeps --root "$rootdir" -i centos-release-7-6.1810.2.el7.centos.x86_64.rpm
rpm: RPM should not be used directly install RPM packages, use Alien instead!
rpm: However assuming you know what you are doing...
warning: centos-release-7-6.1810.2.el7.centos.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID f4a80eb5: NOKEY
# sed -i -e "s,gpgkey=file:///etc/,gpgkey=file://${rootdir}/etc/,g" $rootdir/etc/yum.repos.d/*.repo
# yum --assumeyes --installroot $rootdir groupinstall core
[...]
# sed -i -e "s,gpgkey=file://${rootdir}/etc/,gpgkey=file:///etc/,g" $rootdir/etc/yum.repos.d/*.repo