seajob | 22 Diciembre, 2008 17:17
(Actualización: corrijo la MAC en el script que lanza las máquinas virtuales; tiene que empezar por 54:52:00)
Este artículo es una continuación de otro más genérico que escribí sobre las máquinas virtuales con KVM. Allí comentaba que me faltaba configurar la red de las máquinas virtuales para que pudiesen hablar entre ellas y así poder hacer una red de máquinas virtuales con las que hacer pruebas. Tras una temporada dándole vueltas a ratitos, he conseguido un poco más: que las máquinas virtuales sean accesibles desde cualquier máquina, virtual o no.
Antes de nada: nos van a hacer falta como mínimo los paquetes bridge-utils y uml-utilities, así que tardas en instalarlos.
En redes informáticas, un bridge es un dispositivo que conecta redes diferentes pero del mismo tipo, segmentándolas para reducir el tráfico en cada uno de los segmentos. Como siempre, tenéis Información para aburrirse en
http://es.wikipedia.org/wiki/Puente_de_red
Nosotros vamos a crear una red interna -la de las máquinas virtuales-, y a través de eth0 voy a comunicarla con el exterior.
Para esto lo primero que tenemos que hacer es crear en el arranque nuestro bridge, br0, añadir nuestra tarjeta ethernet eth0 al bridge, y configurar br0 como antes hacíamos con eth0. En concreto, primero tenía:
# The loopback network interface
auto lo
iface lo inet loopback
# The primary network interface
allow-hotplug eth0
iface eth0 inet dhcp
up /usr/local/sbin/firewall.sh
down /usr/local/sbin/firewall.sh
y ahora tengo:
# The loopback network interface
auto lo
iface lo inet loopback
# The primary network interface
auto br0
iface br0 inet dhcp
bridge_ports eth0
bridge_stp off
bridge_maxwait 5
up /usr/local/sbin/firewall.sh
down /usr/local/sbin/firewall.sh
* Ojo: por algún motivo que desconozco, br0 tarda bastante más que eth0 en conseguir la ip por dhcp, pero funciona bien, así que no asustarse.
* Ojo2: en el script del firewall tenía una referencia a eth0 que he tenido que sustituir por br0 para que funcionase. Además, el tráfico de las máquinas virtuales va por la cadena FORWARD, así que tendréis que modificar las reglas adecuadamente
La salida de /sbin/ifconfig -a ahora queda:
br0 Link encap:Ethernet HWaddr 00:1e:0b:65:03:23
inet addr:192.168.4.25 Bcast:192.168.4.255 Mask:255.255.255.0
inet6 addr: 2001:720:1410:8fff:21e:bff:fe65:323/64 Scope:Global
inet6 addr: fe80::21e:bff:fe65:323/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:8770 errors:0 dropped:0 overruns:0 frame:0
TX packets:4103 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:2118422 (2.0 MiB) TX bytes:453521 (442.8 KiB)
eth0 Link encap:Ethernet HWaddr 00:1e:0b:65:03:23
inet6 addr: fe80::21e:bff:fe65:323/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:10660 errors:0 dropped:0 overruns:0 frame:0
TX packets:4341 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:100
RX bytes:2432390 (2.3 MiB) TX bytes:483596 (472.2 KiB)
Memory:f0180000-f01a0000
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:99 errors:0 dropped:0 overruns:0 frame:0
TX packets:99 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:5892 (5.7 KiB) TX bytes:5892 (5.7 KiB)
Una interfaz de red tap es una interfaz de red -de nivel 2- software, y son las que usaremos en estas máquinas virtuales. Como siempre, más información en la wikipedia
http://en.wikipedia.org/wiki/TUN/TAP
Todo lo que hago a partir de aquí debería ser capaz de hacer kvm sin más que tener un fichero /etc/kvm/kvm-ifup adecuado, pero no termina de funcionar. Específicamente, si le decimos que queremos usar una interfaz tap, como el dispositivo no lo hayamos creado y levantado antes, la cosa no funciona. Creo que tiene que ver con este bug:
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=412941
Así que antes de ejecutar kvm creamos una interfaz tap0 que pertenezca a nuestro usuario, la levantamos y la añadimos al bridge br0. Como tengo que arrancar máquinas virtuales con relativa frecuencia, a cada una le creo un script como el que sigue que hace todo el trabajo, y deshace los cambios al acabar. Por supuesto, cada máquina virtual tiene una MAC -que tiene que empezar por 54:52:00-, un NUM y una imagen diferente:
#!/bin/bash
MEMORIA=256MAC=54:52:00:12:34:5E
NUM=0
IMAGEN=~/MyMachines/CentOS4/centos4.img
sudo /sbin/iptables -P FORWARD ACCEPT
sudo /usr/sbin/tunctl -u $USERsudo /sbin/ip link set tap$NUM up
sleep 0.5s
sudo /usr/sbin/brctl addif br0 tap$NUMkvm -hda $IMAGEN -m $MEMORIA -k es \
-net nic,macaddr=$MAC -net tap,ifname=tap$NUM
sudo /usr/sbin/brctl delif br0 tap$NUM
sudo /sbin/ip link set tap$NUM down
sudo /usr/sbin/tunctl -d tap$NUM
y ya está, la eth0 de la máquina virtual me coje una ip del dhcp público.
Tenés algo más de información en los documentos que más o menos he seguido:
Networking - Kernel based Virtual Machine
y
| « | Diciembre 2008 | » | ||||
|---|---|---|---|---|---|---|
| Lu | Ma | Mi | Ju | Vi | Sa | Do |
| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 8 | 9 | 10 | 11 | 12 | 13 | 14 |
| 15 | 16 | 17 | 18 | 19 | 20 | 21 |
| 22 | 23 | 24 | 25 | 26 | 27 | 28 |
| 29 | 30 | 31 | ||||