Icono del sitio Disaster Project

Máquina virtual linux con KVM desde linea de comandos

Si queremos levantar máquinas virtuales en un entorno Linux KVM que no disponga de entorno gráfico podemos levantar máquinas virtuales desde linea de comando usando una plantilla XML.

Este artículo explica como funciona internamente el despliegue que se realiza con Ansible-libvirt en https://www.disasterproject.com/index.php/2019/06/entorno-minimo-kvm-y-ansible/

Instalar Qemu-KVM y Libvirt

Primero debemos tener instalado libvirt y Qemu-KVM que en Ubuntu/Debian se instala con:

$ sudo apt-get install -y libvirt-daemon-system python-libvirt python-lxml

Y en CentOS/Redhat con:

$ sudo yum install -y libvirt-daemon-kvm python-lxml

Para iniciar el servicio haremos $ sudo systemctl enable libvirtd && sudo systemctl start libvirtd

Configurar una plantilla de red

Libvirt nos provee de una poderosa herramienta para gestión de las máquinas virtuales llamada ‘virsh’, la cual debemos de utilizar para poder gestionar las máquinas virtuales KVM desde la linea de comandos.

Para una máquina virtual necesitamos principalmente tres elementos, el primero es una configuración de red que entre otras cosas provea a las máquinas virtuales de IP vía DHCP. Para ello libvirt necesita de una plantilla XML como la siguiente (que llamaremos net.xml):

<network>
  <name>NOMBRE_DE_RED</name>
  <forward mode='nat'>
    <nat>
      <port start='1' end='65535'/>
    </nat>
  </forward>
  <bridge name='NOMBRE_DEL_BRIDGE' stp='on' delay='0'/>
  <ip address='IP_HOST' netmask='MASCARA_RED'>
    <dhcp>
      <range start='INICIO_RANGO_DHCP' end='FIN_RANGO_DHCP'/>
    </dhcp>
  </ip>
</network>

Cuyos elementos principales son:

Preparando la imagen del sistema operativo

El segundo elemento es la imagen de la máquina virtual, la imagen se puede crear o descargar, siendo recomendable lo segundo para reducir el tiempo de despliegue. Una fuente de imágenes para máquinas virtuales con KVM/libvirt es Vagrant ( https://app.vagrantup.com/boxes/search?provider=libvirt ), para obtener una imagen de la máquina virtual que nos interese de las que existen en dicha página nos las descargaremos de https://app.vagrantup.com/NOMBRE_APP/boxes/ETIQUETA_APP/versions/VERSION_APP/providers/libvirt.box siendo NOMBRE_APP el nombre de la aplicación que queremos utilizar (p.e. debian), ETIQUETA_APP es la distribución de dicha aplicación (p.e. stretch64) y por último VERSION_APP es la versión de la aplicación (p.e. 9.9.0). Aún así existen repositorios de imágenes específicos como por ejemplo los de CentOs que están en http://cloud.centos.org/centos/7/vagrant/x86_64/images .

Una vez obtenido el archivo libvirt.box, se descomprime con tar -zcf libvirt.box lo que nos genera tres archivos, uno de los cuales es la imagen de la máquina virtual (box.img) que renombraremos a NOMBRE_DESCRIPTIVO.qcow2 y copiaremos en la carpeta estándar para imágenes de máquinas virtuales de libvirt (/var/lib/libvirt/images) y le daremos permisos al usuario libvirt para que pueda gestionar dicha imagen (chown libvirt /var/lib/libvirt/images/NOMBRE_DESCRIPTIVO.qcow2 )

Es importante indicar que si queremos acceder a la máquina virtual vamos a necesitar una clave que la descargamos con wget -O insecure_private_key https://raw.githubusercontent.com/hashicorp/vagrant/master/keys/vagrant, que le aplicamos permisos para el acceso solo para el usuario actual ( $ chmod 600 insecure_private_key )

Plantilla para la máquina virtual

El tercer elemento para crear la máquina virtual una vez creada la red es una plantilla de máquina virtual, que para un sistema operativo reciente tendrá la siguiente forma:

<domain type='kvm'>
  <name>NOMBRE_VM</name>
  <memory unit='MB'>MEMORY_VM</memory>
  <vcpu>CPU_NUMBER</vcpu>
  <os>
    <type>hvm</type>
    <bootmenu enable='no'/>
    <boot dev='hd'/>
  </os>
  <features>
    <acpi/>
    <apic/>
  </features>
  <clock offset='utc'/>
  <on_poweroff>destroy</on_poweroff>
  <on_reboot>restart</on_reboot>
  <on_crash>destroy</on_crash>
  <devices>
    <disk type='file' device='disk'>
      <driver name='qemu' type='qcow2'/>
      <source file='RUTA_ALMACEN_IMAGENES/NOMBRE_IMAGEN.qcow2'/>
      <target dev='vda' bus='virtio'/>
    </disk>
    <interface type='network'>
      <source network='NOMBRE_DE_RED'/>
      <model type='virtio'/>
    </interface>
    <console type='pty'>
      <target type='serial' port='0'/>
    </console>
    <input type='mouse' bus='ps2'>
      <alias name='input0'/>
    </input>
    <input type='keyboard' bus='ps2'>
      <alias name='input1'/>
    </input>
    <graphics type='spice' port='5900' autoport='yes' listen='127.0.0.1'>
      <listen type='address' address='127.0.0.1'/>
      <image compression='off'/>
    </graphics>
    <video>
      <model type='cirrus' vram='16384' heads='1' primary='yes'/>
      <alias name='video0'/>
    </video>
    <memballoon model='virtio'/>
  </devices>
</domain>

Cuyos elementos son:

Desplegando la máquina virtual

Una vez creadas las plantillas y desplegada la imagen ejecutamos:

# sudo virsh net-create plantilla_red.xml
# sudo virsh create plantilla_máquina_virtual.xml

Por último comprobamos que funciona, primero identificamos si está iniciado con # sudo virsh list, segundo obtenemos la ip en uso con # sudo virsh net-dhcp-leases NOMBRE_DE_RED y por último accedemos a la IP asignada con # ssh -i insecure_private_key vagrant@IP

Salir de la versión móvil