Networking Server

IP Network Multipathing

Introducción

Este corto documento busca dar a conocer como ofrecer una redundancia para la capa 1 y 2 del modelo OSI, cuando tenemos una estación con el sistema operativo OpenBSD.

La duda surgió mientras configuraba en Solaris el IP NETWORK MULTIPATHING y me daba cuenta de las ventajas que ofrecía para un servidor en producción por ejemplo.

Como ya sabia como hacerlo en Linux, quise averiguar de que forma podría implementar algo similar en OpenBSD, este documento es el resultado.

Como siempre, dudas, comentarios, observaciones o cualquier otro tipo de comunicados, son bienvenidos al correo electrónico.

¿Que es IP Network Multipathing (IPMP)?

Pensemos en un servidor que ofrece servicios a una red y esta conectado 7×24 (toda la semana, día y noche).

Supongamos que por error alguien rompe el cable que conecta la tarjeta de red principal del servidor o supongamos que el cable se daña por algún motivo, que sucedería?

  • El servidor dejaría de prestar los servicios a la red.
  • Los clientes se enojarían mucho.
  • Tendríamos que comprar una tarjeta nueva o buscar un reemplazo en el menor tiempo posible.
  • Quizás perdamos mucho tiempo buscando la causa del mal funcionamiento del servidor, aveces un cable dañado no es tan fácil de detectar.

Pensemos que no solo puede ser el cable que conecta nuestra tarjeta de red (NIC), puede ser que nuestra NIC se dañe, por que la energía subió o porque la energía bajó o porque era el tiempo de que la tarjeta se dañara. Sucedería exactamente lo mismo que describimos lineas arriba.

La solución?

Crear un arreglo de tarjetas que estén conectadas al mismo segmento de red y que en conjunto se comporten como una sola (con una misma configuración de red) y habilitar un mecanismo que permita reparar automáticamente la tarjeta dañada por otra y por lo tanto mejore el tiempo de respuesta para tales eventualidades. Eso es IPMP.

center|thumb|400px|Configuración IPMP con tres interfaces de red

En la mayoría de los sistemas operativos existen mecanismos para lograr esto y OpenBSD no es la excepción. Buscando un poco encontré que una posible solución es usando el driver trunk1 que viene en el kernel por defecto y permite hacer lo mencionado y un poco más.

Un sistema IPMP detecta que una interfaz ha caído realizando pruebas hacia esa interfaz o con ayuda del controlador de la tarjeta que le informa que efectivamente el dispositivo esta deshabilitado. Trunk en OpenBSD solo soporta el chequeo por estado de enlace, esto quiere decir que es el controlador trunk el que le informa al kernel de los acontecimientos de las tarjetas de red. Esto no quiere decir que no se pueda chequear una interfaz haciendo pruebas (pings o similares), por ejemplo se podría crear un pequeño script para el demonio ifstated para que realizara algo similar, pero no es el objetivo de este documento.

Trunk

Aquí están las posibles configuraciones para trunk, esta información se encuentra en el manual al que puedes acceder con el comando:

Manual de Trunk

$ man trunk

Trunk permite configurar 3 protocolos: roundrobin, failover y loadbalace.

Por defecto si se crea una interfaz trunk, el protocolo seleccionado es roundrobin.

Roundrobin

Este protocolo distribuye todo el trafico saliente entre los puertos que tenga activos, según una programación de saltos, esto quiere decir que durante un tiempo va a enviar información por una interfaz de red, luego de otro tiempo enviará la información por la otra y así hasta completar el ciclo con cada una de las interfaces de red disponibles. El sistema sigue recibiendo trafico de datos por todas las interfaces de red que se tengan disponibles.

Failover

Este protocolo es el que usamos para ejemplificar trunk en este documento, lo que se logra es definir una interfaz maestra y una serie de interfaces esclavas.

Todo el trafico saliente y entrante se manejará por la interfaz maestra hasta que suceda algo, esto quiere decir hasta que ocurra un fallo en el cableado o en el dispositivo físico como tal. Cuando esto suceda lo que el trunk hará es configurar una de las interfaces esclavas para que tome la posición de la maestra y el trafico pueda seguir circulando de forma normal, una vez la interfaz caída este de vuelta, el trunk volverá a configurar las cosas como estaban en un inicio. Esto será transparente para el usuario y nos ofrecerá un esquema de redundancia bastante útil.

Loadbalance

Este protocolo usas “hashs” para identificar el tipo de trafico a través de las interfaces disponibles, una vez lo tenga identificado, tratará de balancearlo para que no exista sobrecarga en ninguna de las interfaces y por lo tanto los usuarios experimenten mejoras en el rendimiento de los servicios instalados.

El trafico entrante seguirá su flujo normal a través de cualquiera de las interfaces que se encuentren disponibles.

None

Este protocolo lo que hace realmente es deshabilitar el funcionamiento del trunk, sin eliminar las interfaces creadas.

Configurando Trunk en OpenBSD

Para ejemplificar la configuración de un servicio IPMP en OpenBSD, tendremos un servidor con dos interfaces de red conectadas al mismo segmento y un equipo cliente desde donde se hacen las pruebas.

Configurando el failover

Lo primero que debemos asegurarnos es que las interfaces estén disponibles (hayan sido reconocidas por el núcleo) y no estén configuradas. Para eso usamos el comando ifconfig y eliminamos los archivos que comiencen con hostname en el directorio /etc.

Borrado de interfaces

# ifconfig -a
# rm /etc/hostname.*

Obviamente antes de borrar la configuración, haga una copia de seguridad de los archivos que considere necesarios por si las cosas no salen bien.

Voy a asumir que mis interfaces se llaman sis0 y rl0.

Lo segundo que hago es subir las interfaces para que se puedan usar:

Activar interfaces

# ifconfig sis0 up
# ifconfig rl0 up

Creando la interfaz trunk

Ahora creamos una interface trunk (es necesario) para que se haga pasar por las otras dos y pueda controlar el trafico de acuerdo a los parámetros que le configuremos.

Configuración de trunk

# ifconfig trunk0 trunkproto failover trunkport sis0 \
trunkport rl0 172.16.1.103 netmask 255.255.255.0 up

Lo que se hace aquí es definir cual será la interfaz creada (trunk0), el protocolo a usar (failover) y cuales serán las interfaces que usará (sis0 y rl0), los otros parámetro es la dirección IP general a usar y la mascara de red.

La información de IP y MASCARA es recomendable que se configuren al mismo tiempo que se crea la interfaz porque de lo contrario no tendremos ninguna interfaz activa en caso de que estemos haciendo la configuración remotamente.

Trunk definirá como interfaz maestra la que se escriba primero en la línea de comandos después de definir el protocolo a usar, para este ejemplo sis0.

Verificando la interfaz trunk

Chequeo de interfaces

$ ifconfig

lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 33224
 groups: lo
 inet 127.0.0.1 netmask 0xff000000
 inet6 ::1 prefixlen 128
 inet6 fe80::1%lo0 prefixlen 64 scopeid 0x5
sis0: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1500
 lladdr 00:fe:e1:ba:d0:a7
 trunk: trunkdev trunk0
 media: Ethernet autoselect (100baseTX full-duplex)
 status: active
 inet6 fe80::2fe:e1ff:feba:d0a7%sis0 prefixlen 64 scopeid 0x1
rl0: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1500
 lladdr 00:fe:e1:ba:d0:a7
 trunk: trunkdev trunk0
 media: Ethernet autoselect (100baseTX full-duplex)
 status: active
 inet6 fe80::208:a1ff:fe85:dec4%rl0 prefixlen 64 scopeid 0x2
pflog0: flags=0<> mtu 33224
enc0: flags=0<> mtu 1536
trunk0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
 lladdr 00:fe:e1:ba:d0:a7
 trunk: trunkproto failover
 trunkport rl0 active
 trunkport sis0 master,active
 groups: trunk
 media: Ethernet autoselect
 status: active
 inet6 fe80::2fe:e1ff:feba:d0a7%trunk0 prefixlen 64 scopeid 0x6
 inet 172.16.1.103 netmask 0xffffff00 broadcast 172.16.1.255

$

Podemos observar que todas las interfaces quedan con la misma dirección MAC y solo queda activa una dirección IP, para el ejemplo: 172.16.1.103.

Probando la configuración trunk failover

Podemos usar la herramienta systat o cualquier otra que nos vigile las interfaces:

Monitoreo de interfaces

$ systat -w 1 ifstat

2 users Load 0.17 0.15 0.08 Sat Jul 21 19:47:17 2007

Iface State Ibytes Ipkts Ierrs Obytes Opkts Oerrs Colls
sis0   up:U   0      3     0     440    4     0     0
rl0    up:U   0      0     0       0    0     0     0
pflog0 dn     0      0     0       0    0     0     0
enc0   dn     0      0     0       0    0     0     0
lo0    up     0      0     0       0    0     0     0
trunk0 up:U 194      3     0     496    4     0     0
Totals      194      6     0     936    8     0     0

Observemos que la salida y entrada de trafico solo esta en sis0, la interface maestra del trunk. Para probar el funcionamiento vamos a realizar un ping sostenido a la ip 172.16.1.103 desde otro computador y vamos a desconectar el cable maestro observando como se comporta el ping y las estadísticas desde el systat.

Ping de prueba

C:Documents and Settingsotros>ping -t 172.16.1.103

Haciendo ping a 172.16.1.103 con 32 bytes de datos:
Respuesta desde 172.16.1.103: bytes=32 tiempo<1m TTL=255
Respuesta desde 172.16.1.103: bytes=32 tiempo<1m TTL=255
Respuesta desde 172.16.1.103: bytes=32 tiempo<1m TTL=255
Respuesta desde 172.16.1.103: bytes=32 tiempo<1m TTL=255
Respuesta desde 172.16.1.103: bytes=32 tiempo<1m TTL=255
Respuesta desde 172.16.1.103: bytes=32 tiempo<1m TTL=255
Respuesta desde 172.16.1.103: bytes=32 tiempo<1m TTL=255
Tiempo de espera agotado para esta solicitud.
Respuesta desde 172.16.1.103: bytes=32 tiempo<1m TTL=255
Respuesta desde 172.16.1.103: bytes=32 tiempo<1m TTL=255
Respuesta desde 172.16.1.103: bytes=32 tiempo<1m TTL=255
Respuesta desde 172.16.1.103: bytes=32 tiempo<1m TTL=255
Respuesta desde 172.16.1.103: bytes=32 tiempo<1m TTL=255
Estadísticas de ping para 172.16.1.103:

 Paquetes: enviados = 13, recibidos = 12, perdidos = 1 (7% perdidos),

Tiempos aproximados de ida y vuelta en milisegundos:
 Mínimo = 0ms, Máximo = 0ms, Media = 0ms

Y estas son las estadísticas:

Estadisticas de interfaces

2 users Load 0.17 0.15 0.08 Sat Jul 21 19:48:45 2007

Iface State Ibytes Ipkts Ierrs Obytes Opkts Oerrs Colls
sis0   up:D   0      0     0     0      0     0     0
rl0    up:U   0      2     0   334      3     0     0
pflog0 dn     0      0     0     0      0     0     0
enc0   dn     0      0     0     0      0     0     0
lo0    up     0      0     0     0      0     0     0
trunk0 up:U 120      2     0   376      3     0     0
Totals      120      4     0   710      6     0     0

Se puede observar que el ping se cae por un tiempo (1 paquete) y luego se reestablece la comunicación, inmediatamente el trunk configura la interface rl0 como maestra para que reemplace la interfaz desconectada.

Si se vuelve a conectar el cable de la interfaz sis0, se podrá observar el cambio nuevamente desde las estadísticas.

Guardando la configuración

Como los cambios hechos desde la línea de comandos son temporales, debemos guardar nuestra configuración. Eso lo hacemos de la siguiente forma:

Nos aseguramos de configurar los tres archivos correspondientes a las interfaces sis0, rl0 y trunk0 en el directorio /etc.

Configuración de interfaces

# cat /etc/hostname.sis0
up

# cat /etc/hostname.rl0
up

# cat /etc/hostname.trunk0
trunkproto failover trunkport sis0 trunkport rl0 172.16.1.103  
netmask 255.255.255.0 up

Obviamente debes de configurar los datos según los parámetros de tu red.

Configurando roundrobin y loadbalace

Para configurar los otros protocolos es un procedimiento similar, lo que hay que tener en cuenta es como funcionará el arreglo que hagamos.

Lo único que habría que cambiar es en la línea de la interfaz trunk:

Configuración de roundrobin y loadbalance

  - ifconfig trunk0 trunkproto [[PROTOCOLO]] trunkport sis0 
trunkport rl0 172.16.1.103 netmask 255.255.255.0 up

y reemplazamos PROTOCOLO por roundrobin o por loadbalace según sea el caso.

Un ejemplo de estadísticas con el balanceo de carga se observa con esta salida:

Estadísticas de interfaces

3 users Load 2.29 1.18 0.51 Tue Jul 24 18:13:25 2007

Iface State Ibytes Ipkts Ierrs Obytes Opkts Oerrs Colls
sis0   up:U     0   635     0  179406  1219   0     0
rl0    up:U     0    24     0    7152    24   0     0
pflog0 dn       0     0     0       0     0   0     0
enc0   dn       0     0     0       0     0   0     0
lo0    up       0     0     0       0     0   0     0
trunk0 up:U 52794   659     0  203960  1243   0     0
Totals      52794  1318     0  390518  2486   0     0

Se puede observar que ambas interfaces están sacando datos, esto se debe a que algunos protocolos los esta encaminando por sis0 y otros por rl0. Para el ejemplo, hice pruebas con SSH, FTP Y WEB al mismo tiempo desde dos maquinas diferentes que actuaban como clientes.

Fuentes y Enlaces


Personal Tools