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.