Hace un tiempo tuve que implementar un balanceo de carga con alta disponibilidad y me resultó una tarea interesante. Cuento un poco como lo hice.
Vamos a implementar un cluster de alta disponibilidad (ha) que mantenga un servicio de balanceo entre
dos servidores, en este caso y a modo de ejemplo dos servidores Web.
IP Virtual: 192.168.50.205
IP Nodo 1 ha: 192.168.50.215
IP Nodo 2 ha :192.168.50.225
IP servidor Web1: 192.168.50.211
IP servidor Web2: 192.168.50.221
Necesitaremos:
- Alta disponibilidad : Heartbeat
Con este paquete se establece una comunicacion entre los miembros del cluster (nodos) y se
definen unos servicios que se quieran poner en alta disponibilidad. Uno de los nodos será el master y
será quien dé el servicio. Si se cae, el/los otros nodos tomarán el servicio hasta que se recupere.
Nosotros vamos a poner como servicio el ldirectord que es el que se encarga de balancear la carga
sobre los servidores Web.
Es el paquete que propiamente proporciona el balanceo de carga. Se configura definiendo una
IP Virtual que el servicio se encarga de mantener a la “escucha” y repartir las demandas sobre los
servidores reales (web).
Como el balanceador tiene que hacer forwarding de las peticiones sobre la IP virtual a las reales, es
requisito habilitar en el kernel esta característica:
# /etc/sysctl.conf
net.ipv4.ip_forward = 1
Instalación :
apt-get install heartbeat ldirectord (debian)
yum heartbeat ldirectord install (RedHat)
Configuración:
Ldirectord
Lo primero y como queremos que este servicio sea controlado por heartbeat y que sea éste quien lo
arranque, lo deshabilitamos del boot de la máquina:
update_rc.d ldirectord remove (debian)
chkconfig ldirectord off (RedHat)
Creamos el fichero de configuración : ldirectord.cf y lo ubicamos en /etc/ha.d/conf
En este caso va a tener la pinta:
(No entro a describir todos los parámetros puesto que es extensísmo, consultar man)
# vim /etc/ha.d/ldirectord.cf
checktimeout=10
checkinterval=2
autoreload=no
logfile="/var/log/ldirectord.log"
quiescent=yes
virtual=192.168.50.205:80
real=192.168.50.211:80 gate
real=192.168.50.221:80 gate
fallback=127.0.0.1:80 gate
#protocolo que se gestionará
service=http
#Scheduler es el algoritmo usado para hacer el reparto de carga rr=RoundRObin, lc= least
conections... etc (ver man ldirectrd)
scheduler=rr
protocol=tcp
#Checktype es la “prueba de vida” que hará el ldirectord para saber si el servidor real esta vivo, en
este caso negotiate que comprobará una respuesta (hay otros por ej connection..)
checktype=negotiate
#archivo que se solicitará en los servidores web para la prueba de vida, debe estar en DocumentRoot
request="test/ldirector.html"
#El archivo debe contener unicamente esta linea de texto para confirmar la validez del sitio
web
receive="Si, estoy vivo!"
Con esto el ldirectord creará una IP virtual 192.168.50.205:80 que repartirá a los servidores reales por
el método Direct Routing (gate). Existen 3 métodos: NAT ,Direct Routing e IP Tunneling.
Las peticiones entrantes llegan a la IP virtual y son reenviadas hacia los servidores reales
cambiando la IP destino (NATeo). La respuesta de los servidores reales vuelve al balanceador
quien de nuevo cambia la IP y reenviía al petcionario. Como todo el tráfico pasa por el
balanceador suponde normalmente un cuello de botella para el cluster.
LVS manda las peticiones a los servidores reales a través de un tunel IP y los servidores
responde directamente al peticionario a través de sus tablas de enrutamiento (necesitan pues de
gateway).
Los paquetes del peticionario son enviados directamente a los servidores reales (forwarding).
Como el paquete IP no es modificado los servidores reales para aceptarlo necesitan una interfaz
virtual no-ARP ( para evitar conflictos de red al tener la misma IP que la virtual). La respuesta
se envía directamente al peticionario desde el servidor real.
Lo que hace Ldirectord:
Conecta cada 10 segundos (checkinterval) con cada servidor real y pide la prueba
192.168.50.205:80/test/ldirector.html (request/receive). Si no recibe la cadena que pusimos en ese
fichero (“Si, estoy vivo”) en un tiempo de 2 segundos (checktimeout), eliminara ese servidor del “pool”
de servidores disponilbles a los que mandar peticiones. Estará de nuevo disponible cuando el test sea
exitoso.
Copiamos este fichero de configuracion ldirectord.cf en /etc/ha.d/conf del resto de nodos
Una vez definido el servicio de balanceo, vamos a ponerlo en Alta Disponibilidad a través de
HeartBeat.
Hearbeat
Para establecer la comunicación entre los nodos hay que definir un método de autenticación que se
hace a través del ficherito /etc/ha.d/authkeys
#vim /etc/ha.d/authkeys
auth 1
1 md5 EstaEsmiClaveSecreta
Este fichero que contiene la clave de autenticacion y el método de encriptación (md5) lo protegemos
para que solo lo lea root:
#chmod 600 /etc/ha.d/authkeys
Otra cosa a tener en cuenta es que los nodos se “conozcan”, es decir editar /etc/hosts en ambos y poner
los nombres de los nodos del cluster. Poner el nombre que devuelva el comando : uname -n
# vi /etc/hosts
192.168.50.215 Nodo1 NODO1
192.168.50.225 Nodo2 NODO2
Definimos el cluster: /etc/ha.d/ha.cf (bastante simplificado)
#Fichero de log
logfile /var/log/ha-log
logfacility local0
keepalive 2
deadtime 30
initdead 120
# Tarjeta por la que se realizará el broadcast
bcast eth0
udpport 694
auto_failback on
#nombre de host (uname -n) de los equipos directores
node Nodo01
node Nodo02
Copiamos este fichero en /etc/ha.d/ del resto de nodos.
Nota: La definicion del cluster se puede simplificar bastante con la herramienta gráfica hb_gui
Por último ya solo queda definir los servicios en alta disponiblidad que en nuestro ejemplo será el
ldirectord.
Los recursos se definiran en /etc/ha/haresources
El formato viene bien descrito en los comentarios del propio fichero. En este ejemplo va a tener la
pinta:
#vi /etc/ha.d/haresources
Nodo01 IPaddr2::192.168.50.205/24/eth0/192.168.50.255 ldirectord::ldirectord.cf
LVSSyncDaemonSwap::master
El ficherito haresources será identico en todos los nodos del cluster. La referencia al nombre del nodo
es el nodo que será el preferido para actuar como master (en este caso el Nodo1).
El formato que vemos es:
Nodopreferido IP_para_el recurso1 recurso:parametro1.......
En el formato de la IP se ha especificado IP/mascara/interfaz/broadcast.
El recurso LVSSyncDaemonSwap es el demonio que habilita las capacidades de la alta disponibilidad.
Sincronización en te los nodos, commutación...
Configuración de los servidores reales
Debemos configurar los servidores reales de modo que acepten el forwarding que les envía el
balanceador LVS por la IP virtual.
Tenemos que configurar un alias virtual que levante la direccion virtual y además hacer que sea “sorda”
a ARP de modo que no desvele la IP y no entre en conflicto.
Los cambios a realizar en los parámetros del kernel de los sevidores reales serán:
# /etc/sysctl.conf
#habilitar la opcion de ignorar ARP
net.ipv4.conf.all.ARP_ignore = 1
#No responder a las solicitudes de ARP si la direccion IP esta configurada sobre el interfaz
“lo” (loopback) o cualquier otro interfaz virtual eth0:0
net.ipv4.conf.eth0.ARP_ignore = 1
#Habilitar la opcion de anuncio ARP
net.ipv4.conf.all.ARP_announce = 2
Como la fuente IP de la peticon ARP entrará en la cache ARP del destino esto tiene el efecto de
anunciar esta direccion. Esto no es deseable para “lo” o cualquier otro interfaz virtual ethx:0 de los
servidores reales. Usando este valor haremos que los servidores reales siempre que reciban una peticion
ARP usen la IP real como fuente de la peticion ARP.
net.ipv4.conf.eth0.ARP_announce = 2
Y cargamos los cambios con:
# sysctl -p
Una vez hechos estos cambios ya tendremos la posibilidad de levantar el interfaz virtual que nos sirva
la IP virtual sin conflictos.
Definimos en los servidores reales sobre lo, la interfaz virtual lo:0 añadiendo:
# /etc/network/interfaces
...
iface lo inet loopback
auto lo:0
iface lo:0 inet static
address 192.168.50.205
netmask 255.255.255.255
Esta interfaz será la encargada de recibir el forwarding del balanceador.
Gateway:
Hay que tener en cuenta que la respuesta de los servidores reales será directa a los usuarios con lo cual
estos deben tener el router en el default gateway.
Con esto ya queda acabada la configuración.
Finalmente, ya solo queda arrancar el cluster ejecutando en todos los nodos del cluster :
# service hearbeat start
.... Y a depurar, claro.