qemu-kvm

QEMU-kVM aumentar la memoria “en vivo”, método 1

Existen dos métodos principales para aumentar (o disminuir) la memoria “en vivo” del servidor. Ambas requieren un poco de previsión.

El primer paso, al arrancar el servidor tener en cuenta que “memory” identifica la memoria máxima que queremos que pueda ocupar ese servidor, y “currentmemory” es la que le dejamos ocupar al arrancar.

En el XML de libvirt:

En línea de comandos con QEMU:

 

Si queremos modificar la RAM que utiliza nuestro servidor:

 

En libvirt,

 

Y en libvirt, pero pasando el comando directamente al “monitor” de QEMU con “virsh qemu-monitor-command –hmp SERVIDOR –cmd ”

 

 

Veremos como se ajusta la RAM dentro del servidor, siempre que este tenga activado el soporte para “Memory Ballooning”.

 

Hay varias cosas a tener en cuenta:

 

  • En Windows, necesitas tener activo el device de ballooning y con el driver adecuado, que viene en la ISO de drivers para windows de QEMU , https://fedoraproject.org/wiki/Windows_Virtio_Drivers
  • Al arrancar, el servidor te intentará reservar lo que esté especificado como MÁXIMO. Es decir, si tu creas un servidor con 1024 de Memory y 512 de “current”, al arrancar, intentará reservar 1024. Si no cabe, porque deja sin memoria el servidor, el proceso de QEMU morirá.
  • No es bueno bajar la RAM por debajo de 128MB en los linux. Dará kernel panic. Hay que tener cuidado al especificar las unidades de medida de la RAM.

 

 

Actualizar la versión de QEMU, sin “reiniciar”

Hay dos maneras de modificar / actualizar la versión de QEMU sin “reiniciar”.

 

La primera, es haciendo una migración en caliente. Si tenemos dos servidores físicos con el mismo almacenamiento compartido (o incluso sin eso, utilizando la opción –copy-storage-all), podemos ejecutar un comando para migrar el servidor en caliente de uno a otro.

El truco aquí consiste en que al arrancar el qemu-kvm en el servidor remoto se hace con el ejecutable de la versión actualizada. Obviamente, tiene que poder arrancar, sin eso, fallará la migración, pero, al menos, el servidor virtual seguirá funcionando en origen.

 

La segunda manera, es hacer un “virsh save” y luego un “restore.

El comando “save” de libvirt te guarda un fichero con la memoria y las especificaciones de la máquina virtual. Dentro del fichero, por ejemplo, va el XML de definición.

El servidor virtual se detiene del todo, pero…con truco. Cuando se restaura la máquina virtual la ejecución continua en el mismo punto en el que se guardó 😉

De nuevo, al hacer el restore de la máquina virtual, si antes hemos modificado la versión de qemu-kvm, se intentará arrancar con la nueva versión.

 

Algún error que me ha dado alguna vez al hacer este tipo de upgrades era que el servidor estaba definido con el tipo de máquina “pc”.

Y al restaurarlo, ese “pc” en realidad es un alias a la última versión de máquina ACTUAL. Con modificar el fichero de save para poner un tipo de maquina más antiguo, funcionaba.

Para ver los diferentes tipos de VM posibles, se ejecuta el comando, donde se ve que “pc” se corresponde, en este caso, con pc-i440fx-1.5.

 

Para modificar el fichero donde hemos guardado la VM, se utiliza el comando

Cuidado con este comando, porque no permite hacer cualquier modificación. Parece ser que el tamaño de las modificaciones que se hacen en el XML guardado no pueden superar en tamaño a lo que había antes.

 

Instalar y compilar la última versión de libvirt en Ubuntu / Debian

En este mini-artículo vamos a ver cómo compilar la última versión de libvirt en un Ubuntu o Debian moderno.

Lo primero es descargar el código fuente de http://libvirt.org/sources/ . En este caso:

Lo descomprimimos con “tar xf ” y dentro del directorio creado ejecutamos:

 

Es posible que fallen dependencias, por lo que hay que instalar varios paquetes “-dev” para ser capaces de empezar a compilar.

En mi caso, un Ubuntu 16, tuve que instalar “libdevmapper-dev”, “libyajl-dev”. En un sistema recién instalado habrá que instalar bastantes más.

 

Cuando haya terminado el comando autogen correctamente, ejecutamos:

 

Si estamos en un sistema con systemctl (Debian 8 , Ubuntu 16 o superior), hay que editar el fichero

y modificar la línea que apunta al ejecutable de libvirt de esta manera

 

Luego ejecutamos

para recargar los ficheros de configuración, y para reiniciarlo:

 

 

Finalmente, con un “sudo virsh version”, tendremos que ver la versión correcta.

 

 

Es posible que os de un error indicando que no encuentra el emulador de X86_64. Eso ocurre porque no encuentra el emulador de qemu-kvm.

En mi caso, con hacer un link de /usr/local/qemu-kvm/bin/qemu-system-x86_64 a /usr/sbin/qemu-kvm ya bastó para que funcionase correctamente.

 

De igual manera que hicimos el otro día, se puede crear un paquete .deb para redistribuirlo en otros servidores físicos con checkinstall, pero no os cogerá los cambios del fichero del systemctl para el arranque.

 

 

QEMU-KVM: compilar / instalar QEMU en Debian / Ubuntu

Instalar QEMU en un Debian es cuestión de un comando, normalmente.

 

Compilar QEMU y crear un paquete en Debian no es tan fácil ni tan útil como en Redhat/CentOS. Básicamente porque es una mala idea sobreescribir los ejecutables del sistema operativo con tu propio paquete.

Pero las versiones de QEMU y libvirt que vienen con el sistema base son tan antiguas, que es casi imposible resistirse a tener una versión moderna con la que probar.

Primero descargamos el código fuente de QEMU de:

http://wiki.qemu.org/Download

Yo he probado con la versión 2.6.0. La 2.7.0 saldrá en breve. Mi sistema operativo es un Debian 8, pero con pocas variaciones, sirve también para Ubuntu.

Necesitamos instalar unos cuantos paquetes previos a la compilación:

Ahora entramos en el directorio de qemu, tras descomprimirlo, y hacemos el “configure”.

Las opciones de qemu son bastantes más. Pero eso es lo básico para funcionar, y tenerlo, además, algo optimizado utilizando la librería tcmalloc de google. Es muy posible que tengáis que tener arrancado el demonio “numad” para poder hacer funcionar ciertos servidores virtuales.

Tan solo nos interesa el ejecutable de x86_64 (en mi caso, porque mi portátil tiene dicha arquitectura), y el instalarlo en /usr/local/qemu-kvm para que no se mezcle con el previo del sistema operativo, si está instalado.

Si no queremos tener instalada SDL, se puede usar GTK, con –enable-gtk.

 

Si el configure funciona, tendremos una lista de las opciones activadas. Hay que fijarse bien en estas:

VNC support       yes , para tener soporte de VNC y poder conectar con clientes VNC al proceso de QEMU, como si fuera una pantalla

vhost-net support yes, para tener soporte para los módulos de vhost_net, que aceleran MUCHO el rendimiento de los interfaces de red

KVM support       yes, que nos indica que ha aceptado el soporte para KVM. Sin eso funciona pero mucho más lento

 

Seguidamente, ejecutamos “make”. Podemos acelerarlo con “make -jX” donde X es el número de cores que tenemos en el ordenador donde estemos compilando qemu.

Si todo va bien, podemos ejecutar el checkinstall, con el comando

Nos preguntará acerca de la documentación y los nombres de los paquetes. Yo no suelo incluirla.

Al concluir, nos mostrará un mensaje:

Lo podemos instalar con

La mayor ventaja que tiene es que al llevarlo a otro servidor físico, podremos instalar las dependencias automáticamente.

Ahora ya podemos ver que tenemos la nueva versión instalada.

 

Se puede ejecutar directamente, o bien via libvirtd, en el XML de definición de un servidor virtual, añadir

<emulator>/usr/local/qemu-kvm/bin/qemu-system-x86_64</emulator>

 

QEMU-KVM: virtio vs SCSI vs IDE

Una de las optimizaciones más importantes en cuanto a almacenamiento en QEMU-KVM es decidir el driver que vamos a utilizar para los discos duros de nuestro servidor simulado. Normalmente será VirtIO, pero, como veréis más adelante, no siempre es la mejor opción.

En las primeras versiones, tan solo existía IDE, luego añadieron SCSI, y más adelante, cuando observaron que simular de manera demasiado exacta esos protocolos hacía que no aprovechasen tanto los sistemas, inventaron VirtIO, que es una serie de módulos propios con mucha más velocidad de entrada/salida en máquinas virtuales con QEMU-KVM.

¿Qué ofrece cada uno?

  • IDE: ¿Recordáis cuando en vuestro PC casero teníais dos cables como cintas conectadas a la placa base y podíais colocar tan solo 4 dispositivos? Pues en QEMU el modo IDE hace exactamente lo mismo, de manera que se utiliza principalmente para colocar los lectores de CDROM. Los dispositivos con IDE se llaman /dev/hda, /dev/hdb, etc..
  • SCSI: Aquí el número de dispositivos aumenta, al igual que el rendimiento. Es una simulación casi completa de SCSI, lo cual tiene sus ventajas e inconvenientes. Los dispositivos con SCSI se llamarán /dev/sda, sdb, sdc…
  • VirtIO: Los dispositivos serán /dev/vda, vdb, vdc, y tendrán mayor rendimiento que los otros dos protocolos, y un uso menor de CPU (por mega transferido).

¿Cuánto es más rápido uno que el otro?

Si con IDE obtienes 512 MB/s de transferencia, con SCSI obtendrás 700-800 MB/s y con Virtio 1.2 GB/s. La regla suele ser más o menos esa, pero depende de la versión de kernel que se esté utilizando tanto en el hypervisor como en el servidor virtual y de los sistemas de almacenamiento utilizados.

Hay algunas webs que ofrecen benchmarks bastante antiguos ya:

https://www.ibm.com/support/knowledgecenter/linuxonibm/liaat/liaatbpperfmods.htm

Realmente no merece la pena ni mirarlos porque esos resultados han quedado desactualizados. En otro post comentaremos cómo hacer pruebas de carga decentes para obtener el mejor rendimiento de nuestro sistema y poder irlo comparando de unos entornos a otros.

RedBooks de IBM

La mejor documentación respecto a esto la proporciona IBM en sus RedBooks.

https://www.ibm.com/support/knowledgecenter/linuxonibm/liaat/liaatbestpractices_pdf.pdf

Y es lo que recomiendo leer si se quiere exprimir al máximo los diferentes sistemas.

 

Trim y comandos SCSI

Aunque esos libros estén realmente bien esto se explica en poco sitios, y es algo a tener REALMENTE en cuenta antes de tomar la decisión de cual sistema de almacenamiento utilizar.

VirtIO no soporta TRIM ni los comandos necesarios para hacer que, si eliminas un bloque de datos en el disco duro del servidor virtual, este cambio llegue exacto al sistema de almacenamiento que hay por debajo de todo, y se liberen los bloques no utilizados.

Es decir, imaginad que hemos comprado SSD último modelo y creamos dentro de este SSD una imagen de disco duro con un “truncate -s” o con un “LVM” en modo de thin provisioning. Si desde la VM escribimos un sector, luego escribimos más a posteriori después de ese, y luego borramos el sector del medio, el sistema de almacenamiento del hypervisor creerá que ese sector sigue ocupado, y no lo liberará.

La manera de corregir esto es utilizar SCSI. Pero a costa de perder rendimiento ( y mucho).

Si se utiliza VirtIO, por mucho que hagáis “fstrim” en vuestro sistema operativo, eso no se traducirá en liberación de espacio. De hecho, probablemente os salte un error comentando que no está soportado ese comando.

Para activar esta funcionalidad en SCSI se utiliza el valor “discard=unmap” en las opciones del disco duro, ya sea en el comando de qemu-KVM o  en el XML de definición del servidor en libvirt.

 

VirtIO en Windows

Los drivers de VirtIO para servidores virtuales con sistema operativo Windows se pueden conseguir en la web de Fedora:

https://fedoraproject.org/wiki/Windows_Virtio_Drivers

O bien en la web de Oracle:

http://www.oracle.com/us/technologies/virtualization/virtualilzation-066470.html

Cabe destacar que no siempre tener instalada la última versión significa tener, ni más rendimiento, ni más estabilidad. Yo he hecho pruebas de carga sobre diferentes versiones y con algunas obtenía resultados sorprendentes.

Suelo utilizar una suite de pruebas gratuita muy fácil de instalar llamada CrystalDiskMark para asegurarme que la versión que utilizo es la mejor.

http://crystalmark.info/download/index-e.html