KVM es el hipervisor integrado en el kernel de Linux: convierte el sistema en un anfitrión capaz de ejecutar máquinas virtuales con aceleración por hardware. QEMU emula los dispositivos de cada VM y libvirt ofrece una capa de gestión común con herramientas como virsh y virt-install.

En este tutorial comprobarás que tu servidor admite virtualización, instalarás KVM, QEMU y libvirt en Ubuntu 24.04 y crearás una primera máquina virtual con Ubuntu a partir de una imagen cloud, accesible por SSH.

Requisitos previos

  • Un servidor con Ubuntu 24.04 LTS de 64 bits (x86_64) y un usuario no root con sudo.
  • Una CPU con extensiones de virtualización (Intel VT-x o AMD-V) activadas en la BIOS/UEFI. Lo normal es usar un servidor bare metal; dentro de un VPS solo funciona si el proveedor expone virtualización anidada.
  • Al menos 4 GB de RAM y 20 GB libres en disco para el anfitrión y una VM pequeña.
  • Una clave SSH pública en tu equipo (~/.ssh/id_ed25519.pub o similar) para acceder a la VM.

Paso 1: Comprobar el soporte de virtualización

Cuenta los núcleos que anuncian las extensiones vmx (Intel) o svm (AMD):

grep -Ec '(vmx|svm)' /proc/cpuinfo

Cualquier valor mayor que 0 significa que la CPU las expone. Si devuelve 0, están desactivadas en la BIOS/UEFI o, en una VM, el hipervisor no ofrece virtualización anidada.

La herramienta kvm-ok da un diagnóstico más claro. Está en el paquete cpu-checker:

sudo apt update
sudo apt install cpu-checker
kvm-ok
INFO: /dev/kvm exists
KVM acceleration can be used

Si la salida dice KVM acceleration can NOT be used, entra en la BIOS/UEFI y activa la opción de virtualización (suele llamarse Intel Virtualization Technology, VT-x, SVM Mode o AMD-V). Sin aceleración, QEMU funcionaría solo en modo emulado, demasiado lento para uso real.

Paso 2: Instalar KVM, QEMU y libvirt

Instala los paquetes necesarios:

sudo apt install qemu-system-x86 qemu-utils libvirt-daemon-system libvirt-clients virtinst ovmf
  • qemu-system-x86: QEMU con soporte KVM para VMs x86_64.
  • qemu-utils: incluye qemu-img para crear y convertir discos.
  • libvirt-daemon-system y libvirt-clients: el servicio libvirt y virsh.
  • virtinst: virt-install y virt-clone para crear VMs desde la línea de comandos.
  • ovmf: firmware UEFI, necesario si quieres VMs con arranque UEFI.

Si administras el servidor desde un escritorio, puedes añadir virt-manager para tener una interfaz gráfica. No hace falta en un servidor sin entorno gráfico.

Comprueba que el módulo KVM está cargado:

lsmod | grep kvm
kvm_amd               217088  0
kvm                  1409024  1 kvm_amd

En una CPU Intel verás kvm_intel en lugar de kvm_amd.

Comprueba que el servicio libvirt está activo. En Ubuntu 24.04 se habilita solo al instalarlo:

systemctl status libvirtd
● libvirtd.service - libvirt legacy monolithic daemon
     Loaded: loaded (/usr/lib/systemd/system/libvirtd.service; enabled; preset: enabled)
     Active: active (running) since Fri 2026-09-25 10:20:31 UTC; 1min ago

Paso 3: Dar acceso a tu usuario

Los miembros del grupo libvirt pueden gestionar las VMs del sistema sin sudo. Añade tu usuario a los grupos libvirt y kvm:

sudo usermod -aG libvirt,kvm $USER

Cierra la sesión SSH y vuelve a entrar para que los grupos se apliquen, y compruébalo:

groups
your_user adm sudo kvm libvirt

Cuando un usuario no root ejecuta virsh, libvirt se conecta por defecto a qemu:///session, una instancia privada del usuario, y no verías las VMs ni las redes del sistema. Indica que quieres usar la conexión del sistema:

echo 'export LIBVIRT_DEFAULT_URI=qemu:///system' >> ~/.bashrc
source ~/.bashrc
virsh uri
qemu:///system

Paso 4: Validar el anfitrión

virt-host-validate revisa los requisitos de QEMU/KVM: dispositivos, cgroups e IOMMU:

sudo virt-host-validate qemu
  QEMU: Checking for hardware virtualization                                 : PASS
  QEMU: Checking if device '/dev/kvm' exists                                 : PASS
  QEMU: Checking if device '/dev/kvm' is accessible                          : PASS
  QEMU: Checking if device '/dev/vhost-net' exists                           : PASS
  QEMU: Checking if device '/dev/net/tun' exists                             : PASS
  QEMU: Checking for cgroup 'cpu' controller support                         : PASS
  QEMU: Checking for cgroup 'memory' controller support                      : PASS
  QEMU: Checking for device assignment IOMMU support                         : WARN (No ACPI DMAR table found, IOMMU either disabled in BIOS or not supported by this hardware platform)

Las comprobaciones de /dev/kvm deben dar PASS. El aviso de IOMMU solo importa si vas a pasar dispositivos PCI (una GPU o una tarjeta de red) directamente a una VM.

Comprueba también la red virtual default, una red NAT (192.168.122.0/24) que libvirt crea al instalarse:

virsh net-list --all
 Name      State    Autostart   Persistent
--------------------------------------------
 default   active   yes         yes

Si aparece como inactive, iníciala y márcala para arrancar con el sistema:

virsh net-start default
virsh net-autostart default

Paso 5: Preparar el disco de la VM

La forma más rápida de tener una VM de Ubuntu es partir de la imagen cloud oficial, que ya está instalada y se configura en el primer arranque con cloud-init. Descárgala en el directorio de imágenes de libvirt:

sudo wget -O /var/lib/libvirt/images/noble-server-cloudimg-amd64.img https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img

En lugar de modificar esa imagen, crea un disco qcow2 de 20 GB que la use como base (backing file). Así puedes crear varias VMs a partir de la misma imagen sin copiarla:

sudo qemu-img create -f qcow2 -F qcow2 -b /var/lib/libvirt/images/noble-server-cloudimg-amd64.img /var/lib/libvirt/images/vm1.qcow2 20G

Compruébalo:

sudo qemu-img info /var/lib/libvirt/images/vm1.qcow2
image: /var/lib/libvirt/images/vm1.qcow2
file format: qcow2
virtual size: 20 GiB (21474836480 bytes)
disk size: 196 KiB
backing file: /var/lib/libvirt/images/noble-server-cloudimg-amd64.img
backing file format: qcow2

Paso 6: Crear la configuración de cloud-init

Las imágenes cloud no traen contraseña: el acceso se configura con cloud-init. Crea un archivo user-data en tu directorio personal:

nano ~/vm1-user-data.yaml
#cloud-config
hostname: vm1
users:
  - name: your_user
    groups: sudo
    shell: /bin/bash
    sudo: ALL=(ALL) NOPASSWD:ALL
    ssh_authorized_keys:
      - ssh-ed25519 AAAA... tu_clave_publica
package_update: true
packages:
  - qemu-guest-agent
runcmd:
  - systemctl enable --now qemu-guest-agent

Sustituye your_user por el usuario que quieras en la VM y la línea ssh-ed25519 AAAA... por el contenido completo de tu clave pública. El agente qemu-guest-agent permite al anfitrión consultar la IP de la VM y apagarla limpiamente.

Paso 7: Crear la máquina virtual

Consulta el identificador de sistema operativo que conoce tu versión de libosinfo; virt-install lo usa para elegir dispositivos óptimos:

virt-install --osinfo list | grep -i ubuntu24
ubuntu24.04

Crea la VM con 2 GB de RAM y 2 vCPU, importando el disco preparado:

virt-install \
  --name vm1 \
  --memory 2048 \
  --vcpus 2 \
  --disk path=/var/lib/libvirt/images/vm1.qcow2,format=qcow2,bus=virtio \
  --import \
  --osinfo ubuntu24.04 \
  --network network=default,model=virtio \
  --cloud-init user-data=$HOME/vm1-user-data.yaml \
  --channel unix,target.type=virtio,target.name=org.qemu.guest_agent.0 \
  --graphics none \
  --noautoconsole

Si tu libosinfo no incluye ubuntu24.04, usa --osinfo linux2022. La opción --channel añade el canal que usa el agente de invitado.

Comprueba que la VM está en marcha:

virsh list
 Id   Name   State
----------------------
 1    vm1    running

Paso 8: Conectarte a la VM

Espera un minuto a que cloud-init termine y consulta la IP que el DHCP de libvirt ha asignado:

virsh domifaddr vm1
 Name       MAC address          Protocol     Address
-------------------------------------------------------------------------------
 vnet0      52:54:00:3b:8a:12    ipv4         192.168.122.57/24

Conéctate por SSH desde el anfitrión con el usuario definido en cloud-init:

Dentro de la VM, confirma que corre sobre KVM:

systemd-detect-virt
kvm

También tienes acceso a la consola serie desde el anfitrión con virsh console vm1 (sal con Ctrl+]), útil si la red de la VM falla.

La red default usa NAT: la VM sale a Internet a través del anfitrión, pero no es accesible desde fuera. Para publicar servicios de la VM necesitarás una red enrutada o en puente, o un proxy inverso en el anfitrión.

Solución de problemas

  • Cannot access storage file ... Permission denied: el disco o la imagen base están fuera de /var/lib/libvirt/images en un directorio que el usuario libvirt-qemu no puede leer, o AppArmor lo bloquea. Guarda los discos en /var/lib/libvirt/images.
  • error: failed to connect to the hypervisor o permiso denegado en el socket: tu usuario no está aún en el grupo libvirt. Cierra la sesión y vuelve a entrar, o usa sudo virsh.
  • virsh list no muestra la VM: estás conectado a qemu:///session. Comprueba con virsh uri que la salida es qemu:///system.
  • virsh domifaddr no devuelve nada: la VM aún arranca o cloud-init no terminó. Prueba con virsh net-dhcp-leases default o entra por virsh console vm1.

Conclusión

Tienes un anfitrión KVM con libvirt funcionando en Ubuntu 24.04 y una primera VM creada a partir de una imagen cloud y configurada con cloud-init. Como siguientes pasos:

  • Aprende a gestionar el ciclo de vida de las VMs, snapshots y recursos con virsh.
  • Configura redes aisladas, enrutadas o en puente con libvirt para exponer tus VMs.
  • Automatiza la creación de VMs reutilizando la imagen base y distintos archivos user-data.