Categories
General

Open vSwitch: Un ejemplo práctico

Un ejemplo práctico

Después de instalar KVM i Open vSwitch y ver los comandos básicos para la creación/modificación de bridges/puertos/bondings, vamos a configurar la red de nuestros hosts de KVM, los cuales tienen 53 VLANS diferentes, para este ejemplo utilizaremos 2 hosts físicos, para ver la forma de crear VLANs de forma que puedan ser vistas des del switch externo y de esta forma poder llegar a la red privada de la otra máquina. El esquema de red con los switches virtuales y con varias máquinas virtuales en funcionamiento en un momento dado podría ser:

Éste podría ser un ejemplo de proveedor de Iaas, dónde los clientes comparten la red pública y cada uno de ellos puede crearse sus propias redes privadas entre máquinas. En este ejemplo las máquinas VM1, VM2 y VM3 podrian ser de un cliente, las VM4, VM5, VM6 y VM7 de otro, y las VM8 y VM9 de otro más.
Podemos ver como tenemos varias VLAN’s, la 1 será para el management, la 2 será para el storage NFS de las máquinas físicas, y la VLAN 3 será una VLAN pública común a todos los clientes, mientras que las VLANS de la 04 a la 53 nos servirán para las redes privadas entre máquinas virtuales. Ya que éstas redes privadas deberán verse entre hosts físicos, las tendremos que tener precreadas en el switch exterior. A continuación se detalla cada una de las redes y la configuración necesaria que deberemos tener en el switch exterior.

  • Management: VLAN 01. Red para management del host físico, esta interfície no tendrá ni bridges, ni tagging ni bonding así que no intervendrá el Open vSwitch. Será una sola IP por host: 192.168.1.1 y 192.168.1.2. Así pues tendremos que configurar los puertos 1 y 6 del switch exterior con modo acceso y con la VLAN 01.
  • Storage: Red para el storage NFS de imágenes de máquinas virtuales. Debido a la criticidad del storage, tendremos un bonding sobre dos interfícies físicas. A parte aquí nos entra el tráfico taggeado con la VLAN 02 y las máquinas físicas tendrán las IPs 192.168.2.1 y 192.168.2.2. Así pues tendremos que configurar los puertos 2,3,7 y 8 del switch exterior con la VLAN 02 en modo tagged.
  • MV-pública: Red para agregar puertos a las máquinas virtuales, tanto para esta cómo para la MV-privada tendremos un bridge común sobre el que crearemos puertos con diferentes tags. Para tener mejor redundancia de puertos, vamos a hacer un bonding sobre las interfícies eth3 y eth4, en un caso real cada una de las bocas iría a un switch diferente para tener redundancia a nivel de switch. Las máquinas físicas no tendrán ninguna IP de este rango. En este caso tendremos que configurar las bocas 4,5,9 y 10 en modo tagged con las VLANS de la 3 a la 53.
  • MV-privadas: Red para agregar puertos a las máquina virtuales y crear redes privadas entre ellas, al tener varias máquinas físicas necesitaremos que salgan las VLANs del host y es por eso que tendremos que precrear las VLANs de la 4 a la 53 en el switch exterior. Tal y como se ha explicado en el apartado de MV-pública tendremos los puertos 4,5,9 y 10 del switch exterior con las VLANS 3 a la 53.

Creación de bridges

Vamos pues a crear todos los bridges y configurar la red en los hosts, en este post no entraremos a configurar los switches exteriores, supondremos que ya los tenemos configurados como se ha explicado en el apartado anterior.

Management:

Para la IP de management sólo tenemos que añadir la configuración de la IP en el fichero /etc/network/interfaces, en el host 1 quedará de esta forma:

auto eth0
iface eth0 inet static
        address 192.168.1.1
        netmask 255.255.255.0
        gateway 192.168.1.254

En el host 2 quedará:

auto eth0
iface eth0 inet static
        address 192.168.1.2
        netmask 255.255.255.0
        gateway 192.168.1.254

Storage:

Para la red de storage vamos a crear una interfície de bonding (bondst) sobre un bridge (brst), como necesitamos una IP, vamos también a crear un puerto con una interfície física (brstp1) con tagging y la IP. En los dos hosts físicos ejecutamos:
# ovs-vsctl add-br brst
# ovs-vsctl add-bond brst bondst eth1 eth2
# ovs-vsctl add-port brst brstp1 — set interface brstp1 type=internal
#ovs-vsctl set port brstp1 tag=2
Añadimos la IP a la interfície brstp1 del bridge con el openvswitch y configuramos las interfícies eth1 y eth2 para que se levanten al arrancar.
En el nodo 1 añadimos lo siguiente en el /etc/network/interfaces:

auto brstp1
iface brstp1 inet static
address 192.168.2.1
netmask 255.255.255.0
auto eth1
iface eth1 inet manual
up ifconfig $IFACE 0.0.0.0 up
down ifconfig $IFACE down
auto eth2
iface eth2 inet manual
up ifconfig $IFACE 0.0.0.0 up
down ifconfig $IFACE down

En el nodo 2 quedará:

auto brstp1
iface brstp1 inet static
address 192.168.2.2
netmask 255.255.255.0
auto eth1
iface eth1 inet manual
up ifconfig $IFACE 0.0.0.0 up
down ifconfig $IFACE down
auto eth2
iface eth2 inet manual
up ifconfig $IFACE 0.0.0.0 up
down ifconfig $IFACE down

Algunos problemas con los que me he encontrado con esta solución, son que al añadir el punto de montaje en el /etc/fstab la máquina no arranca porque se intenta montar antes de que el servicio del openvswitch se haya levantado. Una solución temporal es añadir noauto a las opciones del /etc/fstab y arrancarlo des del /etc/rc.local, si hubiera servicios que dependieran de este punto de montaje no seria una solución válida, pero como no es el caso, lo dejamos así.
La linea correspondiente al /etc/fstab podría ser como:

192.168.2.50:/vol/mvs   /mvs                  nfs     noauto 0 0

Y añadiríamos en el /etc/rc.local:

mount /mvs

MV-Pública y MV-privadas:

En este caso, cómo no tendremos ninguna IP asociada en el host, tan solo creamos los bridges y configuramos las interfícies de red eth3 y eth4 para que se levanten al arrancar la máquina.
Creamos el bridge (brmv) con el bonding (bondmv) en los dos hosts:
# ovs-vsctl add-br brmv
# ovs-vsctl add-bond brmv bondmv eth3 eth4
Añadimos en el fichero /etc/network/interfaces de los dos hosts lo siguiente para que las interfícies se levanten al arrancar:

auto eth3
iface eth3 inet manual
up ifconfig $IFACE 0.0.0.0 up
down ifconfig $IFACE down
auto eth4
iface eth4 inet manual
up ifconfig $IFACE 0.0.0.0 up
down ifconfig $IFACE down

Una vez llegados a este punto ya tenemos toda la red configurada, tan sólo nos queda hacer un reboot de los hosts, ver que se ha configurado todo correctamente y empezar a crear máquinas virtuales.

Creación de máquinas virtuales

Para ver el procedimiento de creación de máquinas virtuales y para comprobar que todo esta correctamente, vamos a crear unas maquinas virtuales con la misma VLAN en diferentes hosts y vamos a comprobar que se ven entre ellas, también vamos a comprobar que no se mezcla el tráfico entre VLANs.
Vamos a suponer que tenemos dos clientes, cada uno con dos máquinas virtuales, con una IP privada cada una, cómo es lógico no queremos que las máquinas entre clientes puedan verse el tráfico, así que la VLAN privada va a tener un tag diferente para cada cliente:

  • Cliente1:
  • MV1
  • Host físico: host1
  • Redes:
    • privada: VLAN 4
  • MV2
  • Host físico: host2
  • Redes:
    • privada: VLAN 4
  • Cliente2:
  • MV3
  • Host físico: host1
  • Redes:
    • privada: VLAN 5
  • MV2
  • Host físico: host2
  • Redes:
    • privada: VLAN 5

Supondremos que ya tenemos creadas imágenes de disco con una Ubuntu instalada. Así creamos el xml de creación de la MV1 para libvirt (no se pone el xml de todas las máquina ya que serán muy parecidos adaptando el nombre, la imágen y la mac. Lógicamente el bridge donde se conectaran será para todos el mismo, cambiando posteriormente el tag de cada puerto):

# cd /mvs
# cat mv1.xml
<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
        <name>mv1</name>
        <cputune>
                <shares>1024</shares>
        </cputune>
        <memory>524288</memory>
        <os>
                <type arch='x86_64'>hvm</type>
                <boot dev='hd'/>
        </os>
        <devices>
                <emulator>/usr/bin/kvm</emulator>
                <disk type='file' device='disk'>
                        <source file='/mvs/disk.mv1'/>
                        <target dev='hda'/>
                        <driver name='qemu' type='qcow2' cache='default'/>
                </disk>
                <interface type='bridge'>
                        <source bridge='br32'/>
                        <mac address='00:00:00:00:00:01'/>
                         <model type='virtio'/>
                </interface>
         </devices>
        <features>
                <acpi/>
        </features>
</domain>

Creamos las mv’s en el host1:

# virsh create mv1.xml
# virsh create mv3.xml

Creamos las mv’s en el host2:

# virsh create mv2.xml
# virsh create mv4.xml

una vez creadas las máquinas vamos a ver que puertos les ha asignado a cada uno, en el host1 ejecutamos:

# virsh dumpxml mv1 | grep vnet
<target dev='vnet0'/>
# virsh dumpxml mv3 | grep vnet
<target dev='vnet1'/>

Vamos al host 2:

# virsh dumpxml mv2 | grep vnet
<target dev='vnet0'/>
# virsh dumpxml mv4 | grep vnet
<target dev='vnet1'/>

Visto esto vamos a asignar la VLAN correspondiente a cada uno de los puertos, empezamos con el host 1:

# ovs-vsctl set port vnet0 tag=4
# ovs-vsctl set port vnet1 tag=5

Lo mismo en el host 2:

# ovs-vsctl set port vnet0 tag=4
# ovs-vsctl set port vnet1 tag=5

Comprobaciones finales

Vamos a comprobar que se ven entre las máquinas de cliente y que no se ven las máquinas de diferentes clientes.
Para empezar asignamos una dirección IP a cada una de ellas:
MV 1: 192.168.1.1
MV 2: 192.168.1.2
MV 3: 192.168.1.3
MV 4: 192.168.1.4
Hemos puesto IPs del mismo rango, pero no tendrían que verse entre las máquinas de diferentes clientes, ya que les hemos asignado diferente VLAN. Vamos a comprobarlo, entramos en la MV1:

mv1:~# ping -c4 192.168.1.2
PING 192.168.1.2 (192.168.1.2) 56(84) bytes of data.
64 bytes from 192.168.1.2: icmp_req=1 ttl=64 time=0.187 ms
64 bytes from 192.168.1.2: icmp_req=2 ttl=64 time=0.193 ms
64 bytes from 192.168.1.2: icmp_req=3 ttl=64 time=0.191 ms
64 bytes from 192.168.1.2: icmp_req=4 ttl=64 time=0.205 ms
--- 192.168.1.2 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 2997ms
rtt min/avg/max/mdev = 0.187/0.194/0.205/0.006 ms

Vemos como si que se ven las máquinas mv1 y la mv2, vamos ahora a comprobar que no se ven la mv1 con la mv3

mv1:~# ping -c4 192.168.1.3
PING 192.168.1.3 (192.168.1.3) 56(84) bytes of data.
From 192.168.1.1 icmp_seq=1 Destination Host Unreachable
From 192.168.1.1 icmp_seq=2 Destination Host Unreachable
From 192.168.1.1 icmp_seq=3 Destination Host Unreachable
From 192.168.1.1 icmp_seq=4 Destination Host Unreachable
--- 192.168.1.3 ping statistics ---
4 packets transmitted, 0 received, +4 errors, 100% packet loss, time 3011ms

Eso es todo por hoy. En posts futuros veremos cómo fijar las MACs de las máquinas virtuales, aplicar reglas de firewalling, QoS,…
Un saludo post navideño! 😉

Categories
General

Open vSwitch: Bridges, puertos y bondings

Bridges, puertos y bondings

Antes de entrar en materia, vamos a ver algunos comandos que nos seran útiles para crear, modificar y listar los parámetros  de bridges/puertos/bondings.

Bridges:

Para agregar un bridge la sintaxis és la siguiente:

ovs-vsctl add-br <nombre>

Una vez creado un bridge, si queremos ver las propiedades:

ovs-vsctl list bridge <nombre>

O si queremos ver las propiedades de todos los bridges:

ovs-vsctl list bridge

Esto no dará una salida parecida a la siguiente:

_uuid               : d755e5f7-04c0-477d-91b4-e0b6c078e330
controller          : []
datapath_id         : "00000026b9fae772"
datapath_type       : ""
external_ids        : {}
fail_mode           : []
flood_vlans         : []
mirrors             : []
name                : "br2066"
netflow             : []
other_config        : {}
ports               : [285c7888-d9ec-4eb6-a6cd-33865d946e81]
sflow               : []
status              : {}
stp_enable          : false

Para eliminar un bridge:

ovs-vsctl del-br <nombre>

Puertos:

Para los puertos, la sintaxis es parecida, pero siempre va asociado a un bridge:

ovs-vsctl add-port <bridge> <puerto>

Si queremos que este puerto este asociado a una interficie de red que creara el openvswitch (NO para una interfície que ya exista en la maquina), luego le podremos poner una IP por ejemplo:

ovs-vsctl add-port <bridge> <puerto> -- set interface <puerto> type=internal

Una vez creado el puerto podemos ver sus propiedades:

ovs-vsctl list port <puerto>

Nos dará una salida parecida a la siguiente:

_uuid               : fd908ca0-c636-41bd-bca9-29fcf2e60bce
bond_downdelay      : 0
bond_fake_iface     : false
bond_mode           : []
bond_updelay        : 0
external_ids        : {}
fake_bridge         : false
interfaces          : [13ca2629-5fac-412c-8dcd-b21e917f48e3]
lacp                : []
mac                 : []
name                : "puerto"
other_config        : {}
qos                 : []
statistics          : {}
status              : {}
tag                 : []
trunks              : []
vlan_mode           : []

Aqui ya podemos ver algunas propiedades interesantes, vemos como podemos configurar parametros como trunks o tag si estamos entrando VLANs taggeadas o el modo lacp si quisieramos configurarla en este modo. Para modificar alguna de sus propiedades, la sintaxis es la siguiente:

ovs-vsctl set port <puerto> <propiedad>=<valor>

Así, si quisieramos modificar el tag del puerto, un ejemplo podria ser:

ovs-vsctl set port br01pr01 tag=2022

Y para volver a dejarlo sin tag:

ovs-vsctl set port br01pr01 tag=[]

Bondings e interfícies

Para crear bondings, lo que hacemos es crear un puerto (asociado a un bridge) con bonding formado de dos o más interfícies de red físicas. Al ser creado como un puerto tendrá los mismos atributos que hemos visto para los puertos.

ovs-vsctl add-bond <bridge> <bond_port> <if1> <if2> ...

Por ejemplo si quisieramos crear un bonding sobre las interfícies eth0 y eth1

ovs-vsctl add-bond br01 bond0 eth0 eth1

Para ver el estado del bonding, ejecutamos:

ovs-appctl bond/show bond0

Un puerto esta formado por una o mas interfícies, en los puertos con bonding estan formados por mas de una. Una interfície puede ser mapeada a una interfície de red física de la máquina o a una interfície correspondiente de una maquina virtual. Para ver las interfícies:

ovs-vsctl list interface

O con:

ovs-vsctl show

también vemos toda la estructura de interfícies y bridges a los que estan mapeadas.

Categories
General

Instalación de KVM y Open vSwitch en Ubuntu


Después de un primer post de introducción de la serie Open vSwitch dónde vimos las virtudes de éste, vamos a ver el proceso de instalación en Ubuntu 12.04, en este post vamos a instalar Open vSwitch y KVM.

Instalación inicial y configuración:

Nos loggeamos cómo usuario root y actualizamos la lista de los repositorios y el sistema operativo:

# apt-get update
# apt-get dist-upgrade

Instalamos KVM y libvirt:

# apt-get install qemu-kvm libvirt-bin virtinst virt-manager virt-viewer

Instalamos los paquetes para el manejo de redes:

# apt-get install openvswitch-controller openvswitch-brcompat \ 
openvswitch-switch openvswitch-datapath-source vlan

En nuestro caso, veremos más adelante cómo almacenaremos las imágenes de maquina virtuales en NFS, así que instalamos el paquete necesario para el cliente:

# apt-get install nfs-common

Editamos el fichero /etc/default/openvswitch-switch y descomentamos y cambiamos la linea dónde pone:

#BRCOMPAT=no

la cambiamos por:

BRCOMPAT=yes

Borrado de bridges por defecto y puesta en marcha

Vamos a borrar los bridges que nos crea el KVM por defecto:

# virsh net-destroy default
# virsh net-autostart --disable default

Boramos el paquete ebtables:

# apt-get purge ebtables

Eliminamos el modulo bridge del kernel, ya que el del openvswitch y éste no pueden correr juntos en el kernel, tener en cuenta que si en el fichero de configuración de redes tenemos algún bridge configurado, al reiniciar la máquina se cargará el modulo bridge y no nos será posible iniciar el servicio del openvswitch.

# rmmod bridge
# service openvswitch-switch start

Vemos si nos ha cargado el modulo del openvswitch

# lsmod | grep brcom

Esto debería darnos una salida similar a la siguiente:

brcompat_mod           13512  0
openvswitch_mod        83993  3 brcompat_mod

Llegados a este punto ya tenemos el Open vSwitch instalado y preparado para funcionar. En futuros posts veremos como crear bridges y agregar puertos a estos tanto para la máquina física como para las maquinas virtuales

Categories
In detail

Introducción a Open vSwitch


Con este iniciamos hoy una serie de posts sobre Open vSwitch. Para este primer post de introducción veremos las funcionalidades que nos ofrece. En posts futuros entraremos en materia con ejemplos prácticos y demostraciones del potencial de este software.
Open vSwitch es un switch software de nivel 3 con muchas funcionalidades añadidas a las que nos puede dar el bridge de nivel 2 que viene por defecto en Linux con el comando brctl. Así a grandes rasgos seria como comparar un switch de nivel 2 casero de 20€ con un switch de algún fabricante puntero como el Cisco Nexus 1000V.
De sus múltiples funcionalidades y virtudes, destacaría las siguientes (aqui la lista entera):

  • NetFlow i sFlow – posibilidad de sacar netflows i sflows, que pueden ser capturados y analizados. De esta forma podremos detectar comportamientos anormales de la red, malware,…
  • SPAN i RSPAN – Nos permite hacer mirroring de un puerto o de todo un bridge entero.
  • VLANS 802.1q – Definición de VLANs con soporte de VLANs taggeadas.
  • LACP, Bonding – permite balancear el tráfico entre varios enlaces, LACP és a nivel de switch exterior (trunking) y el bonding a nivel de máquina virtual.
  • Spanning Tree IEEE 802.1D-1998
  • QoS – Nos permite definir niveles de calidad de servicio como disponibilidad, ancho de banda, latencia, ratio de error, así como priorizar el trafico de red.
  • Políticas de tráfico por puerto – firewalling.

Como muchos ya os habréis imaginado, openvswitch nos será muy útil en entornos de virtualización, donde podremos manejar nuestras configuraciones y monitorizaciones a nivel de puerto y bridge virtual, lo cual nos permitirá entrar a niveles de detalle que no podráamos des del switch que tengamos fuera del host físico. Aqui podeis ver también el porque la gente de Open vSwitch nos recomienda utilizarlo.
En posts futuros veremos como instalarlo en Ubuntu y algunas de sus funcionalidades en acción.