lunes, 28 de julio de 2014

KVM: Driver Macvtap para la conexión de VMs

"La utilización del driver Macvtap es otro de los mecanismos utilizados en los KVMs para proporcionar conexión de las máquinas virtuales, al igual que la utilización de bridges o el OVS. Este aporta funcionalidades diferenciadoras que pueden ser útiles en algunos entornos virtualizados"


El driver Macvtap permite un tipo diferente de conectividad a las que aporta la combinación bridge + tap (ver "KVM: bridges, bondigs y VLANs con VMs (bridge mode & routed mode)") o el uso de Open vSwitch (ver "KVM y Open vSwitch (OVS): Componentes, ventajas y configuración de conectividad básica para máquinas virtuales"). Para poder apreciar mejor las diferencias conviene entender previamente el funcionamiento de los bridges y del OVS en los KVMs.

Macvtap puede ser útil por alguno de estos motivos:

  • Se requiere una visibilidad del tráfico de red inter-VM cuando estas residen en el mismo Host: Este requisito con el tiempo irá desapareciendo, ya que otras soluciones como la que utiliza el OVS cada vez aportan una mayor visibilidad de los flujos, del mismo modo que se podrían ver en los switches tradicionales
  • Se necesita hacer uso de una funcionalidad de red que solo se encuentra implementada en los switches físicos: Al igual que en el punto anterior, con el tiempo el OVS está adquiriendo casi todas las funcionalidades que se puedan encontrar en un switch físico.
  • Se necesita que las máquinas virtuales "vean" la misma dirección MAC de sus vNICs que la que ven el Host KVM: Esto no puede darse cuando se utilizan TAPs.
  • Se necesita mejorar el rendimiento de CPU de los Host KVMs: Como se verá más adelante, hay entornos en los que puede ser útil el cambio a este driver.


Los dos primeros motivos vienen dados gracias a que, con el driver Macvtap, se puede obligar a todo el tráfico de las máquinas virtuales a pasar por los switches de uplink, lo cual puede ser una posible solución a algunas de las carencias que introduce la visualización de servidores (ver "TRILL, SPB, VXLAN, NVGRE, EVI, OTV, EVB, VNTag: nuevas soluciones para antiguos problemas"), no obstante, como se ha resaltado, las arquitecturas basadas en SDN cubren estos y otros problemas, por lo que, si este fuese el único motivo para utilizar este driver, se debería buscar también las posibilidades de las soluciones basadas en Software (junto con el OVS, por ejemplo).

En esta entrada se muestra una descripción del driver Macvtap y más tarde se repasan sus ventajas, lo cual hará entender mejor el por qué de los anteriores 4 casos en los que podría ser buena idea utilizar este driver. 


Descripción del driver Macvtap


Macvtap es en driver que combina las propiedades de los interfaces TAP y las de otro driver llamado Macvlan.

El driver Macvlan permite la creación de interfaces virtuales que pueden ser adheridas a las NICs físicas. Cada una de esas interfaces virtuales tiene su propia dirección MAC, la cual es diferente de la dirección MAC de la NIC física, y puede ser utilizada como cualquier otro interfaz habitual. Esto quiere decir que con el driver Macvlan se podrían configurar múltiples IPs en un mismo interfaz físico, pero con la novedad de que cada una de ellas podría tener su propia dirección MAC.

Por su lado, hay que recordar que el interfaz TAP es un interfaz Software que, en lugar de enviar y recibir paquetes de una NIC física, lo hace contra un programa en el userspace del Sistema Operativo.

Un interfaz Macvtap podría verse como un interfaz TAP, pero con funcionalidades añadidas, iguales a las proporciona el driver Macvlan, con lo que las máquinas virtuales que se creen dentro de un KVM podrían utilizarlo para conectarse al mundo exterior sin necesidad de utilizar un bridge intermedio (hay que recordar que Macvlan ofrece la posibilidad de "conectar" varias interfaces a una misma interfaz física):

Las interfaces Macvlan disponen de varios métodos de funcionamiento, y por tanto las interfaces Macvtap utilizadas para la virtualización en KVM también, ya que, como se ha comentado, estos heredan las funcionalidades de los primeros. 

Estos modos de funcionamiento son mutuamente excluyentes pero existe una funcionalidad adicional (Multichannel VEPA) que permite dividir lógicamente un interfaz (mediante encapsulaciones Q-in-Q) de manera que cada división se podría vincular a un modo de funcionamiento diferente.

Los modos de funcionamiento son los siguientes:

1) Modo VEPA (Virtual Ethernet Port Aggregator)

Este es el modo por defecto. Cuando el interfaz Macvtap está configurado para funcionar según el modo VEPA, este enviará todo el tráfico de la máquina virtual al switch físico externo al Host KVM, aunque se quiera comunicar con otra VM que resida en el mismo Host. A continuación se muestra una representación del tráfico unicast entre dos VMs contenidas en el mismo KVM (tomada de este documento):


Figura 1 - Modo VEPA: flujo entre dos máquinas del mismo KVM 

Este comportamiento permite tener la posibilidad de gestionar el tráfico de las VMs en los switches físicos, así como tener visibilidad de dicho tráfico como si de tráfico "tradicional" se tratase, utilizando las mismas herramientas de monitorización que para los servidores y la red física.

Pero la ventaja fundamental es el aprovechamiento de las funcionalidades que aportan los switches físicos a la hora de realizar configuraciones complejas, solo posibles hoy en día si se utilizan switches físicos (hasta que sean implementadas en switches virtuales, por ejemplo en Open vSwitch). También se puede ver como ventaja que la configuración y control de la red esté contenido en los switches, por lo que el personal que gestiona la red será el responsable del networking de la plataforma física y de la virtual, sin necesidad de tener que contar con los responsables de sistemas encargados de la visualización.

El enviar todo el tráfico a los switches físicos también conlleva que se hará un mayor uso de los anchos de banda de las NICs de los KVM, pero la desventaja principal es la necesidad de que los switches físicos permitan que el tráfico pueda ser reenviado por el mismo interfaz por el que ha sido recibido y en la misma VLAN (esto se llama "hairpin mode" o en algunos casos "Reflective Relay"). 

Este comportamiento no está permitido de manera "normal" en los switches, ya que en ningún caso (sin utilizar el driver Macvtap) un servidor enviaría tráfico al switch para ser recibido por él mismo, por lo que habitualmente los switches físicos desechan estos paquetes que "quieren regresar" por el mismo interfaz por el que han llegado el switch.

Esto quiere decir que si los switches físicos que conectan al KVM no están preparados para soportar el "hairpin mode" el modo VEPA no podrá ser utilizado, ya que el tráfico entre las VMs que residan en un mismo Host será descartado.

El modo VEPA, no es el único medio de permitir que los switches físicos gestionen el tráfico de las máquinas virtuales, también existe un protocolo propietario (VNLink / VNTag) que "extiende" las vNICs y las hace parecer directamente conectadas a los switches físicos (ver "TRILL, SPB, VXLAN, NVGRE, EVI, OTV, EVB, VNTag: nuevas soluciones para antiguos problemas"). Este concepto es algo diferente, ya que con VEPA no "aparecen" nuevos puertos de acceso en los switches físicos según se creen nuevas vNICs en las VMs. En este sentido también hay que recordar que VEPA solo exige que los switches de uplink soporten el "hairpin mode", mientras que con las VNtags se debe disponer de switches compatibles con este protocolo propietario, algo que es más difícil que lo primero. VMware utiliza VNTag para poder "obligar" al tráfico inter-VM  a pasar por el switch de uplink.

2) Modo bridge

Este modo de funcionamiento emula al comportamiento de un bridge, es decir, el tráfico procedente de una VM que quiera alcanzar a otra VM contenido en el mismo Host KVM, y dentro del mismo dominio L2, se enviará directamente dentro del Host, es decir, no saldrá al switch de uplink externo.

Con esto se evita la necesidad de switches que soporten el hairpin mode, y también se evitan los retardos producidos por el envío hasta los switches externos así como el uso del ancho de banda de las NICs que conectan el Host con ellos.

Este es un esquema de ejemplo en la configuración modo bridge:



Figura 2 - Modo bridge: flujo entre dos máquinas del mismo KVM 

Se puede pensar qué sentido tendría utilizar el driver Macvtap en modo bridge frente a la utilización de TAPS. Esto se aclarará más adelante en la sección de ventajas del uso del driver Macvtap.

A parte, también hay que recordar que diversos fabricantes de NICs aportan la funcionalidad SRVIO, la cual gestiona por Hardware el funcionamiento modo bridge, liberando de este trabajo a la CPU del Host KVM. Esto también puede ser un aspecto determinante en el uso del modo bridge frente a los otros dos.

3) Modo privado

El modo privado es igual que el modo VEPA, con la salvedad de que se impide la comunicación directa entre las máquinas virtuales contenidas en el Host (si estas utilizan también el interfaz Macvtap). Esto es lo mismo que pasaría si se configurase el modo VEPA y el switch de uplink no soportase el "hairpin mode".

Para representarlo se muestra este esquema:



Figura 3 - Modo privado: flujo entre dos máquinas del mismo KVM 

Esto puede ser útil para entornos en los que se necesite que las VMs de un Host estén aisladas unas de otras pero dentro de la misma red.


Pros y contras de Macvtap


Las ventajas de la utilización del driver Macvtap se podrían dividir en dos grupos: Las provenientes de hacer pasar el tráfico por los switches de uplink y las de no utilizar el modo promiscuo en las interfaces NICs externas.

Gracias al modo VEPA se puede obligar al tráfico de las máquinas virtuales por los switches físicos de uplink. Ya se han señalado las ventajas de este comportamiento: mayor visibilidad de tráfico por parte del personal de red, posibilidad de utilización de las funcionalidades de los switches físicos, etc.

Por otro lado, para entender como ventaja que no hay necesidad de utilizar el modo promiscuo en las NICs externas, hay que recordar que cuando se utilizan bridges, las NICs físicas que dan acceso a la red física se configuran en modo promiscuo, es decir, aceptan todos los paquetes aunque la MAC destino no sea la suya. Esto lo hacen para poder proporcionar acceso a las MACs de las máquinas virtuales que conectadas internamente al bridge, ya que si no tan solo se permitiría la conexión a la IP/MAC del propio Host KVM, no a las de las VMs.

Cuando se utiliza Macvtap no es necesario que la NIC acepte todas los paquetes de todas las MAC (el chip debe soportar RX filter management para no necesitar el modo promiscuo), ya que la propia NIC tiene conocimiento de todas las MACs utilizadas por las VMs, con lo que solo aceptará los paquetes con destino su MAC o las de las interfaces virtuales Macvtap que estén vinculadas a ella.

El no tener la NIC física en modo promiscuo tiene una serie de ventajas, como pueda ser una disminución de las necesidades de CPU del Host en redes en las que exista mucho tráfico, ya que el kernel no tiene porqué inspeccionar todos los paquetes que lleguen para saber si lo tiene que reenviar a una VM o no. Esto a su vez implica que los Host con esta configuración son menos sensibles a algunos ataques DoS (para más información de estos ataques ver "Ataques DoS y DDoS, prevención, detección y mitigación").

Como ventaja adicional está el hecho de que los Sistemas Operativos de las máquinas virtuales detectan la misma dirección MAC en sus vNICs que el Host KVM en el que reside. En "KVM: bridges, bondigs y VLANs con VMs (bridge mode & routed mode)" se vio cómo el KVM detectaba una MAC para una vNIC mientras que el SO de la VM detectaba otra (diferían los dos primeros dígitos). Esto no sucede si se utiliza Macvtap.

En el lado opuesto, como desventajas, se pueden encontrar también dos diferentes. Una ya se ha resaltado, y es la necesidad de que los switches de uplink externos soporten el hairpin mode  para poder utilizar el modo VEPA. 

A parte de esto, hay una desventaja adicional en la utilización de Macvtap, y es que cuando se utilizan estas interfaces, las VMs se pueden ver entre ellas (si no se configura el modo privado), pero el Host KVM no tiene conectividad de red con las máquinas virtuales que residen en él. Esta desventaja no lo es tanto, ya que se puede solucionar si se crea una interfaz Macvlan que pueda utilizar en el Host (hay que recordar que las interfaces Macvtap eran un producto de "sumar" las Macvlans y las interfaces TAP para las VMs).


Configuración de Macvtap


Los siguientes comandos han sido ejecutados en un sistema CentOS 6.5 con una instalación mínima y los siguientes paquetes instalados para dar soporte a la virtualización con KVM:


yum install kvm qemu-kvm libvirt virt-manager libguestfs-tools libvirt-python python-virtinst

La creación de una interfaz Macvtap es sencilla, tan solo hay que ejecutar un comando similar al siguiente:

ip link add link eth3 name macvtap0 type macvtap mode vepa
En este caso el modo configurado es "vepa", pero podría haber sido "bridge" o "private". También se ha vinculado a un interfaz física (eth3) pero existiría la posibilidad de vincularlo a un interfaz de bonding, con lo que se ganaría en alta disponibilidad y ancho de banda.

Tras la creación se puede activar el interfaz del siguiente modo:

ip link set macvtap0 up

Una vez hecho esto ya aparecerá en la lista de interfaces:
  

[root@kvm3 ~]# ifconfig
eth0      Link encap:Ethernet  HWaddr 00:0C:29:5C:E9:84
          inet addr:192.168.52.136  Bcast:192.168.52.255  Mask:255.255.255.0
          inet6 addr: fe80::20c:29ff:fe5c:e984/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:22 errors:0 dropped:0 overruns:0 frame:0
          TX packets:21 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:2427 (2.3 KiB)  TX bytes:2012 (1.9 KiB)

eth1      Link encap:Ethernet  HWaddr 00:0C:29:5C:E9:8E
          inet addr:1.0.1.33  Bcast:1.0.1.255  Mask:255.255.255.0
          inet6 addr: fe80::20c:29ff:fe5c:e98e/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:92 errors:0 dropped:0 overruns:0 frame:0
          TX packets:94 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:10341 (10.0 KiB)  TX bytes:13729 (13.4 KiB)
          Interrupt:16 Base address:0x2000

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:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)

macvtap0  Link encap:Ethernet  HWaddr 76:EC:D0:A9:3F:B3
          inet6 addr: fe80::74ec:d0ff:fea9:3fb3/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:3 overruns:0 carrier:0
          collisions:0 txqueuelen:500
          RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)

virbr0    Link encap:Ethernet  HWaddr 52:54:00:4B:52:03
          inet addr:192.168.122.1  Bcast:192.168.122.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)



Los siguiente sería utilizar esa interfaz con una máquina virtual.

Por otro lado, las interfaces Macvtap también pueden ser creadas mediante libvirt. Para ello se modificará el interfaz de una VM en el XML para que se parezca a este:


<devices>
   <interface type='direct'>
      <mac address='d0:0f:d0:0f:00:01'/>
       <source dev='eth5' mode='vepa'/>
   </interface>
</devices>



Es importante el tipo de interfaz (direct) con la interfaz "eth5" y el modo de funcionamiento, el cual en este caso también es "vepa".

Hay que recordar que tras hacer este cambio se deberá parar y volver a iniciar la máquina virtual para que este tenga efecto.

jueves, 24 de julio de 2014

KVM y Open vSwitch (OVS): Componentes, ventajas y configuración de conectividad básica para máquinas virtuales

"En esta entrada se repasan los componentes del Open vSwitch, sus ventajas frente a los bridges, y las posibilidades de configuración que ofrece , tanto en un despliegue standalone, como cuando se integra con Controladores SDN externos"


El Open vSwitch (OVS) es una implementación Software de switch virtual programable, el cual se puede utilizar para proporcionar conectividad a las máquinas virtuales, sustituyendo a bridges y bondings (ver "KVM: bridges, bondigs y VLANs con VMs (bridge mode & routed mode)").

Puede funcionar en dos modos: cómo un switch tradicional (resolución de MACs), o gestionado por un Controller (configuración de flujos). Este último es el que puede parecer más interesante, al poder utilizarse para desplegar una plataforma SDN, e integrar esta con otras herramientas de gestión del Data Center (por ejemplo los orquestadores de virtualización) para aportar soluciones escalables a la hora de implementar arquitecturas Cloud.

Como se ha dicho, el OVS es un elemento interesante para el despliegue de plataformas Cloud, ya que proporciona la posibilidad de incorporar las ventajas de las redes basadas en flujos programables (SDN), y es por ello que varios desarrolladores de Software lo han utilizado como "base" para generar nuevos productos destinados a proporcionar funcionalidades avanzadas de red en entornos Cloud. Un ejemplo de esto se puede ver en el componente Virtual Routing & Switching (VRS) de Nuage.

En esta entrada no se desarrollarán conceptos de conectividad avanzada (VXLAN, túneles GRE, etc) ya que lo que se pretende es dar una visión introductoria al OVS. Este tipo de configuraciones se revisarán en una futura entrada.

Descripción del Open vSwitch


El Open vSwitch dispone de un diseño de mayor complejidad que los bridges, siendo este compuesto por varios componentes. Mientras que los bridges solo se ejecutan en el espacio del kernel del Host, el OVS, al necesitar un código más complejo que los bridges para poder proporcionar todas las funcionalidades avanzadas, hace uso no solo del espacio del kernel, sino también del user space, en concreto para realizar la decisión de cómo procesar los paquetes "nuevos".

Hay que recordar que el kernel y el user space son dos separaciones lógicas de la memoria que hacen los Sistemas Operativos para proteger el sistema ante fallos o ataques. En el espacio del kernel se ejecutarían los módulos y los drivers del sistema, mientras que en el espacio de usuarios se encontraría la mayoría del Software.

Un paquete "nuevo" es aquel tipo de paquete de un flujo del cual no se ha realizado todavía ninguna decisión de forwarding, y por tanto dicha decisión no pude encontrarse en la caché. Cuando un paquete de un nuevo flujo llega al OVS, este realizará una decisión bajo el user space, pero los sucesivos paquetes de ese flujo serán encaminados directamente por el kernel (más rápido).

Componentes del Open vSwitch

Los componentes del OVS son tres:
  • ovsdb-server
  • ovs-vswitchd
  • openvswitch_mod.ko

Los dos primeros se ejecutan en el user space, mientras que el tercero lo hace en el espacio del kernel.

El ovsdb-server es un servidor ligero de bases de datos. En la base de datos que gestiona se encuentran todos los parámetros de configuración del OVS, los cuales se almacenan de forma que dicha información se mantenga tras un reinicio del Host. 

A modo de ejemplo, algunas de las tablas que existen en esa base de datos, las cuales contienen la configuración de su elementos correspondientes, serían Bridge, Port, Interface, Flow_Table, QoS, Mirror, Controller, ...

Esta base de datos puede ser modificada desde elementos externos utilizando el protocolo Open vSwitch Database Management Protocol (OVSDB), el cual será tratado más adelante en el punto sobre gestión externa del OVS.

El ovs-vswitchd es el proceso que implementa las funcionalidades de switch (junto con el módulo del kernel openvswitch_mod.ko). Implementa el comportamiento ante VLANs, el bonding o la monitorización. 

Este proceso es el Core del OVS, y se ha de comunicar con los otros dos componentes. El proceso ovs-vswitchd debe comunicarse con el ovsdb-server para poder guardar y aplicar las configuraciones almacenadas en la base de datos albergada por el servidor ovsdb-server. Esta comunicación se realiza mediante sockets Unix con el protocolo OVSDB.

El módulo del kernel openvswitch_mod.ko también debe ser contactado por el demonio ovs-vswitchd para poder tomar decisiones sobre los nuevos flujos que reporta el kernel (como se ha visto anteriormente). Para ello utiliza el protocolo netlink el cual permite comunicar el espacio del kernel con el del usuario.

El módulo del kernel openvswitch_mod.ko es quien maneja el packet switching. Ha sido designado para ser muy simple y rápido, por lo que no puede ser modificado mediante Openflow, ni lleva a cabo el borrado de flujos, tan solo maneja una memoria caché en la que tiene determinado qué hacer con cada flujo y, de no conocerlo, contactará con el proceso ovs-vswitchd mediante netlink para saber qué hacer con él.

Los anteriores componentes, así como la relación entre ellos se puede ver en el siguiente esquema:



Figura 1 - Componentes del Open vSwitch

Gestión del Open vSwitch
Sobre los OVS se puede realizar una gestión directamente sobre él, o incluir un elemento controlador central (Controller) utilizando el modo de funcionamiento de OVS de flujos configurables. Como se puede imaginar, se recomienda disponer de un Controller, ya que de esta manera se podrán utilizar las ventajas asumidas de los despliegues SDN (ver "Ideas básicas sobre Software Defined Network").

Si no se dispone de Controller (modo de funcionamiento standalone), se pueden utilizar una serie de herramientas:
  • Gestión de ovsdb-server: se gestiona mediante ovsdb-client
  • Gestión de ovs-vswitchd: Con ovs-vsctl se puede manipular la configuración y con ovs-appctl también se pueden modificar ciertos parámtros de funcionamiento como por ejemplo el logging.
  • Gestión de openvswitch_mod.ko: se puede modificar la configuración del módulo del kernel directamente con ovs-dpctl y mostrar los flujos cacheados con ovs-ofctl.

Con un Controller que centralice la gestión de flujos, se hará uso de los protocolos de gestión externa del OVS: Openflow y OVSDB, los cuales permitirán sacar el máximo partido al OVS en una topología de virtualización compleja.

El protocolo Openflow permite consultar y modificar las tablas de flujos del proceso ovs-vswitchd, haciendo posible que el Software residente en el controller tome decisiones  atendiendo a una serie de variables (recogidas de orígenes diversos), y "reprograme" dinámicamente el comportamiento del OVS con este protocolo, para que los paquetes sean reenviados en consecuencia a uno u otro puerto.

Por otro lado, el protocolo Openflow permite modificar la tabla de flujos, pero no es capaz de cambiar la configuración de un dispositivo, por ejemplo deshabilitando un interfaz, por lo que para todas las gestiones que no estén directamente relacionadas con la modificación de las tablas de flujos se utilizará el protocolo OVSDB. 

El protocolo OVSDB management protocolcomo se ha visto, permite consultar y modificar la configuración del OVS, permitiendo un medio de reprogramar las variables de la base de datos interna, realizando de esta manera tareas como por ejemplo:
  • Creación y modificación de puertos
  • Creación de datapaths 
  • Configuración de los controllers que gestionan la plataforma
  • Recolección de estadísticas
  • Configuración de túneles
  • Configuración de QoS
  • etc...

En este esquema se muestran las comunicaciones externas del Open vSwitch cuando existen elementos controladores:


Figura 2 - Comunicaciones del OVS con el Controller


Ventajas del Open vSwitch

Las ventajas de este sustituto de los bridges a la hora de dar conectividad a las máquinas virtuales son varias. Algunas de ellas se pueden encontrar en ambos métodos de funcionamiento (standalone y con Controller), mientras que otras son exclusivas de la utilización de flujos programados regidos por Controller:
  • Incorporación de funcionalidades de red similares a los switches Hardware
El OVS, a parte de las funcionalidades L2 y L3, VLAN tagging (por puerto) y agregación de enlaces, también provee  funcionalidades propias de un switch Hardware configurable, como puedan ser SPAN/RSPAN, Netflow/sFlow, QoS, Túneles GRE, etc.

Las configuraciones de VLANs y agregados se realizan directamente sobre el OVS, no sobre terceros elementos (bondings, un bridge por VLAN,...) asemejándose de este modo a los switches Hardware.

  • OVSDB y Openflow (OVS en modo flujos configurables)
Si el KVM es parte de un Cloud, hay que tener en cuenta que estas infraestructuras son muy dinámicas, con lo que los cambios en la red se producen numerosas veces y ante multitud de eventos. Gracias al OVS y la utilización de Controller SDN, se facilita el responder dinámicamente a esa gran tasa de cambios que se producen en la infraestructura, modificando la configuración de red

Como se ha visto, el OVS mantiene una la base de datos llamada OVSDB (Open vSwitch Network State Database), la cual alberga toda la información distribuida de la configuración y el estado de los OVS de una infraestructura. Utilizando la información contenida en esa base de datos, ser puede realizar triggers de numerosos aspectos de red más allá de los tradicionales, como por ejemplo el movimiento de máquinas virtuales, de modo que las herramientas de orquestación puedan conocer el estado de la Cloud y utilizar esa información para modificar, mediante el Controller SDN, el comportamiento de reenvío de paquetes dentro de los flujos con Openflow

Con OVSDB, aportando una visibilidad general pormenorizada del estado, y Openflow, con el que se pueden realizar casi cualquier reconfiguración del plano de forwarding que se desee, el Open vSwitch (en modo de funcionamiento por flujos) proporciona los medios para que capas de control/gestión superiores manejen las modificaciones necesarias en la red como respuesta a los cambios que se producen dinámicamente en los entornos virtualizados. Estas mismas modificaciones dinámicas serían imposibles de trasladar a una arquitectura en la que únicamente se hubiesen utilizado bridges en la conectividad de máquinas virtuales.

También, gracias a la base de datos OVSDB, el estado del puerto de red de una máquina virtual puede ser fácilmente migrado junto con la máquina.

El Open vSwitch funcionando por flujos, a su vez, también soporta algunas de las últimas innovaciones desarrolladas para los Data Centers Multitenant, incluso mejora la escalabilidad de las VXLAN. Para explicar esto último hay que recordar que la implementación clásica de VXLAN (por parte de VMware), no dispone de un plano de control, y para el auto-descubrimiento de los Host integrantes de la VXLAN utiliza multicast, lo cual plantea diferentes problemas, desde la necesidad de una arquitectura de red que soporte multicast extremo a extremo, como posibles problemas de recursos cuando se escala a un elevado número de nodos y máquinas virtuales, ya que se ha de hacer flooding (multicast) de las direcciones MAC de estas.

Como ya se comentó (ver "TRILL, SPB, VXLAN, NVGRE, EVI, OTV, EVB, VNTag: nuevas soluciones para antiguos problemas") la problemática de la falta de un plano de control puede ser solventada mediante la utilización de Controladores SDN, los cuales puedrán utilizar Openflow y OVSDB.


  • Offloading de procesamiento de paquetes a Hardware
Una ventaja añadida de Open vSwitch es que está diseñado para poder realizar el procesamiento en Hardware, es decir, que puede realizar un offloading del procesamiento de paquetes a las NICs de los Host KVMs en los que residen, en lugar de hacerlo por Software, con la consiguiente mejora del rendimiento. Ya hay algunos fabricantes, como Broadcom, con los que conseguir este offloading.

  • Compatibilidad con Software basado en bridges
En el caso de que se necesitase hacer compatible el OVS con algún Software basado en bridges (por ejemplo el Virt-manager), esto podría ser llevado a cabo configurando el Open vSwitch de manera que pueda emular el comportamiento de un bridge ("fake bridge") frente a las VLANs. De este modo se contemplaría un bridge por cada VLAN (como se vió en "KVM: bridges, bondigs y VLANs con VMs (bridge mode & routed mode)"), en lugar del comportamiento normal en el cual, dentro de un mismo OVS (bridge), cada puerto tiene una configuración propia (un puerto de acceso a cierta VLAN o un puerto "trunk" 802.1q), del mismo modo que se hace en un switch tradicional.


Este sería un esquema comparativo de la utilización de OVS con fake bridges para proporcionar conectividad de VLANs frente a la configuración "normal":



 Figura 3 - Comparativa de despliegue normal frente a la utilización de fake bridges

Para configurar estos "fake bridges" se utilizará las herramienta ovs-vsctl vista anteriormente, y se tratará cada "fake bridge" como si de bridges tradicionales se tratasen.


Configuración del Open vSwitch

Para la configuración de los bridges se disponían de tres métodos: el manual, la utilización de herramientas CLI como las proporcionadas por libvirt, y el uso de herramientas GUI (ver "KVM: bridges, bondigs y VLANs con VMs (bridge mode & routed mode)"). Para la configuración del OVS se dispone, en algunos casos, de ciertas integraciones con el Sistema Operativo que permiten una configuración puramente manual (generando, por ejemplo, ficheros ifcfg-xxx en sistemas RHEL), no obstante se prefiere a estas el uso de herramientas CLI (ovs-vsctlovs-appctl, etc) así como la utilización de Openflow y OVSDB por parte de los Controllers.


La API de libvirt también es útil en los despliegues en los que exista el OVS, configurando las conectividades de las máquinas virtuales al OVS utilizando los XML. Los nombres de los puertos de las vNICs de las máquinas virtuales cambian en el tiempo (lo cual puede ser un problema a la hora de configurar el OVS) y libvirt puede hacer un trabajo de mediador necesario entre el OVS y la configuración de los puertos, haciendo transparentes estos cambios, con lo que se simplifica la gestión y configuración.

Como se ha visto, las modificaciones de configuración del OVS se hacen sobre una base de datos. Esta base de datos tiene una serie de tablas, sobre las que existen variables con unos posibles valores predeterminados. Para conocer los nombres de las tablas, de las variables y de sus posibles valores se puede consultar la documentación facilitada por la página openvswitch.org.

A continuación se muestran algunos aspectos interesantes de la configuración, aunque existen multitud de configuraciones adicionales (spanning-tree, Sflow, port status, ...) que pueden ser consultados en la documentación de openvswitch.org.

Instalación del Open vSwitch

La instalación se puede llevar a cabo mediante paquetes precompilados con yum, apt-get, etc o bajando la última versión del código y compilándolo uno mismo, lo cual es recomendable para poder disfrutar de las últimas funcionalidades y correcciones de Bugs.

Si se opta por la descarga del fichero con la última versión se podrá comprobar cómo dentro de él (es un .tar) existen varios ficheros de texto nombrados como "INSTALL" e "INSTALL.XXX". En ellos se describen los pasos para instalar correctamente el OpenvSwitch en cada uno de los Sistemas Operativos soportados (en los ejemplos de más abajo se utilizó el procedimiento de INSTALL.RHEL).

Tras la instalación propiamente dicha, se crearán los bridges que utilizará el proceso ovs-vswitchd para realizar las funciones Core dentro del userspace, tal y como se explicó anteriormente (ver ejemplo de configuración más abajo). 

Incorporación de interfaces al Open vSwitch

La vinculación de las interfaces al OVS se puede hacer por dos métodos. El primero, y preferido, es la utilización de las herramientas de gestión propias del Open vSwitch (como ovs-vsctl). Un ejemplo para incluir una interfaz sería el siguiente (ovsbr1 es el nombre del bridge vinculado al OVS):

ovs-vsctl add-port ovsbr1 eth4

Open vSwitch también proporciona una segunda vía de  configuración mediante la integración con el Sistema Operativo (por ejemplo en los sistemas tipo RHEL creando ficheros "ifcfg-xxx"). Para los Sistemas Operativos en los que esta integración sea posible, dentro del propio fichero .tar, también existirán los archivos de texto correspondientes en los que se explican las posibilidades de esta vía opcional (en el caso de los sistemas RHEL el fichero se encuentra en rhel/README.RHEL). El mismo ejemplo de introducción de un interfaz, utilizando la integración con los ficheros de sistema, sería el siguiente:

vi /etc/sysconfig/network-scripts/ifcfg-eth4


DEVICE=eth4
ONBOOT=yes
DEVICETYPE=ovs
TYPE=OVSPort
OVS_BRIDGE=ovsbr1
BOOTPROTO=none
HOTPLUG=no


Se recomienda el primer método ya que es independiente del Sistema Operativo en el que se instale y porque incluye todos los parámetros posibles de configuración (no están todos en las integraciones con los ficheros de sistema).

Configuración de bondings

Del mismo modo que para la incorporación de interfaces, para la configuración de bondings también existen los dos métodos: el uso de las herramientas de OVS y la utilización de la integración con el SO.


Los modos de bonding soportados son los siguientes:
  • Balanceo SLB: Se balancea respecto a la MAC origen y periódicamente se hace un re-balanceo. No necesita configurar nada en el switch físico que conecta las interfaces externas del Host, ni siquiera un agregado de enlace, siempre y cuando el switch permita varias MACs por puerto físico. Es recomendable conectarlo al mismo switch para que no exista pérdidas de paquetes en los re-balanceos.
  • Activo/Backup: En este caso no existe balanceo, hay un enlace que es activo y el resto son backups que entrarán en funcionamiento en el caso de la necesidad de un failover. Esta configuración se puede utilizar sin problemas cuando se conectan los interfaces externos a diferentes switches físicos y por supuesto no es necesario configurar ningún agregado en estos. 
  • Balanceo TCP: Se balancea atendiendo a parámetros L2. L3 y L4 de los paquetes TCP. En este caso si se necesita la configuración de un agregado de enlace LACP en los switches físicos que conectan al Host (todos los enlaces de un agregado LACP a un mismo switch físico o a un stack físico o virtual).

Se recomienda el balanceo LACP por los mismos motivos que los especificados en "KVM: bridges, bondigs y VLANs con VMs (bridge mode & routed mode)". Además, se puede configurar que, en el caso de fallar la negociación LACP, automáticamente se pase al funcionamiento activo/backup.

También se puede configurar cómo se realiza la detección de la necesidad de acometer un failover (o poner un interfaz como "caído"). Por defecto se detecta el estado físico de la interfaz (detección de la portadora o "carrier"), pero también se puede configurar la detección errores, no solo el estado de la interfaz, si se configura la monitorización del MII (Media Independent Interface). Se podrá ver un ejemplo de configuración más adelante.

Configuración de VLANs

Los puertos de OpenvSwtich pueden ser configurados con cuatro modos diferentes de tratamiento de los tags de VLANs. Alguno de ellos podrían llevar a confusión teniendo en cuenta cómo funcionan habitualmente los switches físicos:
  • Modo trunk: En la entrada de estos puertos se esperan paquetes con tags de las VLANs definidas (si no está definida el paquete se desecha) y si llega un paquete sin tag lo incluirá en la "VLAN 0". En la salida de estas interfaces, todos los paquetes irán con la tag de su VLAN, menos los paquetes de la VLAN 0 que se enviarán sin tag.
  • Modo acceso: Es un puerto que transmite los paquetes de una VLAN determinada, pero ni en su salida ni su entrada los paquetes serán marcados con un tag. Si llega a este tipo de puerto un paquete con tag, este será descartado. 
  • Modo "native-untagged": En la entrada se esperan paquetes con tag y, en caso de que llegue un paquete sin tag, el OVS lo tomará como parte de la VLAN asignada como nativa (ha de ser definida por configuración). La salida del puerto serán paquetes con tag menos el tráfico de la VLAN nativa que se enviará sin tag.
  • Modo "native-tagged": Este modo es igual que el modo native-untagged con la excepción de que los paquetes de salida de la VLAN nativa sí que se enviarán con tag, es decir,  que un paquete que se recibe en el puerto sin tag se destina a la VLAN nativa, pero cuando el paquete de la VLAN nativa sale por el puerto (por ejemplo la respuesta al anterior paquete), a este se le asigna el tag, de modo que al switch le llegará el paquete con el tag de la VLAN nativa, en lugar de un paquete sin tag que el incluiría en la VLAN nativa directamente.

Como se puede ver, los modos que tienen un comportamiento similar al de los switches tradicionales son el modo acceso y el modo "native-untagged", ya que el modo trunk utiliza la VLAN 0 para la VLAN nativa y no hay nada similar al modo "native-tagged".

A pesar de lo anterior, todos los modos anteriores pueden funcionar correctamente con los switches tradicionales siempre y cuando en los puertos 802.1q no se utilice la VLAN nativa (si no hay que utilizar el modo "native-untagged")

Por defecto los puertos del OVS se encuentran en modo trunk permitiendo todas las VLANs.

Estos modos de funcionamiento pueden ser configurados tanto en los puertos externos  como en los internos que conectan las VMS, por lo que se podría permitir que estas realizasen tag de VLANs.

Más adelante se mostrará un ejemplo de configuración de modo de funcionamiento ante las VLANs, todos ellos utilizando las herramientas proporcionadas por el OVS.


Por otro lado, tal y como se ha comentado antes, existe otro diseño del OVS para dar soporte a las VLANs en caso de necesitarse compatibilidad con Software basado en bridges: uso de "fake bridges". Un ejemplo de este "Software basado en bridges" podría ser el virt-manager, quien muestra los bridges disponibles en el sistema para poder vincular las máquinas virtuales a ellos.

Los fake bridges se pueden configurar tanto mediante las herramientas de OVS como por mediación de las integraciones con el Sistema Operativo (el mismo método visto anteriormente, utilizando los ficheros de sistema).

En este diseño se creará un fake bridge por cada VLAN el cual se conectará al OVS mediante un puerto de acceso.

Routing con OVS

Se puede realizar enrutamiento con el openvswitch utilizando la funcionalidad de routing del kernel del SO donde está instalado cuando el OVS está funcionando en modo standalone creando fake bridges y realizando el mismo proceso que se vió en 
"KVM: bridges, bondigs y VLANs con VMs (bridge mode & routed mode)".

Si se utiliza el OVS como un switch Openflow (en lugar de standalone), al reenviar este los paquetes según una tabla de flujos programable, el Open vSwitch realmente puede trabajar como un switch o como un router, ya que las decisiones de encaminamiento se pueden hacer tanto por las etiquetas L2 (MACs) como por las L3 (IP), es más, como se ha visto incluso se pueden utilizar elementos de la capa L4 para dichas decisiones. 

Modo de funcionamiento (MAC learning / tabla de flujos)

Hasta ahora en este apartado de configuración, se ha estado tratando al OVS como un Software que lleva a cabo las funciones de un switch tradicional (MAC learning), en las cuales él determina los puertos a los que se han de reenviar los paquetes atendiendo a parámetros como son las MACs, la configuración de VLANs, bonding, etc...


No obstante hay que recordar que el Open vSwitch puede funcionar mediante la configuración de flujos, en lugar de utilizar el modo tradicional, lo cual aporta una gran flexibilidad y abre la puerta a las arquitecturas SDN (ver "Ideas básicas sobre Software Defined Network"). Estos flujos pueden ser configurados ya sea manualmente o mediante un Controller.

Para hacer funcionar el OVS mediante este método de consulta a su tabla de flujos tan solo hay que añadir en su configuración la dirección IP del Controller. Cuando se configura el Controller también es buena idea configurar el modo de funcionamiento en caso de que se pierda la comunicación con él. En este sentido existen dos posibilidades de funcionamiento mientras no hay conectividad con el controller (durante una serie de segundos configurables):
  • Standalone: Cuando se pierde la conectividad (no se reciba ningún paquete desde el Controller durante tres veces un temporizador determinado) el OVS comenzará a funcionar según el método tradicional (MAC learning), en el cual él mismo es quien determina dónde enviar los paquetes según su configuración. Este es el método por defecto en la versión actual de OVS.
  • Secure: El switch continuará funcionando según el método de flujos, pero al no existir Controller no se podrán configurar nuevos flujos. El OVS no admitirá nuevos flujos, ya que no se le permite tomar sus propias decisiones sin controlador, como sucede en el modo standalone, pero los continuará reenviando los paquetes de los flujos que sí que tiene definidos.

El segundo método se llama "seguro" ya que el método standalone tiene el riesgo de que, de no estar correctamente configurado, puede dar lugar a bucles, perdidas de conectividad o paquetes, etc. Por contra, el "método seguro" tiene el riesgo de que los nuevos flujos serán descartados.

Hay que señalar que cuando se recupera la conectividad nuevamente se vuelve al comportamiento de reenvío basado en flujos.


Ejemplo de configuración


El ejemplo de configuración se centrará en la configuración mediante las herramientas CLI del OVS. La configuración mediante la  integración con los ficheros de sistema no se mostrará ya que aparece claramente especificada en el archivo README del .tar y, además, es bastante parecida a la ya vista en "KVM: bridges, bondigs y VLANs con VMs (bridge mode & routed mode)".

También se hará una rápida mención a la configuración necesaria para activar en el OVS el comportamiento por flujos regidos por un Controller. Será breve ya que la mayoría de la configuración se realizaría sobre el propio Controller, lo único a llevar a cabo en el OVS es la propia integración de los dos componentes.

Para estos ejemplos se utilizará el Sistema Operativo CentOS 6.5. Antes de comenzar con la instalación y configuración del OVS, se realiza la instalación del Host KVM y las herramientas libvirt:

yum install kvm qemu-kvm libvirt virt-manager libguestfs-tools libvirt-python python-virtinst

Ya que se va a descargar el fichero con el código de la última versión de OVS, también hay que instalar otras dependencias para poder compilarlo:


yum install gcc make python-devel openssl-devel kernel-devel graphviz kernel-debug-devel autoconf automake rpm-build redhat-rpm-config libtool

El fichero con el código de la versión 2.1 de OVS se puede descargar del siguiente modo:


curl -o openvswitch-2.1.2.tar.gz http://openvswitch.org/releases/openvswitch-2.1.2.tar.gz

Una vez descargado se puede descomprimir:

tar xvfz openvswitch-2.1.2.tar.gz

Dentro del directorio descomprimido se puede encontrar el fichero INSTALL.RHEL el cual muestra los siguientes pasos para configurar correctamente el OVS (compilación de las fuentes en RPMs):


1) Copiar el fichero .tar en el directorio de fuentes RPM:

cp openvswitch-2.1.2.tar.gz /root/rpmbuild/SOURCES/


2) Crear los RPMs del userspace. Para ello antes se ha de entrar en el directorio openvswitch descomprimido:

cd openvswitch-2.1.2
Y luego se crear el RPM:

rpmbuild -bb rhel/openvswitch.spec

Esto crea dos RPMs:
  

[root@kvm2 openvswitch-2.1.2]# ls /root/rpmbuild/RPMS/x86_64/
openvswitch-2.1.2-1.x86_64.rpm  openvswitch-debuginfo-2.1.2-1.x86_64.rpm


3) Crear los RPMs del módulo del kernel.

rpmbuild -bb rhel/openvswitch-kmod-rhel6.spec

Este paso puede originar un error (en algunas versiones de Sistema Operativo) debido a que faltarían por incorporar ficheros necesarios para completar el compilado. El error sería como el siguiente: "error: Installed (but unpackaged) file(s) found:  /etc/depmod.d/openvswitch.conf"

Para solucionarlo se pueden incluir las siguientes líneas al final del fichero de texto openvswitch-kmod-rhel6.speckmod-rhel6.spec (tras el comando de la definición "%clean") de dentro del archivo.tar descomprimido: 

vi rhel/openvswitch-kmod-rhel6.speckmod-rhel6.spec


%files
%defattr(-,root,root,-)
/etc/depmod.d/openvswitch.conf


Tras esta modificación se puede volver a lanzar el comando rmpbuild y, si en esta ocasión no existen errores adicionales, se generarán otros dos RPMs adicionales: 


[root@kvm2 openvswitch-2.1.2]# ls /root/rpmbuild/RPMS/x86_64
kmod-openvswitch-2.1.2-1.el6.x86_64.rpm  openvswitch-debuginfo-2.1.2-1.x86_64.rpm
openvswitch-2.1.2-1.x86_64.rpm           openvswitch-kmod-2.1.2-1.el6.x86_64.rpm


Una vez que se tienen estos cuatro RPMs se pueden instalar en el sistema:


rpm -ivh /root/rpmbuild/RPMS/x86_64/kmod-openvswitch-2.1.2-1.el6.x86_64.rpm
rpm -ivh /root/rpmbuild/RPMS/x86_64/openvswitch-debuginfo-2.1.2-1.x86_64.rpm
rpm -ivh /root/rpmbuild/RPMS/x86_64/openvswitch-2.1.2-1.x86_64.rpm
rpm -ivh /root/rpmbuild/RPMS/x86_64/openvswitch-kmod-2.1.2-1.el6.x86_64.rpm

Desde este punto ya se habría completado la instalación del OVS en el Sistema. Ya que el OpenvSwitch dispone de los dos métodos de funcionamiento comentados (el similar a un switch tradicional y el funcionamiento por flujos), a continuación se dividirá el resto de la configuración en dos secciones, según el caso de uso que se quiera hacer del OVS: una configuración standalone (utilizando tanto las herramientas de OVS como su integración con los ficheros de sistema) o una configuración de las tablas de flujos utilizando un Controller externo.

Configuración para funcionamiento tradicional standalone

En este punto se realizará una configuración primero utilizando las herramientas de OVS y más tarde una configuración similar utilizando la integración con los ficheros de sistema (aunque se recomienda la primera de ellas para entornos reales).


En el siguiente esquema se puede ver la implementación que se realizará en este ejemplo:



 Figura 4 - Esquema del ejemplo de configuración standalone

Como primer paso se ha de crear una bridge al cual se vincule el proceso ovs-vswitchd de manera que se pueden tratar los paquetes recibidos. En este caso se c rea un bridge llamado "ovsbr1":

ovs-vsctl add-br ovsbr1

Una vez ejecutado este comando, se puede comprobar su creación del siguiente modo:


[root@kvm2 ~]# ovs-vsctl show
7f0948cf-6534-46b3-b462-cc2c57e857e4
    Bridge ovsbr1
        Port ovsbr1
            Interface ovsbr1
                type: internal
    ovs_version: "2.1.2"


Como se puede apreciar, el bridge OVS se crea con un puerto incluido de tipo interno. Este puerto es utilizado para configuraciones propias del Open vSwitch, como pueda ser la asignación de una dirección IP a este bridge.

El siguiente paso sería añadir las interfaces externas. Para agregar la interfaz eth2 al OVS,se haría lo siguiente:

ovs-vsctl add-port ovsbr1 eth2

Se comprueba cómo se ha incluido:


[root@kvm2 ~]# ovs-vsctl show
7f0948cf-6534-46b3-b462-cc2c57e857e4
    Bridge "ovsbr1"
        Port "ovsbr1"
            Interface "ovsbr1"
                type: internal
        Port "eth2"
            Interface "eth2"
    ovs_version: "2.1.2"


Pero si lo que realmente se busca es crear un bonding LACP de varias interfaces, se utilizará el comando:

ovs-vsctl add-bond ovsbr1 bond0 eth2 eth3 lacp=active bond_mode=balance-tcp other_config:lacp-time=fast other_config:bond-detect-mode=miimon

En el comando se incluye el tipo de balanceo (balance-tcp), así como la activación de LACP y el método de detección de fallo basando en MII.

NOTA: Para utilizar el eth2 en el bonding primero hay que eliminarlo del OVS antes si se ejecutó el comando del anterior ejemplo, para ello se utilizará: "ovs-vsctl del-port ovsbr1 eth2"

Los puertos del bonding se presentan de esta manera dentro del OVS:


[root@kvm2 ~]# ovs-vsctl show
7f0948cf-6534-46b3-b462-cc2c57e857e4
    Bridge "ovsbr1"
        Port "ovsbr1"
            Interface "ovsbr1"
                type: internal
        Port "bond0"
            Interface "eth3"
            Interface "eth2"
    ovs_version: "2.1.2"


La información de configuración del puerto ya creado se puede obtener así:


[root@kvm2 ~]# ovs-vsctl list port bond0
_uuid               : c23f91b6-0e65-4ffb-8f6e-dca1e2f9d965
bond_downdelay      : 0
bond_fake_iface     : false
bond_mode           : balance-tcp
bond_updelay        : 0
external_ids        : {}
fake_bridge         : false
interfaces          : [0b62165d-98b8-4500-afb0-6b397624938e, 2a7fdc8c-2e45-4a5e-ac68-295e646c2054]
lacp                : active
mac                 : []
name                : "bond0"
other_config        : {bond-detect-mode=miimon, lacp-time=fast}
qos                 : []
statistics          : {}
status              : {}
tag                 : []
trunks              : []
vlan_mode           : []


Para comprobar más información sobre el método de funcionamiento del bond0 se puede utilizar el siguiente comando:


[root@kvm2 ~]# ovs-appctl bond/show bond0
---- bond0 ----
bond_mode: balance-tcp
bond-hash-basis: 0
updelay: 0 ms
downdelay: 0 ms
next rebalance: 2479 ms
lacp_status: configured

slave eth2: disabled
        may_enable: false

slave eth3: disabled
        may_enable: false


Existe un comando adicional que proporciona más información sobre el estado de los enlaces pertenecientes a un agregado LACP:


[root@kvm2 ~]# ovs-appctl lacp/show bond0
---- bond0 ----
        status: active
        sys_id: 00:0c:29:c5:09:fc
        sys_priority: 65534
        aggregation key: 6
        lacp_time: fast

slave: eth2: defaulted detached
        port_id: 6
        port_priority: 65535
        may_enable: false

        actor sys_id: 00:0c:29:c5:09:fc
        actor sys_priority: 65534
        actor port_id: 6
        actor port_priority: 65535
        actor key: 6
        actor state: activity timeout aggregation collecting distributing defaulted

        partner sys_id: 00:00:00:00:00:00
        partner sys_priority: 0
        partner port_id: 0
        partner port_priority: 0
        partner key: 0
        partner state:

slave: eth3: defaulted detached
        port_id: 7
        port_priority: 65535
        may_enable: false

        actor sys_id: 00:0c:29:c5:09:fc
        actor sys_priority: 65534
        actor port_id: 7
        actor port_priority: 65535
        actor key: 6
        actor state: activity timeout aggregation collecting distributing defaulted

        partner sys_id: 00:00:00:00:00:00
        partner sys_priority: 0
        partner port_id: 0
        partner port_priority: 0
        partner key: 0
        partner state:


NOTA: en este ejemplo no se formará el agregado LACP porque el Host no está conectado a un switch físico con LACP configurado

Por defecto, los puertos del OVS se encuentran configurados en modo trunk permitiendo todas las VLANs, pero si se desea configurar el agregado como un trunk que permita ciertas vlans con tag y la VLAN nativa (VLAN 1) y, a la vez, sea compatible con los switches físicos tradicionales, habrá que modificar los parámetros del puerto bond0 mediante este comando:

ovs-vsctl set port bond0 trunks=125,126 tag=1 vlan_mode=native-untagged

En este comando se indica los tags de VLANs permitidos (125 y 126), a la vez que se modifica el modo de comportamiento a "native-untagged", que es como funcionan los switches tradicionales. La variable "tag" en este caso indicaría la VLAN nativa. Como se verá más adelante, la variable tag lo que hace es eliminar el tag de la VLAN indicada, por eso se utiliza en la configuración de los puertos tipo "acceso", en los cuales se desea que el tráfico salga del puerto sin tag alguno.

La configuración del puerto quedará del siguiente modo:


[root@kvm2 ~]# ovs-vsctl list port bond0
_uuid               : 5a5f8f53-5e3b-4ca7-adfa-dae5faa65ec4
bond_downdelay      : 0
bond_fake_iface     : false
bond_mode           : balance-tcp
bond_updelay        : 0
external_ids        : {}
fake_bridge         : false
interfaces          : [b480b60b-50fa-49b1-bf99-2a6562e3ff85, b482f09e-1754-4543-a1f4-03143d5304b9]
lacp                : active
mac                 : []
name                : "bond0"
other_config        : {bond-detect-mode=miimon, lacp-time=fast}
qos                 : []
statistics          : {}
status              : {}
tag                 : 1
trunks              : [125, 126]
vlan_mode           : native-untagged


En lugar de modificar el puerto con la configuración del trunk, también se podrían haber indicado estos valores durante la creación del agregado de este modo:

ovs-vsctl add-bond ovsbr1 bond0 eth2 eth3 lacp=active bond_mode=balance-tcp trunks=125,126 tag=1 vlan_mode=native-untagged other_config:lacp-time=fast other_config:bond-detect-mode=miimon


Con los uplinks externos configurados, solo resta la configuración de los puertos de las máquinas virtuales. Para facilitar esta tarea y que las configuraciones sean mantenidas tras los rebotes del Host, se utilizarán las herramientas libvirt.

Lo primero será crear los virtual networks asociados al Open vSwitch, para ello se deberá crear un fichero XML con una definición parecida a esta:

vi xml-ovs


<network>
  <name>ovs-net</name>
  <forward mode='bridge'/>
  <bridge name='ovsbr1'/>
  <virtualport type='openvswitch'/>
  <portgroup name='Vlan1' default='yes'>
  </portgroup>
  <portgroup name='Vlan125'>
    <vlan>
      <tag id='125'/>
    </vlan>
  </portgroup>
  <portgroup name='Vlan126'>
    <vlan>
      <tag id='126'/>
    </vlan>
  </portgroup>
  <portgroup name='Trunk_all_Vlans'>
    <vlan trunk='yes'>
      <tag id='125'/>
      <tag id='126'/>
    </vlan>
  </portgroup>
</network>


En el fichero se indica que es un puerto vinculado al OVS creado antes ("<bridge name='ovsbr1'/>") y, además, se habilitan las VLANs a las cuales se podrán vincular las VMs creando portgroups. En este ejemplo se han creado dos portgroups de tipo "acceso" a las VLANs 125 y 126, y otro portgroup tipo trunk, por si se desea que la máquina virtual pueda realizar tag de los paquetes.

Hay que recordar que también se pueden añadir servicios como DHCP a la red creada por libvirt.

Con el XML ya se puede definir la red virtual con el siguiente comando:

virsh net-define xml-ovs

La red ya aparecerá pero se encontrará inactiva (hay que recordar que "default" es la red virtual por defecto de libvirt que hace NAT):


[root@kvm2 ~]# virsh net-list --all
Name                 State      Autostart     Persistent
--------------------------------------------------
default              active     yes           yes
ovs-net              inactive   no            yes


Para ponerla activa y que se active automáticamente en los inicios del Host:

virsh net-start ovs-net
virsh net-autostarovs-net 

Con estos comandos ya se puede ver lo siguiente:


[root@kvm2 ~]# virsh net-list --all
Name                 State      Autostart     Persistent
--------------------------------------------------
default              active     yes           yes
ovs-net              active     yes           yes


Una vez que la red virtual está creada, ya se pueden crear las máquinas virtuales y asociarlas a ellas:

virt-install --name=VM_OVS_test --arch=x86_64 --vcpus=1 --ram=512 --os-type=linux  --hvm --connect=qemu:///system  --vnc --noautoconsole --nodisk --boot cdrom

Se puede ver cómo no se ha indicado el parámetro "--network". Esto es porque para vincularlo al portgroup hay que modificar directamente el XML donde se encuentra la definición de la máquina, con lo que se apagará la máquina:

virsh shutdown VM_OVS_test o con virsh destroy VM_OVS_test.

Se puede comprobar el estado de la máquina:


[root@kvm2 ~]# virsh list --all
 Id    Name                           State
----------------------------------------------------
 -     VM_OVS_test                    shut off


Y más tarde se editará el fichero con este comando:

virsh edit VM_OVS_test

Se deberá modificar esta sección:


    <interface type='network'>
      <mac address='52:54:00:84:be:d8'/>
      <source network='default'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </interface>


de la siguiente manera


    <interface type='network'>
      <mac address='52:54:00:84:be:d8'/>
      <source network='ovs-net' portgroup='Vlan125'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </interface>


 Esta máquina virtual se ha vinculado a la VLAN 125. Para comprobar que el OVS puede "ver" el puerto de la vNIC de esta VM, se encenderá la máquina (virsh start VM_OVS_test)

Una vez que está encendida, se pueden volver a comprobar los puertos vinculados al OVS:


[root@kvm2 ~]# ovs-vsctl show
7f0948cf-6534-46b3-b462-cc2c57e857e4
    Bridge "ovsbr1"
        Port "ovsbr1"
            Interface "ovsbr1"
                type: internal
        Port "bond0"
            tag: 1
            trunks: [125, 126]
            Interface "eth2"
            Interface "eth3"
        Port "vnet0"
            tag: 125
            Interface "vnet0"
    ovs_version: "2.1.2"


Se puede ver cómo existe un nuevo puerto llamado vnet0, que será el interfaz de la VM, el cual se encuentra configurado como un puerto de acceso a la VLAN 125.

Configuración para funcionamiento por flujos con Controller


Las únicas configuraciones necesarias en el OVS (si se dispone de uno ya configurado) para que este sea gestionado por un Controller son la elección del modo de funcionamiento en caso de fallo de conexión ("standalone" frente a "secure") y la indicación de la IP y puerto del Controller, ya que el resto de configuración se llevará a cabo en el Controlador, y por tanto no será tratado aquí.

Si se parte de cero, habría que crear el bridge al cual vincular el OVS, y añadir las interfaces externas del mismo modo que se ha hecho antes.

El modo ante fallo se puede indicar de esta manera (en este caso el método "secure"):

ovs-vsctl set-fail-mode ovsbr1 secure

Y la IP y puerto del Controller para el Openflow:

ovs-vsctl set-controller ovsbr1 tcp:1.0.1.100:6633

Y para el OVSDB:

ovs-vsctl set-controller ovsbr1 tcp:1.0.1.100:6640

Es importante tener en cuenta que esa IP necesita ser alcanzable por el Host. Para ello utilizará su propia tabla de enrutamiento, es decir, no tiene por qué utilizar los interfaces vinculados al OVS, si no que puede usar los de gestión, por ejemplo.

Para comprobar que se ha conectado se puede revisar el parámetro "status" de la salida de este comando

ovs-vsctl list controller

Una cosa más a tener en cuenta cuando se utiliza un Controller es que, al crear las máquinas virtuales, ya no será necesario incluir en al configuración el portgroup al que pertenecen, ya que el camino que siga el paquete dependerá de los flujos instalados por el Controlador, no por las VLANs y resolución de MACs. Es por ello que la sección "interface" del XML de la máquina virtual se podría cambiar simplemente por esto:



    <interface type='network'>
      <mac address='52:54:00:84:be:d8'/>
      <source network='ovs-net'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </interface>


Existen comandos que pueden instalar flujos concretos directamente sobre el OVS, pero este despliegue debería disponer de un Controller complejo desde el que se pueda configurar el comportamiento del OVS (VLANs, bondings, etc).