Virtualización fácil con Xen3

Arco

Esta receta no se si tendrá muchas aplicaciones "domésticas", en ella vamos a tratar de crear n máquinas virtuales en una única máquina física. Esto permitirá crear (por ejemplo) n servidores, cada uno con unos servicios determinados en una misma máquina física. Con ello se consigue (entre otras cosas) proteger unos servicios mas "críticos" de otros más "vulnerables" (lo que pase en una máquina es independiente al resto).

Qué es Xen

Xen es un sistema de virtualización similar a VM-Ware o QEmu, pero tiene una difirecia bastante notable: mientras que VM-Ware degrada alrededor de un 30% el rendimiento de la máquina emulada, Xen lo hace entre un 2% y un 3% (es increible pero cierto!), pero claro... no va a ser todo de color de rosa: es necesario parchear tanto el núcleo del sistema real como el núcleo de los sistemas que se emularán (esto debería impedir ejecutar sistemas hasefroch 95, XP, etc. bajo un linux ya que no podemos parchear, a priori, el núcleo de estos sistemas privativos... se comenta por ahí que existen estos parches, aunque yo no los he visto).

¿Cómo consigue esto?, en realidad Xen no es una máquina virtual, sino un hypervisor para núcleos linux de la rama 2.6, cuando se inicia un núcleo parcheado con Xen antes de nada aparecerán unos mensajes que empiezan con "[XEN]:", así se muestran los mensajes del hypervisor, también se puede dirigir la consola de Xen a un puerto serie concreto o compartir una cosola con el sistema principal. Después podremos cargar más núcleos como linux, FreeBSD o Plan9.

Para gestionar todos los sistemas que se quieran ejecutar en una máquina, Xen divide el sistema en dominios (o dom), el dominio 0 (o Dom0 a partir de ahora, denominado asi por ser privilegiado o priviledge) es el sistema real y será el encargado de lanzar/administrar el resto de los dominios (o genéricamente DomU o unpriviledge a partir de ahora,). La comunicación entre dominios se realiza mediante backends de hotplug, esto permite la comunicación entre dominios con interfaces de red virtuales (o vif's), discos compartidos, etc.

Los discos de los dominios serán imagenes de sistemas de ficheros ext2, ext3 o reiser. Se pueden crear con dd y montar como dispositivos loop (esto lo veremos más adelante) o incluso usar particiones reales.
La conexión de los dominios a una red se puede hacer de diversos modos: bridged, NAT, etc.
Las versiones de Xen a partir de la 3 soportan virtualización SMP en sistemas SMP. Ninguna versión de Xen liberada hasta ahora soporta librerías TLS, es necesario "deshabilitarlas", no he encontrado un método Debian-like en ninguna parte para hacerlo, los chicos de Xen sugieren lo siguiente (que es lo que he hecho yo):

$ cd /lib
$ mv tls tls.disabled

Instalación con paquetes binarios

La forma más cómoda de instalar Xen es descargarse los paquetes binarios: xen-3.0.0-install-x86_32.tgz o xen-3.0.0-install-x86_32p.tgz (incluye soporte PAE). Estas distribuciones traen de serie el soporte SMP. Ahora símplemente debemos descomprimir el paquete y ejecutar el script de instalación:

$ unp xen-3.0.0-install-x86_32.tgz
$ cd xen-3.0.0-install
# ./install.sh

Este script copiará los ejecutables necesarios, las bibliotecas de python, el hypervisor y los scripts de inicio. Sólo nos queda configurar Grub y corregir unos problemas con este tipo de instalación.

Problemas serios y soluciones cutres en la instalación

Bien, esos problemas "serios" me han ocurrido en una Debian unstable (tenedlo en cuenta si usáis Ubuntu o alguna otra), algunos ejecutables no funcionan correctamente por no encontrar una serie de librerías: libssl.so.4, libcrypto.so.4 y libcurl.so.4. La solución cutre que he encontrado ha sido la siguiente: enlaces débiles de las librerías que vienen en Debian (más nuevas) a las que me pide el programa:

# cd /usr/lib
# ln -s libssl.so libssl.so.4
# ln -s libcrypto.so libcrypto.so.4
# ln -s libcurl.so libcurl.so.4

También puede ocurrir que los programas python den error al importar algunos módulos, esto también se puede corregir de forma cutre fácilmente:

# cd /usr/lib
# cp python/* python2.3/

O también podríamos haber creado enlaces simbólicos (más mejor...). El problema está en que el script de instalación deja las bibliotecas de python en /usr/lib/python y nuestro intérprete las busca en /usr/lib/python2.3.

Un problema que ha aparecido en esta versión de Xen (coincidiendo con la sustitución de hotplug por udev) se debe a que aunque se necesita el módulo loop éste no se carga, es necesario cargarlo antes de iniciar xend. Para ello haremos lo siguiente:

# echo "loop" >> /etc/modules

Nota: cuando se carga el módulo, por defecto no deja montar más de 8 dispositivos loopback, esto puede ser problemático en sistemas donde querámos montar más de 4 dominios y no queramos usar particiones reales. Podemos pasar un parámetro a la carga del módulo:

# modprobe loop max_loop=64

Finalmente, la instalación añade dos servicios nuevos en init.d pero, en cambio, no actualiza los enlaces simbólicos de los servicios según el runlevel, así que lo hacemos nosotros y en paz:

# update-rc.d xend defaults
#update-rc.d xendomains defaults

Con esto, la próxima vez que arranque el sistema lo hará con el módulo cargado, xend inciará correctamente y podremos lanzar todos los dominios que necesitemos.

Configurar GRUB

Bueno... por si no lo he dicho: es obligatorio Grub... así que migraros los que aún sigáis usando cargadores obsoletos... :-P

En este paso, tendréis que tener xen-3.0.0.gz en /boot, al igual que las tres imagenes del kernel (sólo privilegiado o -xen0, sin privilegios o -xenU y uno capaz de funcionar de ambos modos o -xen). Muy importante es que no ejecutéis update-grub porque os va a añadir las imágenes parcheadas al menú de arranque y esas opciones no van a ser válidas. Las nuevas opciones las añadiremos "a pelo":

title Xen 3 Linux, Kernel 2.6.12-xen
root(hd0,4)
kernel /boot/xen-3.0.0.gz dom0_mem=262144
module /boot/vmlinuz-2.6.12.6-xen root=/dev/hde5

Empecemos con las explicaciones... lo primero que las opciones root serán distintas en vuestro sistema, mirad la de las otras opciones de arranque que tenéis y poned lo mismo.
También podemos especificar una imagen initrd, para ello solo tenemos que añadir una nueva entrada tal que:

module /boot/initrd.img-2.6.12

De todas formas yo no la uso y me funciona.
Otra cosa, dom0_mem establece la cantidad de memoria física que verá el Dom0, este dominio no lo usaremos para ofrecer servicios, símplemente para gestionar el resto de dominios, por tanto, no gastéis demasiada memoria en él, yo le he asignado 256Mb que para lo que se usa ya va bien.

Pues nada, ya sólo nos falta reiniciar el sistema y seleccionar ese arranque, si todo va bien veremos los mensajes del hypervisor y después los del arranque normal del linux, si esto es así... ¡ya tenemos el Dom0 funcionando!.

Compilación de Xen3

Puede ser que queramos meternos de lleno en Xen, ya sabéis: compilar es más bonito, pero tened en cuenta una cosa, se crean 3 núcleos diferentes: -xen (funciona como Dom0 y DomU), -xen0 (funciona sólo como Dom0) y -xenU (funciona como DomU, tiene algunos drivers menos y ocupa 30% menos); así pues el núcleo se compilará 3 veces cada vez, si os apetece entonces vamos al tema:

Necesitaremos los paquetes necesarios para compilar el linux, a parte, también tendremos que tener instalado:

  • zlib1g-dev
  • rubber (para instalar latex de "rebote")
  • python-dev
  • gs-common
  • transfig
  • tetex-extra
  • python-twisted

Si hace falta algún paquete más, por favor, comunicadmelo. La compilación es bastante rollo porque si te falta alguno de estos programas se para y cada vez que se hace un make empieza desde el principio porque hace clean antes de empezar.

Ahora necesitamos el archivo xen-3.0.0-src.tgz, en la página de XenSource no está el link directo, hay que pedirlo por mail pero os lo dan automáticamente al hacerlo. Lo que si os viene es un archivo torrent para descargar los mismos ficheros, intentad esta opción si pasáis de dar vuestro mail por ahí.

Una vez tengamos el fichero, lo descomprimimos:

$ unp xen-3.0.0-src.tgz
Y finalmente compilamos:

$ cd xen-3.0.0
$ make KERNELS=linux-2.6-xen world

Esto compilará la documentación y tres núcleos parcheados: version-xen0, version-xenU y version-xen: uno para el Dom0, otro para el DomU y finalmente uno que puede funcionar de ambos modos (este el que usaremos para todo...). Los parches tienen un problema: vienen pensados para una versión concreta del linux, no sirve cualquiera de la 2.6, en este caso hace falta la 2.6.12, pero tranquilos porque el mismo script se descargará los fuentes del núcleo apropiado y lo parcheará debidamente... más fácil imposible!

Una vez compilado lo instalamos (ya como root):

# make install

Y ahora como antes, sólo nos queda configurar Grub.

Parámetros de configuración de núcleos parcheados

Supongamos que queremos establecer/modificar valores en el núcleo: inhabilitar módulos, añadir nuevos, etc. Podemos utilizar objetivos normales como los vistos en la receta "Configurar, parchear, cacharrear y compilar un linux FÁCILMENTE" de una forma bastante simple:

$ cd xen-3.0.0
$ cd linux-2.6.12-xen0
$ make ARCH=XEN menuconfig

También puede ser más cómodo usar make-kpkg, en cuyo caso:

$ make-kpkg --arch xen kernel_image

Los archivos de configuración también se gestionan de igual manera, aunque este núcleo tendrá nuevos parámetros añadidos por el parche de Xen.
Hay que tener en cuenta que esto funcionará una vez compilado como se ha explicado porque la descarga y parcheo del núcleo se habrán realizado automáticamente, en caso contrario hay que hacerlo "a mano".

Creación de dominios

Bien... ¿cómo creamos DomU?... en Debian existe un paquete llamado xen-tools con unos scripts bastante chulos que lo hacen todo automático, explicaremos su uso más abajo; ahora veremos como hacerlo a la forma "tradicional".

Los dominios se describen con pequeños archivos de configuración situados en /etc/xen/ que especifican aspectos básicos como el disco, las interfaces de red, el número de procesadores virtuales, etc. Nosotros vamos a crear un dominio cuyo disco va a ser un archivo (para manejarlo luego con más comodidad), para ello creamos el fichero y le damos formato. Los alojaremos en /var/xen/domains/{nombre_dominio}, no por obligación, sino por comodidad:

cd /var/xen/domains/xentest/
$ dd if=/dev/zero of=disk.img bs=1k seek=2048k count=1
# mkfs -t ext3 disk.img

Con esto hemos creado un archivo de 2GB que contiene un sistema ext3, lo podemos montar para "rellenarlo" de una forma fácil:

# mount -o loop disk.img /mnt/test
# cp -ax /{root,dev,var,etc,usr,bin,sbin,lib} /mnt/test
# mkdir /mnt/test/{proc,sys,home,tmp}

Esto copiará nuestro sistema actual dentro de ese "sistema virtual", además, crearemos los directorios necesarios para la adecuada ejecución del sistema. Ya podemos desmontar /mnt/test, ahora crearemos otra imagen para el swap:

$ dd if=/dev/zero of=swap.img bs=1k seek=128k count=1
# mkswap swap.img

Con esto tendremos un archivo de intercambio de 128Mb, ahora solo nos queda crear el archivo de configuración (xentest.cfg por ejemplo):

kernel = "/boot/vmlinuz-2.6.12.6-xen"
memory = 128
name = "xentest"
disk = ['file:/var/xen/domains/xentest/disk.img,sda1,w','file:/var/xen/domains/xentest/swap.img,sda2,w']
root = "/dev/sda1 ro"
dhcp = "dhcp"
nics = 1

Como véis, especificamos que núcleo (accesible por Dom0) y cuanta memoria dispondrá. También se especifica el número de interfaces de red (nics) y cómo obtendrá la IP, tambíen se puede especificar directamente:

ip = "192.168.0.2"

Este archivo lo pondremos en /etc/xen/ y podremos lanzarlo mediante:

# xm create xentest.cfg -c
Si Dom0 esta correctamente configurado, se habrá lanzado xend y xendomains al inicio, entonces se lanzará ese nuevo dominio, podemos
ver que se ha lanzado y se está ejecutando con el comando:
# xm list

Si queremos que un dominio se lance automáticamente al iniciar Dom0 sólo tenemos que crear un enlace simbólico del archivo de configuración en el directorio /etc/xen/auto:

# cd /etc/xen
# ln -s xentest.cfg auto/xentest.cfg

Creación de dominios con xen-tools

Debian dispone de dos paquetes relativos a Xen: xen y xen-tools. Es mejor no instalar el paquete xen porque va por la versión 2.0.6, además tampoco incluye los núcleos parcheados con lo que tendremos que compilarlo nosotros. Si podemos instalar y usar xen-tools, este paquete incluye scripts muy útiles para la gestión de dominios (creación, duplicado, etc.). Una vez instalado el paquete, podemos crear dominios fácilmente con la herramienta xen-create-image del paquete xen-tools, tan fácil como:

# xen-create-image --dir /var/xen --hostname xentest
Esto creará una Debian base en el archivo de imagen creando el archivo de intercambio directamente. Podemos especificar más parámetros, por ejemplo:

# xen-create-image --dir /var/xen --hostname xentest --fs ext3 --kernel /boot/vmlinuz-2.6.12.6-xen --mirror http://ftp.rediris.es/debian --dist sarge

Configurar la red de los dominios

En primer lugar, el Dom0 se configura como siempre, no hay que hacer nada "raro". Tenemos dos posibilidades para crear una red con los dominios: bridged o NAT. En modo bridge la interfaz del DomU tiene acceso a la red através del interfaz de Dom0. Podemos imaginarlo como si nuestra máquina real tiene varias IP's, una para cada dominio. En el modo NAT creamos una LAN entre los DomU, la salida a la LAN real se hace por la interfaz del Dom0 de forma similar a como funciona un red doméstica con varios equipos y un "routercillo" conectado a una ADSL.

Vamos con el modo bridge, en principio este modo es más sencillo pero tendremos que realizar un par de cambios a la configuración de nuestros DomU: principalmente usar el linux parcheado específicamente para DomU, modificamos la línea del kernel a cargar por la siguiente:

kernel = "/boot/vmlinuz-2.6.12.6-xenU"

Con esto, programas como dhcp-client nos darán menos problemas. En mi caso todos los dominios se configuran con DHCP, vuestra LAN debe tener dhcpd o similar funcionando. Todos los dominios tienen que tener la interfaz configurada en /etc/network/interfaces como sigue:

auto eth0
iface eth0 inet dhcp

Y en el archivo de configuración del dominio:

nics = 1
dhcp = "dhcp"

Xen configura la red mediante unos scripts (más o menos sencillos pero muy bien comentados) situados en /etc/xen/scripts, echad un vistazo a network-bridge que os explica como arrancarlo, básicamente:

$ /etc/xen/scripts/network-bridge start

Y ya arrancamos el dominio como antes, si todo ha ido bien, dhcp-client debe obtener una IP (también tenéis que tener dhcpd bien configurado en vuestra LAN...). Podéis probar a hacer pings a equipos incluso fuera de la LAN o desde otros equipos al dominio. Los pings hacedlos así:

$ ping -c 10 www.google.com

Por la sencilla razón de que los dominios, al compartir la terminal, no reciben señales como Ctrl+C y el ping se va a ejecutar indefinídamente hasta que no cerréis el dominio.

Conclusiones

En esta receta se han quedado muchisimas cosas por explicar, por ejemplo: configuración del núcleo parcheado con Xen, parámetros de Xen, nuevas opciones de núcleos parcheados, imagenes Xen en discos reales, en discos LVM, en discos NFS, migración en vivo de máquinas Xen (esto es impresionante), topología de red en dominios Xen, etc. Muchas de estas cosas son fáciles de realizar con la documentación en la mano, otras las estoy estudiando a ver si lo echo a andar completamente. Por ahora necesito ayuda con lo que ya he puesto aquí... gracias y que le aproveche a alguien... ;-)

Enlaces de interés

XenSource, página oficial

Perfect Xen setup on Debian/Ubuntu

Comentarios

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.

Problemas xen

Hola estoy intentando instalar Xen en mi maquina pero me aparece un problema cuando arranco el hypervisor en el grub, al intentar arrancar el servicio xend aparece una serie de "permisos denegados" y no me deja continuar.

Cuando lo he arrancado con el inicio interactivo y he negado que se ejecute "xend" a terminado de cargar bien pero al preguntar si xen estaba activado con la orden "/usr/sbin/xm list" me dice que no esta corriendo.

Alguien ha tenido este problema?
O alguien sabe como solucionarlo?

Gracias, salu2