Cluster de Alta Disponibilidad de Servidores PostgreSQL con DRBD y Heartbeat
alfredo publicó esto el 01/10/09 en Bases de Datos, Herramientas. 3 comentariosEn este post vamos a ver cómo armar un cluster de alta disponibilidad de servidores PostgreSQL, con DRBD y Heartbeat.
Como en IPCorp nos gusta dormir tranquilos toda la solución va a estar soportada por GNU/Linux y en este ejemplo utilizaremos Ubuntu Server 9.04.
Requisitos
Se necesitan dos servidores o máquinas de similares características. En ambas es necesario tener una partición sin montar y sin formatear para el DRBD.
La capacidad de almacenamiento reservado en estas particiones permitirá almacenar como máximo la capacidad de la partición más chica.
Para el propósito de este instructivo denominaremos a los servidores: server1 y server2. Ambos equipos necesitan ser capaces de resolver los hostnames entre ellos, así que se debemos tener configurado algún servidor de DNS o agregar los nombres de hosts y sus IPs directamente en /etc/hosts. Ambos servidores deberían tener direcciones IP estáticas.
Vamos a suponer que cada servidor tiene un disco de 320Gb de los cuales particionaremos sin LVM, dejando un espacio libre para el volúmen compartido a través de la red. Esto depende del cálculo del tamaño estimado de la base de datos que vamos a replicar.
| Hostname | Dirección IP | Partición para DRBD |
|---|---|---|
| server1 | 10.0.0.2 | /dev/sda3 |
| server2 | 10.0.0.3 | /dev/sda3 |
Los clientes de la base de datos se comunicarán a la IP Virtual 10.0.0.1, además vamos a necesitar los siguientes paquetes instalados, necesarios para poder configurar correctamente el servidor:
sudo aptitude install hearbeat drbd8-utils build-essential libreadline5-dev zlib1g-dev
Configuración de DRBD
Primero vamos a guardar una copia del archivo de configuración original:
mv /etc/drbd.conf /etc/drbd_backup.conf
Editamos el archivo /etc/drbd.conf y reemplazamos su contenido por:
global {usage-count no;} common { syncer {rate 100M;} } resource pg { protocol C; startup { wfc-timeout 15; degr-wfc-timeout 60; } on server1 { device /dev/drbd0; disk /dev/sda3; address 10.0.0.2:7788; meta-disk internal; } on server2 { device /dev/drbd0; disk /dev/sda3; address 10.0.0.3:7788; meta-disk internal; } }
Ahora copiamos este archivo en el servidor secundario e iniciamos el servicio en ambas máquinas. Posteriormente creamos el recurso compartido en ambas máquinas:
sudo /etc/init.d/drbd start sudo drbdadm create-md pg
Dónde “pg” es el mismo nombre que le pusimos al tag “resource” en el archivo de configuración del “drbd”.
Ahora es necesario establecer el nodo primario del cluster. Para este ejemplo elegimos el server1 por lo que en ésta máquina ejecutamos el siguiente comando y luego damos formato a la partición compartida:
sudo drbdadm -- --overwrite-data-of-peer primary all sudo mke2fs -j /dev/drbd0
Con el siguiente comando podemos ver el estado actual de la sincronización de los recursos del cluster:
cat /proc/drbd
Si todo salió bien, vamos a ver algo parecido a esto:
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:82020 nr:1188 dw:82916 dr:5438 al:27 bm:18 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:0
Instalación de la base de datos PostgreSQL
La instalación de PostgreSQL será a través de la compilación del código fuente porque debemos hacer algunas modificaciones al programa pg_ctl para que todo funcione correctamente.
Luego de bajar los fuentes del PostgreSQL descomprimimos, y modificamos el código de la aplicación pg_ctl, más precisamente buscamos la leyenda “no server runnig” dentro del código y reemplazamos la palabra “runnig” por cualquier otra.
Esto tiene una explicación y es que Heartbeat verifica si un servicio está corriendo o no buscando la cadena “running” u “ok” al pedir su status, entonces cuando heartbeat le pregunta a PostgreSQL si está ejecutándose correctamente él responde “no server running” y heartbeat supone que todo está bien aunque realmente no sea así.
El archivo fuente de esta aplicación esta en postgresql-8.X.XX/src/bin/pg_ctl/ y se llama pg_ctl.c.
Un vez hecho este pequeño parche sólo nos falta compilarlo e instalarlo:
cd postgresql-8.X.XX ./configure make make install
Siguiendo el procedimiento regular de instalación, el próximo paso necesario es crear el usuario postgres. Agregamos la ruta /usr/local/pgsql/bin al path del sistema, y debemos crear la carpeta donde se van a alojar los datos y darle los permisos de esa carpeta al usuario postgres:
adduser postgres
Todos los pasos anteriores debemos hacerlo en ambos nodos, los que siguen sólo en el nodo principal:
mkdir /opt/postgresql/data chown postgres.postgres -R /opt/postgresql/data
La ruta “/opt/postgresql/data” es el lugar donde quiero alojar los datos y queda a criterio de cada uno. Para inicializar la base de datos es necesario estar logueado como el usuario postgres y hacer:
initdb -D /opt/postgresql/data
Configuración de Heartbeat
En el nodo primario copiamos los archivos de configuración de ejemplo o simplemente creamos archivos nuevos:
cp /usr/share/doc/heartbeat/authkeys /etc/ha.d/ cp /usr/share/doc/heartbeat/ha.cf.gz /etc/ha.d/ cp /usr/share/doc/heartbeat/haresources.gz /etc/ha.d/ gzip -d ha.cf.gz gzip -d haresources.gz
Editamos el archivo authkeys y ponemos:
auth 2 2 sha1 mipasswordsecreta
“mipasswordsecreta” es la password para que los nodos se puedan comunicar con cierto nivel de seguridad. Ahora es necesario darle permisos sólo a root por cuestiones de seguridad:
chmod 600 /etc/ha.d/authkeys
y en el archivo ha.cf comentamos todo y agregamos:
logfile /var/log/ha-log logfacility local0 keepalive 2 #cada cuanto segundos verifica que este vivo deadtime 30 #cuantos segundos espera hasta que lo considera muerto initdead 120 # este valor es para cuando no bootean los dos juntos, en ese caso espera 120 segundos para empezar el proceso bcast eth0 # placa de red por la que verifica el estado de los otros nodos udpport 694 # puerto UDP por el que se va a enviar el latido auto_failback on node server1 # nodo que participa node server2 # nodo que participa
y por último debemos modificar el archivo haresources. Ahí declaramos los servicios que queremos monitorear y que deben estar siempre disponibles. El equipo server1 es el servidor principal y los otros van a verificar que no caiga. En cuanto caiga una máquina, la otra tomará el control levantando los servicios monitoreados y tomando la IP Virtual. Dentro de haresources ingresamos:
server1 IPaddr::10.0.0.1 drbddisk::pg Filesystem::/dev/drbd0::/opt/postgresql::ext3::defaults postgresql
Les voy a explicar que significa cada parte de este archivo. En primer lugar definimos cuál va a ser el nodo principal en este caso server1. IPaddr::10.0.0.1 es el script que asigna la IP virtual que tendrá el cluster y el cual será el punto de acceso, con drbddisk::pg le decimos que recurso DRBD queremos brindar, luego con Filesystem::/dev/drbd0::/opt/postgresql::ext3::defaults montamos el dispositivo virtual drbd0 en la carpeta /opt/postgresql y por último decimos que arranque postgresql.
En indispensable copiar el archivo de arranque de PostgreSQL a /etc/ha.d/resources.d y modificar la variable de entorno PGDATA para que apunte a la carpeta /opt/postgresql/data que es el lugar donde van a residir las bases de datos:
cp postgresql-8.x.xx/contrib/start-scripts/linux /etc/ha.d/resources.d/postgresql chmod +x /etc/ha.d/resources.d/postgresql
Luego copiamos los archivos de configuración a todos los nodos:
scp -r /etc/ha.d/ root@server2:/etc/
Ahora es cuestión de levantar los servicios en todos los nodos:
sudo /etc/init.d/heartbeat start
Comprobación
Ya estamos en condiciones de levantar el motor de base de datos mediante la siguiente sentencia:
/etc/ha.d/resources.d/postgresql start
Y sólo resta crear la base de datos y restaurar desde un backup anterior o empezar a crear las tablas, índices, vistas, etc., desde cero.
Luego para probar que se estén replicando correctamente los datos, en el nodo secundario ejecutamos el comando “watch cat /proc/drbd” mientras que en el nodo principal bajamos el servicio de hearbeat. Antes de bajar el servicio en el nodo secundario deberíamos tener la siguiente salida:
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:1188 nr:82020 dw:83208 dr:3313 al:15 bm:17 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:0
Luego bajamos a heartbeat:
/etc/init.d/hearbeat stop
Y deberíamos ver lo siguiente:
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:1328 nr:82280 dw:83608 dr:3542 al:15 bm:17 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:0
El agregado de nuevos nodos al cluster diría que es casi trivial.
Amigo, al parecer tienes dos errores en tus lineas:
Publicado el 9 Febrero 2011 a las 17:04. Permalink.1. cuando instalas heartbeat es : apt-get install heartbeat
no apt-get install hearbeat
2. cuando copias, en ubunto es sin “s” resource.d
cp postgresql-8.x.xx/contrib/start-scripts/linux /etc/ha.d/resources.d/postgresql
debe ser
cp postgresql-8.x.xx/contrib/start-scripts/linux /etc/ha.d/resource.d/postgresql
Gracias por tus correcciones y por visitar el blog de IPCorp
Publicado el 10 Febrero 2011 a las 16:21. Permalink.Buen trabajo peor me asalta un par de dudas, cuando realizas el restore de la bbdd lo haces sólo en el nodo principal o en los dos?? Si es en los dos como replica?? Si es en el nodo principal y se cae como sabe de donde tirar el nodo 2??
Publicado el 4 Marzo 2011 a las 08:10. Permalink.Gracias