Category Archives: Virtualización

Una forma de reducir el tamaño de un qcow2 para respaldar

El sistema de virtualización por excelencia en Linux es KVM (libvirt). Las máquinas virtuales en KVM usualmente almacenan su disco en formato QCOW2.

QCOW2 utiliza, en principio, solamente el espacio que requiere, digamos que tenemos un disco QCOW2 de 50GB de tamaño, sin embargo esto no significa que el archivo .QCOW2 utilizará 50GB en disco desde un inicio. Sino que utilizará lo que se va realmente almacenando, digamos que estamos utilizando 8GB de este disco, entonces QCOW2 utilizará aproximadamente 8GB de los 50GB del disco.

A medida que pasa el tiempo, el sistema operativo irá realizando escrituras en diversas partes del disco, creando archivos, actualizándolos, y también eliminándolos. Esto irá provocando que el espacio realmente utilizado vaya difiriendo del espacio utilizado por el archivo de disco de QCOW2. Pasado un tiempo, digamos que nuestro sistema operativo está ocupando 12GB, sin embargo el tamaño del disco del QCOW2 puede ser de, por ejemplo, 29GB.

A veces nos topamos conque queremos dar de baja ya a una máquina virtual, no le usaremos más (o al menos durante mucho tiempo) . Y queremos guardar un respaldo de ella. Tomemos el ejemplo anterior: definitivamente sería mejor almacenar solamente el espacio utilizado (12GB) que no los 29GB que actualmente tiene el QCOW2. Nos ahorramos 17GB de espacio.

Aunque existen muchas técnicas para reducir el tamaño del QCOW2, hoy experimenté con una de ellas que consiste en utilizar el comando virt-sparsify.

virt-sparsify en principio fue concebido como un comando que llena de 0 los espacios declarados como vacíos en un disco. Al llenarse de 0, puede aprovecharse esos 0 para comprimir todo ese espacio conteniendo la misma información. De esta forma logramos librarnos de contenidos escritos en disco que ya no nos son de valor (porque ya fueron declarados como borrados).

Para ellos utilizamos:

[root@backups respaldos]# virt-sparsify mivm.qcow2 --compress mivm-new.qcow2

Lo que hará será leer los contenidos de la VM ‘mivm.qcow2’ y los escribirá hacia la salida ‘mivm-new.qcow2’, comprimiendo sus contenidos.

En mi caso fallaba al iniciar indicándome que no había espacio en TEMPDIR, pues TEMPDIR por defecto es /tmp/, lo que hice fue, antes de volverlo a ejecutar cambié el contenido de la variable TEMPDIR hacia /respaldos/tmp ya que en la partición donde está /respaldos/ yo sí tenía espacio suficiente:

mkdir /respaldos/tmp
export TEMPDIR=/respaldos/tmp

y volví a repetir la operación. Ten en cuenta que tengo un disco duro con varios TB disponibles montado en /respaldos/, es por eso que opero con /respaldos/

El proceso puede tomar tiempo, incluso horas, depende del disco duro, y al finalizar podemos probar que mivm-new.qcow2 pueda ser leído

guestmount -a mivm-new.qcow2 -i /mnt
ls /mnt
umount /mnt

Si efectivamente podemos leer los contenidos, entonces ya con tranquilidad podemos borrar el qcow2 original (mivm.qcow2 en mi caso).

Por último: ¿qué hace guestmount? Es un comando muy interesante y que merece su propio post aparte. guestmount es un comando que te permite “abrir”, montar, un disco qcow2 y poder ver sus contenidos. En este caso lo utilicé para simplemente validar que el disco duro se podía acceder y ver sus contenidos (lo monté en /mnt), pero sirve para mucho más, por ejemplo un cliente al que no le arranca la red, puedes apagar la máquina (guestmount y virt-sparsify deben utilizarse con la VM apagada!), y puedes montar el disco y corregir cualquier falla en la configuración de la red que el usuario necesite, y entonces desmontar el disco montado con guestmount y volver a arrancar la VM.

Notas para instalar KVM en CentOS-7

Estas notas son para mi, que las entiendo, sin embargo posiblemente te sirvan también si necesitaras instalar KVM en CentOS-7.

  • Reviso en el BIOS que tenga activada la opción de virtualización: A veces está oculta/a veces no está. Si estuviera y estuviera desactivada, el sistema correrá en modo emulación (lento) y dirá solamente QEMU y no QEMU/KVM
  • En mi caso me falló el arranque con EFI, desde el BIOS desactivé el EFI para que arrancara la flash. Esto puede no aplicar a todo el mundo.
  • Bajé el CentOS-7 liveCD
    • Configuré teclado
    • Configuré la red
    • Particioné el disco (/boot – 500M, / para el resto del disco). (Puedes particionarle para usar LVM, ahora no es el caso en este rapido tuto)
    • Al inicial la primera vez le dije que no al kdump
    • Deshabilité el SELINUX en /etc/sysconfig/selinux
    • apagué el firewall: systemctl disable firewalld , systemctl stop firewalld
    • Actualicé el sistema (yum update)
    • Instalé los siguientes paquetes y arranqué los siguientes servicios:
      • yum install virt-manager
      • yum groupinstall “Virtualization host”
      • systemctl start libvirtd
      • systemctl enable libvirtd
    • Creé un bridge en el virt-manager, este bridge tiene a la tarjeta de red de mi servidor como componente de él, pero no le “activé ahora” al bridge pues te quedas sin conectividad.

      Sólo le puse onboot y ya. Fíjate en lo marcado en amarillo en la imagen:

      Selección_085

      • Reinicié para que el bridge funcione.
    • De ahora en adelante toda máquina virtual la debo crear conectándose al bridge br0 para que esté en la misma conexión de la red.
    • Al crear las máquinas debo veificar que tanto el disco como la tarjeta de red sean de tipo “virtio” si no lo son, podrá ser potencialmente menos rápido el trabajo el sistema.

Nota lo que he marcado en amarillo (lo del writeback es solamente si tienes un raid por hardware con respaldo por bateria):

Selección_086

Selección_087

Usando imágenes base para clonar rápidamente en KVM

Esto lo encontré hace tiempo en el sitio de KVM y le probé hace varios meses y funciona de maravilla!

Mira, supón eres docente (podrías ser cualquier otra cosa), y tienes que preparar 20 máquinas virtuales para que tus estudiantes hagan una tarea determinada.  Lógicamente como ya tienes un poco de experiencia sabes que las máquinas deben quedar igualitas, para que todos tengan que realizar las mismas tareas y en el peor escenario tengan los mismos errores/omisiones/tareas por resolver.

Cómo lo haces? con virtualización claro está! Virtualización es maravillosa.. crear la máquina es facilito. Con KVM lógicamente! porque usas Software Libre.

Cómo creas las 20 máquinas virtuales? Ahí está el kid del asunto hoy. Porque además seguramente serán 20 máquinas virtuales que luego de un par de días u horas eliminarás porque habrán hecho su tarea.

Opción 1: Crear las 20 máquinas una a una, estilo: seguir el wizard, el procedimiento de instalación de CentOS, 20 veces.. es difícil eh? Te pasarás al menos unas 4 ó 5 horas instalando las 20 máquinas.

Opción 2: Crear e instalar una máquina virtual, dejarla bien instaladita.. y luego clonarla 19 veces. Es una opción válida, buenaza! Pero igual la clonación toma tiempo, aproximadamente toma 1 minuto clonar 1 GB de disco. Por tanto si creaste una máquina de 20GB, cada máquina clonada te tomará no sé, digamos 20 minutos. Pero claro es más fácil pues ya no hay que pensar mucho, simplemente preparaste la primera máquina y luego clonaste el resto…

Opción 3: Usar disco base.

Esto es lo que quiero ver ahora. Y lo que me facilita durísimo el trabajo:

Imagínate crees una máquina, tal y como la opción 2, y la dejes listita, tuneadita, tal y como quieres que sean todas. Y luego le apagas y no le usas más.

Este será el disco de respaldo. Este disco lo usaremos como base para leer de él todo lo que requiramos.

En base a este disco, creamos ahora 20 discos, uno por cada una de las máquinas virtuales que necesitemos, estos serán utilizados solamente para almacenar los cambios que dentro de esta máquina ocurran! Estos discos estarán enlazados al disco base que no se cambiará para nada. Se usará solamente para leer lo que no haya cambiado.

Por ejemplo digamos que en la máquina 1 requiero leer la lista de usuarios, esta está en /etc/passwd, esta lista será transparentemente leída del disco base, pues no está modificado el archivo.

Si en la máquina 2 requiero leer la lista de usuarios, igual veré /etc/passwd y este lo leeré del disco base pues no ha sido modificado.

Ahora, si en la máquina 1 agrego un usuario , se modificará /etc/passwd y esta modificación será almacenada en el disco de los cambios. Este disco pertenece solamente a máquina 1.

Y si en máquina 2 requiero eliminar un usuario, /etc/passwd aparecerá almacenado en su disco de cambios y solamente maquina 2 le verá.

A ver aqui una imagen feíta de cómo es la cosa, el disco base y dos discos llamados cambiosvm1 y cambiosvm2, ambos discos son los que leen las máquinas VM1 y VM2

VM2<—>CAMBIOSVM2<——-(DISCOBASE)—–>CAMBIOSVM1<—>VM1

En la máquina VM1: Si leo algo, le busco en CAMBIOSVM1, si no está, le busco en DISCOBASE. Si quiero escribir algo, modificarlo, eliminarlo, agregarlo, lo agrego al disco CAMBIOSVM1

Lo mismo para VM2: Si quiero modificar algo, lo hago en CAMBIOSVM2, si quiero leer algo busco en CAMBIOSVM2, si no aparece es que estará en DISCOBASE.

DISCOBASE no se toca. Si le tocas, arruinas todo pues CAMBIOSVM1 y CAMBIOSVM2 dependen de que discobase se mantenga igualito.

El tamaño de CAMBIOSVM1 y CAMBIOSVM2 es simplemente lo que vayan almacenando. Y serán los discos de las máquinas virtuales correspondientes, tendrás 20 disquitos cada uno almacenando cada cambio de cada máquina virtual.

Crear estos discos, es facilito y rápido, toma menos de 5 segundos.. así que crear 20 máquinas virtuales tomará un minuto o dos.. y ya.

Creando los discos:

Supongamos que tengo ya el disco base, que se llama base.qcow2

Ahora quiero crear un disco de cambios llamado estudiante1.qcow2, pongo:

qemu-img create -b base.qcow2 -f  qcow2   estudiante1.qcow2

el disco “estudiante1.qcow2” es el que almacenará los cambios para la máquina virtual de estudiante1.

Ahora hago lo mismo para estudiante2, estudiante3.. y así hasta estudiante20

Luego creo las 20 máquinas virtuales, cada una haciendo uso de su propio disco “estudianteX.qcow2” (1<=X<=20).

Todas quedarán igualitas. Lógicamente al finalizar el rtabajo puedo eliminar estos disquitos y ya… y puedo dejar la base para otros experimentos posteriores.. crear y eliminar máquinas será facilito y consumirá poquísimo disco.

Comandos interesantes:

qemu-img info estudiante1.qcow2

te dará información del disco, verás que usa un backend llamado base.qcow2, mira qué cosa más curiosa y es que el tamaño del disco no es 10G como la base, sino de 56K o así.. porque solamente almacenará los cambios:

image: estudiante1.qcow2
file format: qcow2
virtual size: 10G (10737418240 bytes)
disk size: 56K
cluster_size: 4096
backing file: base.qcow2 (actual path: base.qcow2)

Full virtual vs Paravirtual

En la lista de CentOS en Español, surgió un hilo muy interesante el mes pasado sobre sistemas de virtualización para CentOS, derivó a un tema sin salida de sistemas de virtualización que no son para CentOS, luego regresó al tema.. un usuario de la lista habló muy bien de Xen y a mi me gusta Xen y uso Xen desde fines del 2004! Pero igual he visto y probado que KVM es bueno, y en la lista puse un breve escrito sobre cómo comprender que KVM es igual de bueno pues usa algunas técnicas de paravirtualización en algunos dispositivos, aquí va (le he corregido algunas faltas y aclarado cosas que me quedaron en el aire por el apremio):

Dijo el otro usuario (y luego le respondo yo):

xen me parece mejor, porque soporta paravirtualizacion, si tienes un
micro con soporte V-XM, puedes correr incluso un SO instalado y
funcionando en otro disco duro. Ademas de poder direccionar hardware
para un huesped en particular.
No soy experto ni nada pero lo que he leido acerca de xen dan mas que ganas.
Pero tambien hay que ver que quieres virtualizar, porque una cosa es
un SO completo y otra es virtualizar tu propio SO para hacer como
jaulas clonando tu instalacion para otros servicios.
Es verdad lo que indicas y lo apruebo. La paravirtualización es
maravillosa. Y me encanta Xen y le usé mucho tiempo, y le usaré si es
necesario.
Sin embargo, la brecha entre sistemas full virtualizados y paravirtuales
se ha ido reduciendo a casi nada. Y me explico (con simples palabras):

La full virtualización (kvm por ejemplo, xen también) le asigna un slice
de tiempo de procesador a la máquina virtual, esta máquina le usa
directamente al procesador durante este periodo, y le guste o no, a
través de herramientas incorporadas en el procesador, se le saca a la
máquina del procesador y se le devuelve el control al hospedero.

Ventajas: no hay que emular el procesador, no hay que usar llamadas al
hospedero por parte de los invitados para acceder al procesador. Es
acceso directo al procesador! Maravilloso!!!

Sin embargo la full virtualización tenía algunos inconvenientes que no
tenía la paravirtualización (xen por ejemplo soporta paravirtualización)
y es que para el resto de dispositivos (red, disco, ram) había que 
emular para que las máquinas virtuales full virtualizadas accedieran
a ellos. En pocas palabras: Emulación=lentitud.

Entonces algunos (yo incluído) siempre decíamos que la full
virtualización, tal y como se usaba en principio no traía ventajas, o
mejor aún, digamos que la paravirtualización era más rápida.

Por qué? porque en la paravirtualización el invitado está programado
para ejecutar llamadas pre-establecidas al hospedero para realizar
ciertas labores hacia dispositivos. Por ejemplo, no accede directamente
a la tarjeta de red, sino que invoca a llamadas preestablecidas
(funciones) en el hospedero y este le hace la comunicación de red. Lo
mismo al disco, lo mismo a la ram y a otros dispositivos menos
importantes ahora.

Entonces no había que emular hardware.. simplemente llamadas, y el
hospedero a través de su sistema operativo y drivers específicos,
realizaba la labor de comunicación con la red, disco, etc... esto era
rapidísimo, tan rápido como acceder desde el hospedero mismo.

Lo único que podía ralentizar un poquiiiiiiiiiiiiiiiiiiiito era el hecho
de la llamada misma.. pero era algo negligible.. es algo que impacta poco.

Es por eso que decíamos:
-> paravirtual=rapido,
-> full virtual=rapido el procesador, emulado el resto.

Por qué no se puede hacer una mezcla? Qué tal algo full virtual para el
procesador (que es lo que es a la final) y paravirtual el resto? Bueno,
pues "porque los sistemas operativos privativos no pueden ser
modificados" pensaban algunos.. y si no puedo incorporar las llamadas
pre-establecidas entre el invitado que corre un sistema operativo
privativo y el invitado con KVM por ejemplo.. pues no puedo hacer
paravirtualización!

Full virtualización sin embargo no requiere de modificaciones en el
SO con la finalidad de que corra como máquina virtual. Esto lo hacía 
útil para SO privativos. Pero lento por otro lado.

Ahh.. entonces full virtualización para los privativos y
paravirtualización para los que pueden ser modificados (SL)? En
principio algunos pensaron así.

Hasta que alguien sacó a la luz una idea: Pensemos que tengo windows, y
que hago un driver de red llamado digamos virt-net que ese driver, se
incorpora como todo driver de windows al kernel que corre.. y este
driver tiene las llamadas pre-establecidas para comunicarse y
enviar/recibir las peticiones de red con el hospedero en KVM por ejemplo.

Además hago un driver llamado virt-block que igual se comunicará con el
hospedero para enviar/recibir las peticiones de disco. Y hago uno
llamado virt-balloon que se ocupará de mantener las llamadas
pre-establecidas para comunicarse con el hospedero y atender las
llamadas a las operaciones con la ram (fundamentalmente reducir/ampliar
la ram en uso del invitado).

Ah bacán! Todos esos drivers serán drivers "paravirtuales" y sustituirán
la necesidad de drivers "emulados". Qué hay en tu mente?
paravirtual=rápido, emulación=lento.

Entonces qué logro? rapidez! Un sistema full virtual para acceso nativo
y directo al procesador + drivers paravirtuales de red, disco y ram que
permiten acceso casi directo a estos recursos a través del hospedero..

Esto lo hace KVM:
- Al usar un SO Linux, estos ya vienen con los drivers paravirtuales, y
funciona rapidísimo el sistema.
- Al usar un SO tipo windows por ejemplo, le indicas a Windows que por
favor use un disco de drivers (virtio-win)
http://www.linux-kvm.org/page/WindowsGuestDrivers/Download_Drivers y
windows detectará tu tarjeta de red paravirtual, disco paravirtual y
balloon paravirtual. Para esto es necesario decirle al KVM antes de
comenzar a instalar que estos tres dispositivos serán de tipo virtio..
windows no verá disco al inicio, hasta que introduzcas el CD de drivers
y entonces ahi verá el disco PV, red PV, etc.

Rápido? rapidísimo, además de que hace latente una de las ventajas de la
virtualización que es la independencia de las máquinas virtuales del
hardware.. ellas no conocen el hardware bajo el que se ejecutan, sino
que quien sabe del hardware es elhospedero, esto facilita la migración
(cosa que también KVM hace) entre hardware, etc.

Para terminar insisto: KVM y Xen son los dos sistemas de virtualización
más importantes en nuestro mundillo de CentOS.. también puedes usar LXC,
qemu, virtuozzo y otras cosillas, pero fundamentalmente kvm y xen son
los duros. Proxmox y todos esos paneles que hablan, simplemente son
paneles que manejan y facilitan el uso de los sistemas de virtualización
KVM, Xen, LXC, virtuozzo... tal y como virt-manager o virsh lo hacen a
su forma. Pero para mi me parece importante comprender lo que hay
debajo, antes de saltar a usar un panel  y ya.

saludos
epe

Curiosidades de KVM: KSM

bueno: este tema es buenísimo, me ha encantado de kvm… todo con mesura, pero es una excelente idea.

KSM viene de Kernel Samepage Merging (mezcla de las mismas páginas del kernel).

La idea es que cuando virtualizamos, muy posiblemente las máquinas virtuales que corremos, corren bajo el mismo sistema operativo, por lo tanto la posibilidad de que las memoria de estas máquinas estén manteniendo una copia similar de ciertas páginas de memoria es altísima.

Dicho de otra forma: supongamos que tenemos dos máquinas virtuales: centos1 y centos2, ambos corriendo centos-6.2 por ejemplo. La posibilidad de que ciertas partes de memoria de la máquina “centos1” tengan la misma información que la máquina “centos2” es alta, porque posiblemente corren el mismo kernel, quizá procesos similares (mysql, dovecot, sendmail, postfix, apache, etc)..

¿Qué ventajas nos permite esto? Correr varias máquinas virtuales aprovechando al máximo la memoria, pues no se repetirá la misma información que se almacena en la memoria, sino que solamente se mantiene una copia.

Hoy realicé una pequeña prueba, que fue crear 10 máquinas virtuales de CentOS-6, clonándolas por supuesto para hacer el proceso rápido, y luego arrancarlas.

Primero verifiqué que mi kernel del hospedero tuviera kvm activado (el de los invitados deberían tenerle también):

egrep -i ksm /boot/config-2.6.32-220.4.1.el6.x86_64
CONFIG_KSM=y

Entonces a cada máquina virtual le asigné 900MB de RAM, por probar, podría haber usado otro valor. Y luego las arranqué.

Mi sistema hospedero tiene 3GB de RAM solamente, no más. En Xen para CentOS-5 no hubiera podido usar más que 3GB para asignar por máquina por ejemplo hubiera podido correr 2 máquinas de 1gb cada uno y una de 512mb (porque al hospedero en xen hay que dejarle un poco de memoria).

Ahora, en kvm, acabo de arrancar las 10 máquinas virtuales, cada una de 900MB de RAM. Esto sumaría 900MB*10maquinas= 9GB verdad? Pues las máquinas arrancadas consumen menos de 2GB en total!!! No lo crees? mira:

Esto fue antes de arrancar todas las máquinas:

[root@dom0 ~]# free -m
total used free shared buffers cached
Mem: 2982 2908 74 0 2584 32
-/+ buffers/cache: 290 2691
Swap: 511 6 505

En suma, el hospedero está usando aproximadamente 290MB de ram nada más.

Esto es luego de arrancadas las 10 máquinas de 900MB de RAM cada una!!:

[root@dom0 ~]# free -m
total used free shared buffers cached
Mem: 2982 2261 720 0 0 21
-/+ buffers/cache: 2239 742
Swap: 511 64 447

En suma, el hospedero ahora usa 2.2G

por tanto el incremento en el uso de la ram entre el primer escenario (sin máquinas virtuales arrancadas) y el segundo (con las 10 máquinas virtuales arrancadas) es de menos de 2GB.

si miras dentro de una máquina virtual, esta reporta que está usando 900MB.. no menos…

una forma de verificar que el ksm está en efecto haciendo su función es ver la cantidad de páginas ksmeadas:

[root@dom0 ~]# cat /sys/kernel/mm/ksm/pages_sharing
362484

Ahi está, 362mil484 páginas ksmeadas.

Estoy impresionado, pero hay que ser cauteloso, por qué tan bajo consumo? Porque todas las máquinas son iguales y están haciendo exactamente las mismas funciones, en este caso todas las máquinas están simplemente encendidas, realizando NADA .. esperando a que yo me conecte por ssh y nada más.

No hay que ser abusador como en este escenario en el cual arranqué tantas máquinas, leí en algún lugar, luego lo documento, que redhat sugería no se sobrevendiera la memoria por más de un 10% porque a la final las máquinas pueden comenzar a realizar labores diversas y no se pueda hacer uso del KSM al no haber muchas páginas similares.

Aquí las 10 máquinas corriendo:

Aquí las 10 máquinas virtuales corriendo
Aquí las 10 máquinas virtuales corriendo

Un comentario adicional, ahora acabo de verificar la ram y no supera los 875mb de uso!

[root@dom0 ~]# free -m
total used free shared buffers cached
Mem: 2982 949 2032 0 15 58
-/+ buffers/cache: 875 2106
Swap: 511 61 450

No lo sé, pero la idea es que puede decrecer, pero fíjate.. puede crecer también su uso, así que cautela ok?

Activarlo es medio raro. Yo realmente lo que hago es editar esta variable:

vi /etc/sysconfig/ksm

KSM_MAX_KERNEL_PAGES=0

luego reinicio el servicio ksm y en teoría debe funcionar.