miércoles, 17 de marzo de 2010

KVM y multiples interfaces TUN/TAP

He estado ensayando el hipervisor KVM, una de las razones que me llevaron a probar este hipervisor, es que aprovecha las bondades de virtualización que ofrecen los procesadores modernos como mi nuevo Intel I7.

Hasta ahora ha demotrado tener un buen desempeño, y hay que destacar las innumerables opciones de administración, como la capacidad de asignar un número fijo de procesadores, el uso de imágenes qcow, etc.

Un problema con el que tuve que lidiar, es el uso de interfaces virtuales que den acceso directo a la red donde está conectada la tarjeta del equipo anfitrión.

Resulta que QEMU ofrece muchas opciones para el trabajo en red, el modo usuario (parecido a las interfaces NAT que ofrecen otros productos), el uso de dispositivos TUN/TAP, y una alternativa muy interesante llamada VDE.

Hay mucha documentación en la red sobre como hacer correr estas opciones, y me parece innecesario volver a copiar lo que otros han escrito (y de donde he aprendido).

Lo que quiero registrar es como configurar diferentes interfaces en el sistema invitado (guest) y ubicar dichas interfaces en diferentes puentes (bridges).

Bueno, lo primero que hay que hacer es configurar el puente de red.

El comando `brctl`, permite crear este tipo de dispositivos. Basta hacer algo así como:

# brctl addbr dmz
# brctl addbr internal

Hemos creado dos puentes para conectar nuestros dispositivos TUN/TAP. Ahora hay que añadir la interfaz física (eth0, eth1) a cada uno de los puentes.

# brctl addif dmz eth0
# brctl addif internal eth1

Aquí viene la parte interesante, para poder configurar KVM con un dispositivo TUN es necesario añadir la siguiente línea a la llamada a qemu.

-net nic,model=virtio,macaddr=00:16:3e:11:10:5b -net tap,ifname=internal0,script=/home/virtual/ltsp/ifup.internal

Ahora bien, la primera definición a -net crea una interfaz virtual con los drivers de paravirtualización virtio (si esto no suena muy facil de digerir, digamos que mejoran el desempeño y el acceso desde la máquina anfitrión a los dispositivos de entrada y salida), definir la MAC de manera estática es muy importante, sobretodo si se va a correr equipos Linux donde cada nueva MAC incrementa el número de la interfaz (uno puede terminar escribiendo cosas locas como ifconfig eth45), para crear la MAC se puede usar el script definido en alguna página de RED HAT, aquí va:


#!/usr/bin/python
# macgen.py script to generate a MAC address for Red Hat Virtualization guests
#
import random
#
def randomMAC():
mac = [ 0x00, 0x16, 0x3e,
random.randint(0x00, 0x7f),
random.randint(0x00, 0xff),
random.randint(0x00, 0xff) ]
return ':'.join(map(lambda x: "%02x" % x, mac))
#
print randomMAC()

La segunda línea pide a QEmu crear un dispositivo TAP y pasarlo como el argumento $1 al script de inicialización de la interfaz. El argumento ifname además define el nombre de dicha interfaz. Aquí va una copia del script.

#!/bin/bash

set -x
switch=dmz

if [ -n "$1" ] ; then
ip link set $1 up
sleep 0.5s
brctl addif $switch $1
exit 0

else
echo "Error: no interface specified"
fi

Con esto podemos tener una máquina invitada corriendo su dispositivo de red como si estuviera conectada a la misma red del dispositivo anfitrión.

Para añadir una segunda interfaz, uno podría estar tentado a hacer algo así como:
-net nic,model=virtio,macaddr=00:16:3e:11:10:5b -net tap,ifname=internal0,script=/home/virtual/ltsp/ifup.internal -net nic,model=virtio,macaddr=00:16:3e:11:10:5c -net tap,ifname=dmz0,script=/home/virtual/ltsp/ifup.dmz

Pero de este modo, las tarjetas quedan ubicadas en la misma interfaz, y aunque QEmu crea el segundo TAP parece que no lo conecta con la segunda interfaz definida. La solución es muy sencilla (aunque me llevó mucho tiempo encontrarla), se debe definir cada interfaz en una vlan diferente, como aparece a continuación.

-net nic,vlan=1,model=virtio,macaddr=00:16:3e:11:10:5b -net tap,vlan=1,ifname=internal0,script=/home/virtual/ltsp/ifup.internal -net nic,model=virtio,macaddr=00:16:3e:11:10:5c -net tap,ifname=dmz0,script=/home/virtual/ltsp/ifup.dmz

Hasta pronto!

1 comentario:

  1. Interesante amigo lo has hecho editando el xml que se genera una VM virsh edit DOMAINNAME
    Saludos,,

    ResponderEliminar