En esta segunda parte del artículo configuraremos la dirección IP de servicio.
Configurando la IP de servicio
Como se mencionó en la primera parte, utilizando el módulo del kernel “carp” -que implementa el protocolo del mismo nombre-, haremos que una dirección IP esté asignada a dos nodos, de forma que si uno de ellos falla, el otro siga respondiendo las solicitudes.
La configuración consiste en una línea extra en el fichero /etc/rc.conf de cada nodo.
Para el primer nodo, ejecutaremos lo siguiente:
1 |
root@servidor-1 # echo 'ifconfig_em0_alias0="inet vhid 1 pass secret alias 192.0.2.100/32"' >> /etc/rc.conf |
Para el segundo nodo, ejecutaremos:
1 |
root@servidor-2 # echo 'ifconfig_em0_alias0="inet vhid 1 pass secret alias 192.0.2.100/32 advskew 100"' >> /etc/rc.conf |
Analicemos esta línea de forma genérica:
1 2 3 4 5 6 7 8 |
ifconfig_em0_alias0="<resto de parámetros>" inet vhid 1 pass secret alias 192.0.2.100/32 # Solo en el segundo nodo: advskew 100 |
La primera línea indica el uso de un alias de IP. Esto quiere decir que la NIC ’em0′ tendrá una IP adicional a la que ya tuviera configurada como IP principal (192.0.2.5/24 en nuestro caso). Todo lo que va entrecomillado son los parámetros que tomará este alias.
La segunda línea establece que vamos a utilizar la família “inet” (IPv4), y, si no se especifica, es el valor por defecto. Otra opción es “inet6” para el protocolo IPv6.
En la tercera línea se establece el identificador de host virtual. Cada dirección IP de servicio debe tener el mismo valor en todos los nodos donde se configure. Si tuvieramos más direcciones de servicio, este campo debe cambiar. Los valores permitidos son de 1 a 255.
La cuarta línea establece la contraseña de autenticación con la que se identificaran en un “vhid” los nodos participantes. Esta clave no establece ningún tipo de cifrado.
En la quinta línea se establece la dirección IP que establecemos cono dirección IP de servicio.
Por último, y solo para el nodo secundario, se fija el valor de “advskew” a 100. Este valor introduce un retraso a la hora de que el nodo se “anuncie” como nodo de CARP, modificando su orden de procedencia; y es útil cuando queremos forzar un nodo primario automáticamente o hay multiples nodos secundarios.
En este momento debe aplicarse el cambio en cada nodo.
Para el primer nodo ejecutaremos:
1 |
root@servidor-1 # ifconfig em0 inet vhid 1 pass secret alias 192.0.2.100/30 |
Y, en el segundo, ejecutaremos:
1 |
root@servidor-2 # ifconfig em0 inet vhid 1 pass secret alias 192.0.2.100/30 |
Podemos verificar el correcto arranque funcionamiento de varias formas.
Mediante el comando ifconfig em0 en cada nodo:
1 2 3 4 5 6 7 8 9 10 11 |
root@servidor-1:~ # ifconfig em0 em0: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> metric 0 mtu 1500 options=9b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM> ether 08:00:27:bf:d9:13 hwaddr 08:00:27:bf:d9:13 inet 192.0.2.5 netmask 0xffffff00 broadcast 192.0.2.255 inet 192.0.2.100 netmask 0xffffffff broadcast 192.0.2.100 vhid 1 nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL> media: Ethernet autoselect (1000baseT <full-duplex>) status: active carp: MASTER vhid 1 advbase 1 advskew 0 |
1 2 3 4 5 6 7 8 9 10 11 |
root@servidor-2:~ # ifconfig em0 em0: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> metric 0 mtu 1500 options=9b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM> ether 08:00:27:5b:00:66 hwaddr 08:00:27:5b:00:66 inet 192.0.2.6 netmask 0xffffff00 broadcast 192.0.2.255 inet 192.0.2.100 netmask 0xffffffff broadcast 192.0.2.100 vhid 1 nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL> media: Ethernet autoselect (1000baseT <full-duplex>) status: active carp: BACKUP vhid 1 advbase 1 advskew 100 |
Si observamos la última línea, en el primer servidor indica “CARP: MASTER” y, en el segundo, “CARP: BACKUP”.
Otra opción, donde además veremos más información como la elección del nodo “MASTER”, transiciones de estado, etc., es el fichero /var/log/messages de cada nodo:
1 2 3 |
root@servidor-1:~ # grep carp /var/log/messages Oct 9 08:14:29 servidor-1 kernel: carp: 1@em0: INIT -> BACKUP (initialization complete) Oct 9 08:14:32 servidor-1 kernel: carp: 1@em0: BACKUP -> MASTER (master timed out) |
1 2 3 |
root@servidor-2:~ # grep carp /var/log/messages Oct 9 08:11:19 servidor-2 kernel: carp: 1@em0: BACKUP -> MASTER (master timed out) Oct 9 08:15:23 servidor-2 kernel: carp: 1@em0: INIT -> BACKUP (initialization complete) |
Verificando el funcionamiento
Con la configuración ya realizada y activada y los nodos definidos en maestro y esclavo, llega el momento de hacer las pruebas necesarias para verificar que, realmente, el comportamiento es el adecuado.
Utilizaremos el comando “ping” desde algún sistema en la misma subred 192.0.2.100/24 para verificar que la dirección IP de servicio está disponible.
1 2 3 4 5 6 7 8 9 10 11 12 |
root@cliente-1:~# ping -c 5 192.0.2.100 PING 192.0.2.100 (192.0.2.100): 56 data bytes 64 bytes from 192.0.2.100: icmp_seq=0 ttl=64 time=0.301 ms 64 bytes from 192.0.2.100: icmp_seq=1 ttl=64 time=0.419 ms 64 bytes from 192.0.2.100: icmp_seq=2 ttl=64 time=0.621 ms 64 bytes from 192.0.2.100: icmp_seq=3 ttl=64 time=0.379 ms 64 bytes from 192.0.2.100: icmp_seq=4 ttl=64 time=0.281 ms --- 192.0.2.100 ping statistics --- 5 packets transmitted, 5 packets received, 0.0% packet loss round-trip min/avg/max/std-dev = 0.281/0.400/0.621/0.121 ms |
La primera prueba real que haremos será verificar qué ocurre cuando el nodo activo deja de estar disponible por reinicio o perdida de corriente eléctrica; y la segunda consistirá en simular un fallo en la interfaz de red.
En caso de reinicio del nodo activo
Conectados a ambos nodos, reiniciaremos el maestro y en el secundario observaremos qué ocurre:
1 |
root@servidor-1:~# shutdown -r now |
1 2 3 |
root@servidor-2:~# tail -f /var/log/messages [...] Oct 9 08:28:19 servidor-2 kernel: carp: 1@em0: BACKUP -> MASTER (master timed out) |
El nodo esclavo pasa a ser el maestro, y la salida del comando ifconfig así lo muestra:
1 2 3 4 5 6 7 8 9 10 11 |
root@servidor-2:~# ifconfig em0 em0: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> metric 0 mtu 1500 options=9b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM> ether 08:00:27:5b:00:66 hwaddr 08:00:27:5b:00:66 inet 192.0.2.6 netmask 0xffffff00 broadcast 192.0.2.255 inet 192.0.2.100 netmask 0xffffffff broadcast 192.0.2.100 vhid 1 nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL> media: Ethernet autoselect (1000baseT <full-duplex>) status: active carp: MASTER vhid 1 advbase 1 advskew 100 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
root@cliente-1:~# ping -D 192.0.2.100 PING 192.0.2.100 (192.0.2.100): 56 data bytes 64 bytes from 192.0.2.100: icmp_seq=0 ttl=64 time=0.390 ms 64 bytes from 192.0.2.100: icmp_seq=1 ttl=64 time=0.426 ms 64 bytes from 192.0.2.100: icmp_seq=2 ttl=64 time=0.387 ms 64 bytes from 192.0.2.100: icmp_seq=3 ttl=64 time=0.657 ms ### REINICIO EJECUTADO EN ESTE PUNTO ### 64 bytes from 192.0.2.100: icmp_seq=6 ttl=64 time=0.393 ms 64 bytes from 192.0.2.100: icmp_seq=7 ttl=64 time=0.457 ms 64 bytes from 192.0.2.100: icmp_seq=8 ttl=64 time=0.334 ms ^C --- 192.0.2.100 ping statistics --- 9 packets transmitted, 7 packets received, 22.2% packet loss round-trip min/avg/max/std-dev = 0.334/0.435/0.657/0.097 ms |
Como puede observarse, la dirección IP virtual no ha estado disponible durante unos 3 segundos.
En caso de pérdida de la interfaz de red física
Es posible simular la pérdida de una interfaz de red mediante el siguiente comando:
1 |
root@servidor-1:~# ifconfig em0 down |
Podremos comprobar que el nodo esclavo detecta dicho fallo en el maestro:
1 2 3 |
root@servidor-2:~# tail -f /var/log/messages [...] Oct 9 08:37:27 servidor-2 kernel: carp: 1@em0: BACKUP -> MASTER (master timed out) |
Al igual que en el caso anterior, el segundo servidor pasa a tener estado MASTER :
1 2 3 4 5 6 7 8 9 10 11 |
root@servidor-2:~# ifconfig em0 em0: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> metric 0 mtu 1500 options=9b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM> ether 08:00:27:5b:00:66 hwaddr 08:00:27:5b:00:66 inet 192.0.2.6 netmask 0xffffff00 broadcast 192.0.2.255 inet 192.0.2.100 netmask 0xffffffff broadcast 192.0.2.100 vhid 1 nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL> media: Ethernet autoselect (1000baseT <full-duplex>) status: active carp: MASTER vhid 1 advbase 1 advskew 100 |
En caso de deshabilitar la interfaz de red en el segundo nodo mediante
1 |
root@servidor-2:~# ifconfig em0 down |
Al no tener ninguna interfaz habilitada (ni en el primer nodo ni en el segundo), el servicio dejaría de ser prestado.
Forzando un nodo como principal
Es posible que deseemos que un nodo concreto siempre sea el principal.
Para ello podemos utilizar una configuración automática que consiste en añadir una línea al fichero /etc/sysctl.conf del nodo que deseemos que lo sea:
1 |
root@servidor-1 # echo "net.inet.carp.preempt=1" >> /etc/sysctl.conf |
Si no queremos reiniciar el nodo en estos momentos, activaremos el cambio de la siguiente forma:
1 |
root@servidor-1 # sysctl -w net.inet.carp.preempt=1 |
Tambien podemos fijar temporalmente un nodo como principal utilizando el siguiente comando en el nodo principal:
1 |
root@servidor-1 # ifconfig em0 vhid 1 state backup |
Notas finales
Por simplicidad a lo largo de estos dos artículos relacionados con la dirección IP de servicio, hemos utilizado una única interfaz de red física tanto para la gestión del servidor como para prestar el servicio.
Es recomendable utilizar múltiples interfaces de red físicas, cada una para una tarea. Idealmente la interfaz de red física “em0” se utilizará para prestar el servicio, mientras que otra interfaz de red “em1” será la utilizada para administrar el servidor y donde CARP intercambia el estado de ambos nodos.
De igual modo, por simplicidad, sólo hemos utilizado una conexión para cada tarea. En entornos donde prime la alta disponibilidad debe utilizarse un doble enlace de red mediante agregación de enlace, utilizando tarjetas de red independientes; en un futuro publicaré sobre ello.
Esta entrada también está disponible en:
English (Inglés)