🎨 Sysprovider Code
Sysprovider LogoWiki
🇪🇸Hosting español para ecommerce

Virtualización con KVM y QEMU Avanzado

Actualizado el 13 de noviembre de 2025

La virtualización KVM (Kernel-based Virtual Machine) se ha consolidado como la columna vertebral de los entornos de producción modernos, especialmente cuando se combina con QEMU servidores para emular hardware completo. Sin embargo, superar el nivel básico de “crear una VM” implica dominar técnicas avanzadas como la migración en vivo, el aislamiento recursos y el tuning de rendimiento. Este artículo está diseñado para administradores de sistemas que ya tienen experiencia con KVM y buscan llevar su infraestructura al siguiente nivel.

Arquitectura Avanzada de KVM y QEMU

Para entender la virtualización KVM a nivel avanzado, primero debemos desglosar cómo interactúan KVM y QEMU. KVM es el módulo del kernel de Linux que expone las capacidades de virtualización por hardware (Intel VT-x o AMD-V). QEMU actúa como el emulador de dispositivos y el espacio de usuario que maneja la lógica de la VM.

Diferencias clave entre KVM puro y QEMU/KVM

Aunque a menudo se usan juntos, es crucial distinguirlos:

  • KVM puro: Proporciona la aceleración por hardware. Sin QEMU, solo puedes ejecutar código huésped sin dispositivos emulados.
  • QEMU/KVM: La combinación estándar. QEMU emula dispositivos (red, almacenamiento, gráficos) mientras KVM acelera la CPU.
  • KVM con virtio: Usa paravirtualización para dispositivos de red y disco, reduciendo drásticamente la latencia.

[INFO] La mayoría de las distribuciones modernas (RHEL 9, Ubuntu 22.04+) usan QEMU 7.0+ con KVM. Asegúrate de tener habilitado kvm_intel o kvm_amd en el kernel.

Configuración de NUMA y afinidad de CPU

En servidores con múltiples sockets, el aislamiento recursos es crítico. Las máquinas virtuales no deben migrar entre nodos NUMA sin control, ya que esto incrementa la latencia de memoria.

Ejemplo de afinidad CPU y memoria con virsh:

# Ver topología NUMA del host
virsh capabilities | xsltproc --nonet /usr/share/libvirt/schemas/capabilities.rng - | grep -A 10 "cell"

# Asignar vCPUs fijas a una VM (ejemplo: VM1 usa CPUs 0-3 del nodo 0)
virsh vcpupin vm1 0 0
virsh vcpupin vm1 1 1
virsh vcpupin vm1 2 2
virsh vcpupin vm1 3 3

# Fijar memoria a un nodo NUMA
virsh numatune vm1 --nodeset 0 --mode strict

Migración en Vivo: Estrategias y Optimización

La migración en vivo (live migration) permite mover una VM en ejecución entre hosts sin tiempo de inactividad. En entornos avanzados, no solo se migra la RAM, sino también el estado del disco y las conexiones de red.

Tipos de migración en KVM

  1. Migración en vivo estándar (TCP): Usa un puerto dedicado (por defecto 49152-49215). Adecuada para redes de baja latencia.
  2. Migración con bloque de disco (NFS/GlusterFS): Requiere almacenamiento compartido. Ideal para discos QCOW2.
  3. Migración con replicación de bloques (DRBD): Permite migración sin almacenamiento compartido, usando replicación síncrona.

Comando avanzado para migración en vivo con compresión

Para reducir el tráfico de red durante la migración en vivo, podemos habilitar compresión XBZRLE:

virsh migrate --live --compressed --comp-methods xbzrle \
  --comp-zlib-level 3 \
  --domain vm-produccion \
  --desturi qemu+tcp://192.168.10.20/system \
  --verbose

[WARNING] La compresión incrementa el uso de CPU en ambos hosts. Monitorea la carga con top o htop antes de activarla en entornos con CPU limitada.

Tolerancia a fallos en migración

Para evitar que una migración en vivo falle por latencia de red, ajusta los parámetros de convergencia:

# Aumentar el tiempo de espera a 5 segundos
virsh migrate --live --timeout 5 \
  --domain vm-critica \
  --desturi qemu+tcp://192.168.10.30/system

Si la migración no converge (la VM modifica RAM más rápido de lo que se transfiere), usa el modo auto-converge:

virsh migrate --live --auto-converge \
  --domain vm-pesada \
  --desturi qemu+tcp://192.168.10.40/system

Aislamiento de Recursos: Más Allá de cgroups

El aislamiento recursos en KVM se logra mediante cgroups v2, pero la configuración avanzada requiere manipular directamente los controladores de CPU, memoria y E/S.

Control de CPU con cgroups v2

Para garantizar que una VM no consuma más del 50% de una CPU física:

# Crear un grupo de control para la VM
mkdir -p /sys/fs/cgroup/cpu/kvm-vm1

# Establecer límite de 50% (50000/100000 microsegundos)
echo 50000 > /sys/fs/cgroup/cpu/kvm-vm1/cpu.max

# Asignar el PID del proceso QEMU
echo 12345 > /sys/fs/cgroup/cpu/kvm-vm1/cgroup.procs

Limitación de ancho de banda de disco

Con blkio podemos limitar la E/S de una VM:

# Limitar a 100 MB/s de lectura y 50 MB/s de escritura
echo "8:0 104857600" > /sys/fs/cgroup/blkio/kvm-vm1/blkio.throttle.read_bps_device
echo "8:0 52428800" > /sys/fs/cgroup/blkio/kvm-vm1/blkio.throttle.write_bps_device

[TIP] Para discos NVMe, reemplaza 8:0 por el major:minor correspondiente (ej: 259:0). Verifica con lsblk.

Aislamiento de memoria con hugepages

Para mejorar el rendimiento de memoria, asigna hugepages de 2 MB o 1 GB:

# Reservar 4 GB de hugepages de 2 MB
echo 2048 > /proc/sys/vm/nr_hugepages

# Configurar libvirt para usar hugepages en una VM
virsh edit vm-memoria-intensiva
# Agregar dentro de <memoryBacking>:
# <hugepages>
#   <page size="2" unit="Mib" nodeset="0"/>
# </hugepages>

Tuning de Red: OVS y DPDK

Para QEMU servidores con alta demanda de red, la pila de red por defecto (tap + bridge) es insuficiente. Aquí entra Open vSwitch (OVS) con DPDK.

Instalación de OVS con DPDK

# En RHEL 9
dnf install openvswitch dpdk dpdk-tools

# Configurar OVS para usar DPDK
ovs-vsctl set Open_vSwitch . other_config:dpdk-init=true
systemctl restart openvswitch

# Crear un puente DPDK
ovs-vsctl add-br br-dpdk -- set bridge br-dpdk datapath_type=netdev

Conectar una VM a OVS con vhost-user

En el XML de la VM:

<interface type='vhostuser'>
  <mac address='52:54:00:00:00:01'/>
  <source type='unix' path='/var/run/openvswitch/vhost-user-1' mode='server'/>
  <model type='virtio'/>
  <driver name='vhost' queues='4'>
    <host mrg_rxbuf='off'/>
  </driver>
</interface>

Almacenamiento Avanzado: QCOW2 y Thin Provisioning

El formato QCOW2 permite características avanzadas como snapshots, compresión y cifrado.

Creación de un disco QCOW2 con cifrado LUKS

# Crear un disco de 50 GB con cifrado
qemu-img create -f qcow2 -o encrypt.format=luks,encrypt.key-secret=mysecret \
  /var/lib/libvirt/images/vm-segura.qcow2 50G

# En el XML de la VM, agregar:
# <secret type='passphrase' ephemeral='no'>
#   <uuid>uuid-del-secreto</uuid>
# </secret>

Snapshots y backing files

Para ahorrar espacio, usa backing files:

# Crear imagen base
qemu-img create -f qcow2 base.qcow2 20G

# Crear snapshot diferencial (backing file)
qemu-img create -f qcow2 -b base.qcow2 -F qcow2 vm1.qcow2

# Ver la cadena de backing files
qemu-img info --backing-chain vm1.qcow2

Monitorización y Diagnóstico Avanzado

Para depurar problemas de rendimiento en virtualización KVM, usa herramientas específicas:

Estadísticas de KVM con perf

# Monitorear exits de VM (VMEXIT)
perf stat -e kvm:kvm_exit -a -- sleep 10

# Ver si hay muchos exits por E/S
perf stat -e kvm:kvm_entry,kvm:kvm_exit -p $(pgrep qemu)

Análisis de latencia con virsh domstats

# Obtener estadísticas de CPU, memoria y bloque
virsh domstats --state --cpu-total --balloon --block vm-produccion

# Ver estadísticas de red
virsh domstats --net vm-produccion

[WARNING] Un alto número de kvm_exit (más de 5000/s) indica que la VM está haciendo muchas llamadas al hipervisor. Revisa si los drivers virtio están instalados en el huésped.

Automatización con Ansible y libvirt

Para gestionar múltiples QEMU servidores, la automatización es clave. Ejemplo de playbook de Ansible para migración en vivo:

- name: Migrar VM a host de respaldo
  hosts: kvm-hosts
  tasks:
    - name: Verificar estado de la VM
      community.libvirt.virt:
        name: "{{ vm_name }}"
        state: running
      register: vm_state

    - name: Migrar VM en vivo
      community.libvirt.virt:
        name: "{{ vm_name }}"
        migrate: true
        dest: "qemu+tcp://{{ target_host }}/system"
        live: true
      when: vm_state.state == "running"

Seguridad en Entornos KVM Avanzados

El aislamiento recursos también implica seguridad. Implementa sVirt (SELinux para KVM) y etiquetado dinámico:

# Ver etiqueta SELinux de una VM
ps -eZ | grep qemu

# Forzar etiquetado personalizado
chcon -t svirt_image_t /var/lib/libvirt/images/vm-segura.qcow2

Uso de seccomp para limitar syscalls

En el XML de la VM, agrega:

<seccomp>
  <allow_syscalls>
    <syscall name='read'/>
    <syscall name='write'/>
  </allow_syscalls>
</seccomp>

Conclusión

Dominar la virtualización KVM y QEMU servidores a nivel avanzado no solo implica conocer los comandos básicos, sino entender cómo interactúan el kernel, la memoria, la red y el almacenamiento. La migración en vivo bien configurada, el aislamiento recursos mediante cgroups y NUMA, y el tuning de red con OVS/DPDK son habilidades que diferencian a un SysAdmin junior de uno senior.

La clave está en la monitorización constante y la automatización. Implementa las técnicas aquí descritas en un entorno de pruebas antes de llevarlas a producción. La inversión en aprendizaje de KVM avanzado se traduce en una infraestructura más estable, segura y eficiente.

[TIP] No olvides probar la migración en vivo con una VM que tenga al menos 8 GB de RAM para apreciar realmente los efectos de la compresión y el auto-converge.

¿Necesitas ayuda?Son dos de nuestros técnicos, Agustín y Mikel, y están disponibles para resolver cualquier problema.

Hablar con ellos ahora
Agustín y Mikel