HeartBeat y Drbd es una gran solución para crear un cluster de servidores con ‘Alta Disponibilidad’. Podríamos aplicarlo para cualquier tipo de servidor que necesite alta disponibilidad, como un servidor web, una base de datos o una PBX Asterisk.
En este HowTo vamos a instalar un cluster de dos asterisk conectados a un redfone, el cual nos permite tener varias centralitas conectadas a un primario (o varios primarios) y no tener que usar varias tarjetas de telefonía.
En un Call Center donde el sistema debe ser altamente confiable, no se puede dar el lujo de que si cae un servidor asterisk se pare el servicio. Si sucede esto con tarjetas de telefonía y una instalación sin HA, aún teniendo otro asterisk igual configurado, tendríamos que pasar toda la configuración, logs y migrar al nuevo hardware las tarjetas PCI físicamente. Lo cual puede tardar un buen tiempo en ser realizado.
Montando un cluster de asterisk en HA, podríamos tener dos sevidores compartiendo una IP virtual (Heartbeat) y sincronizando los datos de sus directorios (con Drbd) de forma que si el servidor primario se cae, el segundo automáticamente coge esa IP y empieza a dar servicio (Heartbeat). Y todo esto con una parada de servicio de unos 5 segundos.
Así que no mas caidas de servicio y no mas llamadas en medio de la noche
.
Los distribución usada será Ubuntu server (LTS. hardy o Lucid) ya que es a la que estoy mas acostumbrado, pero valdría perfectamente para Debian. Se presuponen conocimientos de Asterisk y GNU/Linux.
DRBD (Distributed Replicated Block Device). En pocas palabras, DRBD es un arreglo de software parecido a un RAID1 pero en red, el cual construye un mirror de discos sobre LAN. Sincroniza dos particiones de dos servers diferentes. No es recomendable sincronizarlos a través del switch o router de tu red ya que genera muchísimas peticiones. Deberían tener cada server dos interfaces de red. Una para la red y otra con un cable cruzado directamente entre los dos servers para el Drbd. De esta forma no colapsaremos la red.
Heartbeat hace referencia a un servicio o un ping periódico para comprobar que el sistema está levantado y corriendo. Mantendrá de esta forma 2 o mas nodos sincronizados bien por puerto serie o por red (UDP).
Se pueden hacer configuraciones avanzadas, pero en este caso usaremos un Hearbeat de 2 nodos.
Empezamos instalando los componentes:
Drbd
Antes de nada explicar que durante la instalación debemos particionar ambos servidores exactamente igual y tendremos que crear una partición extra que en mi caso se va a llamar ‘replica’ que es la que va a tener los datos replicados en ambos servidores. En mi caso he hecho una instalacion con LVM y he creado un raiz de 20 GB y replica de 48 GB. La partición ‘replica’ la formateamos en ext3 o ext4 y la dejamos sin montar.
Los equipos se van a llamar ‘asterisk1′ y ‘asterisk2′. En primer lugar configuramos el segundo interfaz de red para que haga Drbd directo a traves de un cable cruzado y no pase por el switch de nuestra red ya que pordría colapsarla. Ya vamos avisando de que será necesario un servidor con 3 interfaces de red. Uno para la red, otro para el drbd y otro para el Redfone.
Estos datos serían los adecuados para mi red. Seguramente deberás adaptarlos a la tuya.
En el /etc/network/interfaces de astetisk1 ponemos:
# The loopback network interface
auto lo
iface lo inet loopback
# The primary network interface
auto eth0
iface eth0 inet static
address 192.168.3.141
netmask 255.255.255.0
network 192.168.3.0
broadcast 192.168.3.255
gateway 192.168.3.1
# dns-* options are implemented by the resolvconf package, if installed
dns-nameservers 192.168.3.103 192.168.3.203
dns-search telemarketing.es
auto eth1
iface eth1 inet static
address 192.168.10.141
netmask 255.255.255.0
network 192.168.10.0
broadcast 192.168.10.255
Y en el /etc/network/interfaces de asterisk2:
# The loopback network interface
auto lo
iface lo inet loopback
# The primary network interface
auto eth0
iface eth0 inet static
address 192.168.3.142
netmask 255.255.255.0
network 192.168.3.0
broadcast 192.168.3.255
gateway 192.168.3.1
# dns-* options are implemented by the resolvconf package, if installed
dns-nameservers 192.168.3.103 192.168.3.203
dns-search telemarketing.es
auto eth1
iface eth1 inet static
address 192.168.10.142
netmask 255.255.255.0
network 192.168.10.0
broadcast 192.168.10.255
La primera interfaz de red es la del servidor en si y la segunda la del drbd.
También nos aseguramos de que ambos puedan resolver al otro (sin ningún servidor DNS por medio). Para ello editamos en ambos el /etc/hosts y definimos la entrada del otro.
En el /etc/hosts de asterisk1 ponemos:
127.0.0.1 localhost
192.168.3.141 asterisk1.tudominio.es asterisk1
192.168.10.142 asterisk2.tudominio.es asterisk2
Y en el /etc/hosts de asterisk2 ponemos:
192.168.3.142 asterisk2.tudominio.es asterisk2
192.168.10.141 asterisk1.tudominio.es asterisk1
En Karmic y Lucid es muy fácil instalar Drbd. Ya no hay que construir el módulo con m-a. En las versiones recientes ya viene compilado de serie, así que tan solo lo tenemos que cargarlo con modprobe o modconf:
# modprobe drbd
E instalamos las utilidades:
# aptitude install drbd8-utils
El archivo de configuración se encuentra en /etc/drbd.conf este debería de ser idéntico en los dos servidores.
Como siempre, primero procedemos a hacer un backup ‘cp /etc/drbd.conf /etc/drbd.conf.backup’ y lo editamos:
#
# At most ONE global section is allowed.
# It must precede any resource section.
#
global {
usage-count yes;
}
common {
syncer { rate 100M; }
}
#
# this need not be r#, you may use phony resource names,
# like "resource web" or "resource mail", too
#
resource r0 {
protocol C;
startup {
wfc-timeout 5;
degr-wfc-timeout 3;
}
on asterisk1 {
device /dev/drbd0;
disk /dev/mapper/asterisk1-replica;
address 192.168.10.141:7788;
meta-disk internal;
}
on asterisk2 {
device /dev/drbd0;
disk /dev/mapper/asterisk2-replica;
address 192.168.10.142:7788;
meta-disk internal;
}
}
Esta es mi configuración. Mira los recursos que cito para ajustarla a la tuya.
Una vez editado los archivos de config reiniciamos ambos servidores.
Ahora procedemos a crear la particion virtual /dev/drbd0 en ambos servidores:
# drbdadm create-md r0
y nos saldrá un mensaje de éxito:
initialising activity log
NOT initialized bitmap
New drbd meta data block sucessfully created.
success
Si nos sale un error como este:
md_offset 48259657728
al_offset 48259624960
bm_offset 48258150400
Found ext3 filesystem which uses 47128576 kB
current configuration leaves usable 47127100 kB
Device size would be truncated, which
would corrupt data and result in
'access beyond end of device' errors.
You need to either
* use external meta data (recommended)
* shrink that filesystem first
* zero out the device (destroy the filesystem)
Operation refused.
Command 'drbdmeta /dev/drbd0 v08 /dev/mapper/asterisk1-replica internal create-md' terminated with exit code 40
drbdadm create-md r0: exited with code 40
Pués deberemos ejecutar en asterisk1:
# dd if=/dev/zero of=/dev/mapper/asterisk1-replica bs=1M count=128
y en asterisk2 idem:
# dd if=/dev/zero of=/dev/mapper/asterisk2-replica bs=1M count=128
y ahora ya debería dejar crearlo:
# drbdadm create-md r0
Ahora iniciamos el servico Drbd en ambos servidores. Primero asterisk1 y luego en asterisk2:
# /etc/init.d/drbd start
y nos saldrá algo como:
root@asterisk1:~# /etc/init.d/drbd start
* Starting DRBD resources [ s(r0) ]
y también en asterisk2:
root@asterisk2:~# /etc/init.d/drbd start
* Starting DRBD resources [ d(r0) n(r0) ]
Ahora si hacemos un ‘cat /proc/drbd’ veremos que aun no esta sicronizando los discos:
GIT-hash: 9ba8b93e24d842f0dd3fb1f9b90e8348ddb95829 build by ivoks@ubuntu, 2009-01-17 07:49:56
0: cs:Connected ro:Secondary/Secondary ds:Inconsistent/Inconsistent C r---
ns:0 nr:0 dw:0 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:47127100
Para que empiecen a sincronizar, primero debemos marcar uno como primario. En este caso asterisk1:
drbdadm -- --overwrite-data-of-peer primary all
En este mismo momento asterisk2 mepzará a sincronizar los datos. Lo vemos con un:
root@asterisk2:~# cat /proc/drbd
version: 8.3.0 (api:88/proto:86-89)
GIT-hash: 9ba8b93e24d842f0dd3fb1f9b90e8348ddb95829 build by ivoks@ubuntu, 2009-01-17 07:49:56
0: cs:SyncTarget ro:Secondary/Primary ds:Inconsistent/UpToDate C r---
ns:0 nr:3369544 dw:3369492 dr:0 al:0 bm:205 lo:14 pe:2379 ua:13 ap:0 ep:1 wo:b oos:43757608
[>...................] sync'ed: 7.2% (42732/46022)M
finish: 1:02:23 speed: 11,644 (11,268) K/sec
Una vez aparezca ‘ds:UpToDate/UpToDate’ quiere decir que ya habrá sincronizado las particiones.
Podemos determinar cual es el ‘rol’ de un servidor ejecutando:
# drbdadm role r0
en cada uno de ellosy nos dirá Primary/Secondary o Secondary/Primary
Ahora tan SOLO en el primario
Por último nos falta formatear esta nueva partición, en mi caso en ext4 y montarla para que sea accesible. OJO, esto solo lo tenemos que hacer en el servidor primario:
# mkfs.ext4 /dev/drbd0
y lo montamos:
mount -t ext4 /dev/drbd0 /mnt/local/replica
ATENCION!!, ahora quietos paraos, que ya os veo montandolo en el secundario y probando a escribir algo. No se puede tenerlo montado en los dos a la vez e intentar escribir en el.
Si queremos comprender como funciona podemos hacer las siguientes pruebas (opcional):
Pruebas funcionamiento
- Primera prueba:
Una vez montada la partición /dev/drbdo en /mnt/local/replica en el primario, copiamos algo a ella:
# cp /etc/hosts /mnt/local/replica/
desmontamos el recurso y hacemos que el primario pase a ser secundario:
# umount /mnt/local/replica
# drbdadm secondary r0
Si ahora ejecutamos un ‘drbdadm role r0′ veríamos:
Secondary/Secondary
Nos vamos al secundario y lo volvemos primario montamos la partición y comprobamos que este el archivo:
drbdadm primary r0
mkdir /mnt/local/replica
mount -t ext4 /dev/drbd0 /mnt/local/replica
ls /mnt/local/replica
En este punto el primario (asterisk1) ha tomado el rol de secundario y el secundario (asterisk2) ha tomado el rol del primario.
- Segunda prueba:
Apagamos el que es ahora el servidor secundario (osea asterisk1). Veremos que deja de estar sincronizado:
# cat /proc/drbd
version: 8.3.0 (api:88/proto:86-89)
GIT-hash: 9ba8b93e24d842f0dd3fb1f9b90e8348ddb95829 build by ivoks@ubuntu, 2009-01-17 07:49:56
0: cs:WFConnection ro:Primary/Unknown ds:UpToDate/DUnknown C r---
ns:56 nr:48000148 dw:48000204 dr:33 al:3 bm:2877 lo:0 pe:0 ua:0 ap:0 ep:1 wo:d oos:0
Copiamos unos archivos mas a /mnt/local/replica:
# cp /etc/hosts.* /etc/group /mnt/local/replica
Y encendemos otra vez asterisk1. Cuando encienda empieza a sincronizar la partición drbd. Es decir los datos estan replicados en los dos, pero SOLO puede acceder y montar el recurso para escribir uno de ellos en todo momento.
Una vez ha arrancado el secundario (asterisk1) volvemos a chequear el primario y veremos que vuelve a estar sincronizado:
cat /proc/drbd
version: 8.3.0 (api:88/proto:86-89)
GIT-hash: 9ba8b93e24d842f0dd3fb1f9b90e8348ddb95829 build by ivoks@ubuntu, 2009-01-17 07:49:56
0: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r---
ns:176 nr:48000148 dw:48000324 dr:149 al:5 bm:2880 lo:0 pe:0 ua:0 ap:0 ep:1 wo:d oos:0
- Tercera prueba:
Ahora procedemos a apagar el primario (asterisk2) directamente, sin desmontar /dev/drbd0 ni nada.
Al rato el secundario estará des-sincronizado:
# cat /proc/drbd
version: 8.3.0 (api:88/proto:86-89)
GIT-hash: 9ba8b93e24d842f0dd3fb1f9b90e8348ddb95829 build by ivoks@ubuntu, 2009-01-17 07:49:56
0: cs:WFConnection ro:Secondary/Unknown ds:UpToDate/DUnknown C r---
ns:0 nr:120 dw:120 dr:0 al:0 bm:3 lo:0 pe:0 ua:0 ap:0 ep:1 wo:d oos:0
Entonces lo volvemos a hacer primario:
drbdadm primary r0
Y montamos el recurso:
mount -t ext4 /dev/drbd0 /mnt/local/replica
En este momento asterisk1 vuelve a ser el primario y asterisk2 el secudario
Ahora cuando encendamos el secundario, al arrancar, se dara cuenta de que el ya no es el primario y de que el otro (asterisk1) tiene los datos mas ‘frescos’ por lo cual se actualizará con el (ya que mientras ha etado apagado se pueden haber creado mas archivos).
Esta prueba deja el sistema degradado ya que no hemos hecho un apagado en ‘orden’. Para hacer un apagado en orden tenemos que desmontar el recurso y ceder el mando al otro servidor haciendonos secundario y poniendo al otro primario. Habría que automatizar esto y aun no se como se hace (cualquier aporte será agradecido).
Al arrancar nos aparaecerá algo como “Split-Brain detected”, entonces en el secundario que acabamos de arrancar, hacemos:
drbdadm secondary r0
drbdadm -- --discard-my-data connect r0
Y en el primario:
drbdadm connect r0
Y ya tenemos otra vez el sistema sincronizado.
Bien, como hemos visto esto esta todo muy bien, pero si no lo podemos automatizar no nos vale de nada. Si un servidor nos casca, tendríamos que estar allí para desmontar y pasar el control al secundario, lo cual lo hace inservible.
Para automatizar esto esta Heartbeat.
Heartbeat
Para instalarlo en Ubuntu simplemente hacemos:
# aptitude install heartbeat
The following NEW packages will be installed:
gawk{a} heartbeat heartbeat-common{a} libcurl3{a} libheartbeat2{a} libltdl7{a} libnet1{a} libopenhpi2{a} libopenipmi0{a} libperl5.10{a} libsensors3{a}
libsnmp-base{a} libsnmp15{a} libsysfs2{a} libxml2-utils{a} openhpid{a}
0 packages upgraded, 16 newly installed, 0 to remove and 0 not upgraded.
Need to get 5671kB of archives. After unpacking 18,4MB will be used.
Veremos que nos suelta algo como:
Heartbeat not configured: /etc/ha.d/ha.cf not found.
Heartbeat failure [rc=1]. Failed.
Esto es normal, porque lo vamos a configurar a continuación.
Necesitamos configurar tres archivos en el dir /etc/ha.d/ así que nos vamos a este directorio y como no, nos leemos el README de turno.
Estos tres archivos son:
ha.cf - Main configuration file
haresources - Resource configuration file
authkeys - Authentication information
Los copiamos de /usr/share/doc/heartbeat a /etc/ha.d/ y los descomprimimos:
# cp /usr/share/doc/heartbeat/ha.cf.gz .
# cp /usr/share/doc/heartbeat/authkeys .
# cp /usr/share/doc/heartbeat/haresources.gz .
# gzip -d ha.cf.gz
# gzip -d haresources.gz
Editamos primero ha.cf y ponemos:
debugfile /var/log/ha-debug
logfile /var/log/ha-log
logfacility local0
keepalive 2
deadtime 20
warntime 10
initdead 40
udpport 694
bcast eth0
auto_failback off
node asterisk1
node asterisk2
La opcíon ‘auto_failback off’ significa que si asterisk1 se cae, el control pasa a asterisk2 y que si asterisk1 vuele a estar disponible, que asterisk2 no le devuleva el control.
Lo configuro de esta forma, porque en ocasiones un servidor puede estar con un interfaz de red o latiguillo mal y estar pasando de disponible a no disponible todo el rato, lo cual volvería loco al servicio. Es mejor que pase el servicio al secundario y luego estudiar que ha sucedido.
De esta forma se provee una funcionalidad básica en modo activo/pasivo. Cada opción viene explicada en el archvio de configuración que hemos copiado.
Este archico (/etc/ha.d/ha.cf) ha de ser igual en los dos servidores.
A continuación en el archivo haresources definimos en donde vamos a montar el recurso DRBD (/dev/drbd0), que IP va a ser usada como ‘Virtual’, para acceder a los servicios y los scripts en init.d que se van a iniciar durante un failover o un switchover (fonulator y asterisk).
Editamos el /etc/ha.d/haresources de asterisk1 y asterisk2 y ponemos (ojo! TODO en una misma línea):
asterisk1 drbddisk::r0 Filesystem::/dev/drbd0::/mnt/local/replica::ext4 IPaddr::192.168.3.111/24/eth0 asterisk fonulator mail-heartbeat
Al final van los servicios de /etc/init.d que queremos que se ejecuten cuando se haya un failover o un switchover.
En este caso yo pongo:
A continuación editamos el archivo authkeys, que provee un nivel de seguridad para que se autentiquen solo estos dos servidores. Ponemos en ambos servidores:
auth 2
2 sha1 Elpasswordquetedelagana
Y le quitamos los permisos de lectura a todos menos a root:
# sudo chmod 600 /etc/ha.d/authkeys
Ahora ya están los dos servidores configurados.
Pruebas
Apagamos ambos servidores y encendemos el primario (asterisk1). Veremos que monta la partición drdb y que la VIP (Virtual IP) este accesible (la podemos ver haciendo un ifconfig).
También comprobamos que es el primario:
# drbdadm role r0
veríamos:
Primary/Unknown
A continuación arrancamos el secundario (asterisk2). Y comprobamos que es el secundario:
# drbdadm role r0
Secondary/Primary
Y que sincroniza:
cat /proc/drbd
version: 8.3.0 (api:88/proto:86-89)
GIT-hash: 9ba8b93e24d842f0dd3fb1f9b90e8348ddb95829 build by ivoks@ubuntu, 2009-01-17 07:49:56
0: cs:Connected ro:Secondary/Primary ds:UpToDate/UpToDate C r---
ns:0 nr:8 dw:8 dr:0 al:0 bm:2 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:0
Ahora viene la prueba de fuego. Hacemos un ‘failover’. Apagamos a machete el servidor primario. Veremos que acto seguido pasa a ser el primario, que toma control del recurso drdb, que lo monta y que toma control de la ip. De hecho si mantenemos un ping a la VIP veremos que se corta el servicio tan solo entre unos 5-10 segs (en mi caso).
Para volver a poner el primario en asterisk1, tal y como explicamos anteriormente hacemos un ‘switchover’ (cambio controlado).
Encendemos asterisk1, que ahora es el secundario:
# drbdadm role r0
Secondary/Primary
y esperamos a que sincronicen los discos:
# cat /proc/drbd
version: 8.3.0 (api:88/proto:86-89)
GIT-hash: 9ba8b93e24d842f0dd3fb1f9b90e8348ddb95829 build by ivoks@ubuntu, 2009-01-17 07:49:56
0: cs:Connected ro:Secondary/Primary ds:UpToDate/UpToDate C r---
ns:0 nr:8192 dw:8192 dr:0 al:0 bm:4 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:0
Y ahora es tan fácil como ir al primario (asterisk2) y hacer un:
# /etc/init.d/heartbeat restart
Stopping High-Availability services:
Done.
Waiting to allow resource takeover to complete:
Done.
Starting High-Availability services:
2010/02/08_15:23:50 INFO: Resource is stopped
Done.
Y voila!. Asterisk1 pasa a tomar el control, con el recurso montado, la IP virtual y demas.
En el siguiente post explicaré como adaptar la instalación de asterisk a este entorno y como instalar el redfone.
PD:
Por cierto estas instrucciones me han funcionado a mi y se ofrecen sin ningún tipo de garantía.
Siento no permitir comentarios, en parte porque siempre me olvido de contestarlos y porque entiendo que si has llegado hasta aquí y estás intentando instalar algo así tendrás los recursos necesarios para solucionarlo por tu cuenta y no tener que investigar yo sobre como solucionarlo… espero que no suene muy borde ![]()
Si necesites adaptar ciertas cosas e investigar mas sobre el asunto, estaría bien leer las siguientes fuentes en las que me basé.
Fuentes Drbd + Hearbeat:
—————————–
http://roaksoax.wordpress.com/2008/07/31/installing-drbd-on-hardy/
http://roaksoax.wordpress.com/2008/08/04/installing-drbd-on-hardy-part-2/
Fuentes Drbd:
—————
http://kylecordes.com/2007/01/27/drbd-ubuntu/
http://davehall.com.au/blog/dave/2009/12/08/drbd-ubuntu-karmic
https://wiki.ubuntu.com/Testing/Cases/UbuntuServer-drbd
http://www.guatewireless.org/como-instalar-drbd-sobre-linux-debian-ubuntu/
http://www.howtoforge.com/drbd-on-centos-4.5
Fuentes HeartBeat:
———————
http://www.associatedcontent.com/article/1930488/installing_and_configuring_heartbeat.html?cat=15