Crear usuari de graphite

El graphite és una eina molt bona per fer gràfiques. Et permet ràpidament fer-ne de molt completes i aplicant un munt de funcions per treure les dades exactament com les vols. Els paràmetres de configuració de cada gràfica (dades a mostrar, dimensions de la gràfica, llegenda, funcions, etc) estan a la pròpia URL, per tant si volem compartir una gràfica en concret nomes hem de compartir la URL. Però el propi graphite té un sistema per guardar gràfiques y tenir-les a mà a l’apartat “My Graphs” o “User Graphs” que es bastant còmode. Per poder guardar les gràfiques primer ens hem d’autenticar (s’han d’assignar a algun usuari!) i, evidentment, per autenticar-nos hem de tenir un usuari. I a l’anterior post que explicava com instal·lar-lo no ho explicava.

Els usuaris, gràfiques i dashboards estan guardats al fitxer /opt/graphite/storage/graphite.db, que és una base de dades sqlite . Podem mirar el contingut (requereix tenir instal·lat el client sqlite3):

$ cd /opt/graphite/webapp/graphite
$ python manage.py dbshell
Error: You appear not to have the 'sqlite3' program installed or on your path.
$ sudo apt-get install sqlite3
(...)
Processing triggers for man-db ...
Setting up sqlite3 (3.7.3-1) ...
$ python manage.py dbshell
SQLite version 3.7.3
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> .databases
seq name file
--- --------------- ----------------------------------------------------------
0 main /opt/graphite/storage/graphite.db
sqlite> .table
account_mygraph auth_user_groups
account_profile auth_user_user_permissions
account_variable dashboard_dashboard
account_view dashboard_dashboard_owners
account_window django_admin_log
auth_group django_content_type
auth_group_permissions django_session
auth_message events_event
auth_permission tagging_tag
auth_user tagging_taggeditem
sqlite> ^D
$

En comptes de tocar aquestes dades nosaltres mateixos (que requeriria que entenguessim exactament el que fan, i ara mateix no tinc l’interes :P), voldrem fer-ho a través del graphite (o millor dit, a través del seu framework, django). En primer lloc necessitem un superusuari, que es crea des de la línia de comandes:


$ cd /opt/graphite/webapp/graphite
$ python manage.py createsuperuser
Username: tomas
E-mail address: [email protected]
Password: xxxxxx
Password (again): xxxxxx
Superuser created successfully.
$

Ara podem entrar amb aquest nom d’usuari i contrassenya al login que apareix a la part superior del graphite.

Fer login al graphite

Un cop autenticats, podrem anar a l’interfície d’administració accedint a “/admin/“, http://your-graphite-server.tld/admin/, i aqui podrem donar d’alta tants usuaris com volguem.

Panel d'administracio django a graphite

Configuració bàsica de Varnish amb http cache i stale-while

En entorns d’alta demanda arriba un moment on les peticions php (o similar, CGI en general) que volem servir a traves del nostre apache httpd son més de les que el nostre servidor pot processar. Per solucionar-ho podem fer el més senzill, que és afegir més servidors a la granja de balanceig i disminuir així la càrrega (es reparteixen les peticions entre més servidors). Però el més senzill no necessariament és el més eficient. En comptes de repartir la càrrega entre més servidors, no podriem fer que cada servidor pogués servir més peticions?

I tant. D’una banda podem fer més ràpid el processament dels PHP (o similar, CGI en general) amb FastCGI. D’altra banda podem fer que el nostre servidor HTTP sigui més ràpid, canviant-lo per un de mes lleuger, com per exemple nginx. Una altra aproximació, de la que parlarem aquí, es tracta de mantenir una cache en memòria dels continguts, en comptes de processar-los cada vegada, evitant així el consum de CPU i accelerant enormement el temps que es triga a servir-los. Ho farem fent servir varnish .

Mantenir una cache és força delicat perquè s’han de tenir en compte moltes coses. No s’hauria de fer cache si hi ha cookies pel mig, per exemple, o si hi la petició http és de tipus POST. Però això es una cosa a avaluar dintre de cada aplicació, els desenvolupadors han de poder indicar què es pot guardar a la cache i què no, i els administradors configurar els servidors en conseqüencia.Aleshores, suposem que comencem de zero, que no tenim res en la cache del varnish, i volem començar posant-hi una URL en concret, de la que sabem que no te risc. Això farem aquí, caché selectiva d’una sola URL.

Per il·lustrar la nostra demostració, farem servir un fitxer PHP senzill que triga 10 segons a tornar el resultat, i que té una capçalera que el fa caducar en 5 segons. L’anomenarem sleep.php:

Si el demanem comprovarem que efectivament triga 10 segons a servir-se:

El primer que hem de fer es instal·lar varnish amb el nostre gestor de paquets (apt-get install varnish, yum install varnish, el que sigui). Després voldrem que sigui el varnish qui escolti pel port 80 en comptes de l’apache. Per això mourem el apache de port (directiva “Listen: “), i el posarem al 8080, per exemple. Després canviarem el port del varnish (directiva VARNISH_LISTEN_PORT= , normalment esta al fitxer /etc/default/varnish o /etc/sysconfig/varnish, depenent de la distro). Necessitem dir-li al varnish quins servidors tindrà darrera, als que ha de reenviar les peticions (els servidors backend). Per això crearem el fitxer /etc/varnish/default.vcl amb el següent contingut:

Amb tot això reiniciem tant el apache com el varnish, i podrem comprobar que estan ambdos en marxa:

Veiem que les capçaleres que retornen un i l’altre són diferents. Quan demanem al varnish apareixen “Via: 1.1 varnish” i “Age: 0”, entre d’altres que amb l’apache no apareixen. Si ho tenim així, ja tenim la base configurada.

El comportament que tindrem ara mateix es de fer cache de tot.

Però com que volem ser selectius i no volem fer cache de tot, sino de algunes URL en concret, evitant que es faci cache de cookies i coses semblants, canviarem el comportament de la rutina sub vcl_recv perque no faci cache, afegint això al fitxer /etc/varnish/default.vcl:

Ho comprovem:

Ara fem que faci cache només del fitxer sleep.php, afegint aixo al default.vcl:

Ho podem comprovar:

També comprovem que la capçalera “Age:” va pujant, i quan arriba a 5 (el max-age que li hem configurat), torna a trigar 10 segons:

Veiem que quan el contingut caduca, el torna a demanar i triga 10 segons. Pero què passa en aquest interval? La resta de peticions que arriben al varnish mentre es fa aquesta petició al backend, s’han d’esperar? Doncs no. Hi ha un periode de gràcia de 10 segons, durant els quals el varnish continuará servint l’objecte antic (o “ranci”, “stale” en anglés). Ho podem comprobar si fem dos curl alhora, en comptes d’un, i veurem com n’hi ha un que s’atura mentre l’altre continua servint les pagines ràpid, amb la capçalera “Age” per sobre dels 5 segons que li hem assignat:

També podem comprovar-ho amb el siege, posant dos usuaris concurrents, i veurem com durant una estona només un d’ells serveix contingut, pero que en cap moment es deixa de rebre continguts:

Si ens sembla que 10 segons de gràcia és massa poc, podem canviar aquest valor amb la directiva beresp.grace dintre de la rutina vcl_fetch al fitxer default.vcl. Per exemple, si volem posar un minut:

I si cau el servidor backend? Continuará servint el contingut antic (“stale“)? Doncs tal i com ho tenim, no. Perquè tal i com ho tenim, al varnish no li hem configurat res per distingir entre un backend saludable i un que no ho és, per tant els considerarà tots saludables. Per tant, si el backend cau, i el contingut caduca, tornarem error 503:

D’aquesta manera es continua servint el contingut antic quan el backend cau, i el servim fins que s’aixequi i el varnish pugui tornar a demanar-li el contingut.

Fent proves amb el siege i curl, podem veure que tant en el cas del contingut que caduca com en el cas del servidor que cau, sempre hi ha un fil que “pringa”. La primera vegada que el varnish es troba amb el contingut caducat, el demana i espera que acabi. Mentrestant, la resta de fils reben el contingut antic, pero aquest fil “pringa”. El mateix passa amb el servidor caigut. Hi ha molta literatura intentant trobar la manera d’evitar que això passi, i pots llegir molt al respecte, pero el resum es que no hi ha manera d’evitar-ho. Que passa i punt. Un d’els fils “pringa”.

Amb això cobrim dos casos en els quals continuarem servint continguts antics (stale):
– No hi ha cap backend disponible, per tant servim contingut antic.
– Hi ha backends disponibles, i un fil ja ha demanat nou contingut. Mentre aquest nou contingut arriba des del backend, el varnish continua servint l’antic a la resta de fils.

I si volem que aquests dos casos tinguin un timeout diferent? Per exemple, pot donar-se el cas que volguem que, si el backend està disponible, els continguts caducats triguin un temps màxim. Passat aquest temps, deixem de servir el contingut antic i forcem a que s’esperin per al contingut nou. Aquest timeout normalment serà d’uns segons. I alhora, volem que si els backends estan caiguts, i per tant no hi ha manera d’aconseguir contingut nou, que el varnish continui servint el contingut antic durant molta estona, que normalment és millor que estar servint una pàgina d’error 503. Això s’ha de configurar a la rutina vcl_recv del default.vcl, i es fa aixi:

Per tant, el nostre fitxer default.vcl complet tindra el seguent contingut:

 

Troubleshooting pacemaker: La IP que configuro al pacemaker no apareix al ifconfig

Els que encara estem acostumats a fer servir ifconfig per administrar els nostres dispositius de xarxa ens trobem amb una dificultat quan posem una IP virtual al pacemaker, i és que no apareix. Si fem un “ip addr” si que la veiem entre totes les IP de la màquina. Perquè si que aparegui al ifconfig nomes hem de fer servir la opcio iflabel=”etiqueta”, i podrem veure la IP, i a més amb el “ip addr” sabrem a simple vista quina es la IP de la màquina i quina es la IP assignada a cadascun dels serveis de pacemaker:

#crm configure show
(...)
primitive IP_VIRTUAL ocf:heartbeat:IPaddr2
params ip="10.0.0.11" cidr_netmask="32" iflabel="IP_VIRTUAL"
op monitor interval="3s"
meta target-role="Started"
(...)

IMPORTANT: Les etiquetes dels dispositius nomes accepten 10 caràcters. Si en posem més, el pacemaker no podrà engegar la IP virtual i fallarà (això m’ha portat maldecaps :D). Assegureu-vos de posar 10 caràcters com a molt.

Sense iflabel no apareix al ifconfig ni està etiquetada al ip addr:

# ip addr
1: lo: mtu 16436 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:50:56:9e:3c:94 brd ff:ff:ff:ff:ff:ff
inet 10.0.0.1/24 brd 10.0.0.255 scope global eth0
inet 10.0.0.11/32 brd 10.0.0.11 scope global eth0
inet 10.0.0.12/32 brd 10.04.0.12 scope global eth0
inet 10.0.0.13/32 brd 10.0.0.13 scope global eth0
inet 10.0.0.14/32 brd 10.0.0.14 scope global eth0
inet6 fe80::250:56ff:fe9e:3c94/64 scope link
valid_lft forever preferred_lft forever
# ifconfig
eth0 Link encap:Ethernet HWaddr 00:50:56:9E:3C:94
inet addr:10.0.0.1 Bcast:10.10.0.255 Mask:255.255.255.0
inet6 addr: fe80::250:56ff:fe9e:3c94/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:1825681745 errors:0 dropped:0 overruns:0 frame:0
TX packets:2044189443 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:576307237739 (536.7 GiB) TX bytes:605505888813 (563.9 GiB)

lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:924190306 errors:0 dropped:0 overruns:0 frame:0
TX packets:924190306 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:415970933288 (387.4 GiB) TX bytes:415970933288 (387.4 GiB)


En canvi, amb el iflabel, si que apareixen:

[[email protected] ~]# ip addr
1: lo: mtu 16436 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth1: mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:50:56:9e:3c:9c brd ff:ff:ff:ff:ff:ff
inet 10.0.0.1./24 brd 10.254.1.255 scope global eth1
inet 10.0.0.11/32 brd 10.0.0.11 scope global eth1:nginx-ncnp
inet 10.0.0.12/32 brd 10.0.0.12 scope global eth1:nginx-clnp
inet 10.0.0.13/32 brd 10.0.0.13 scope global eth1:hap-ncnp
inet 10.0.0.14/32 brd 10.254.1.14 scope global eth1:hap-clnp
inet6 fe80::250:56ff:fe9e:3c9c/64 scope link
valid_lft forever preferred_lft forever
[[email protected] ~]# ifconfig
eth1 Link encap:Ethernet HWaddr 00:50:56:9E:3C:9C
inet addr:10.0.0.1 Bcast:10.0.0.255 Mask:255.255.255.0
inet6 addr: fe80::250:56ff:fe9e:3c9c/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:322545491 errors:0 dropped:0 overruns:0 frame:0
TX packets:333825895 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:92667389749 (86.3 GiB) TX bytes:93365772607 (86.9 GiB)

eth1:hap-clnp Link encap:Ethernet HWaddr 00:50:56:9E:3C:9C
inet addr:10.0.0.12 Bcast:10.254.1.52 Mask:255.255.255.255
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1

eth1:hap-ncnp Link encap:Ethernet HWaddr 00:50:56:9E:3C:9C
inet addr:10.0.0.11 Bcast:10.254.1.51 Mask:255.255.255.255
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1

eth1:nginx-clnp Link encap:Ethernet HWaddr 00:50:56:9E:3C:9C
inet addr:10.0.0.13 Bcast:10.254.1.32 Mask:255.255.255.255
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1

eth1:nginx-ncnp Link encap:Ethernet HWaddr 00:50:56:9E:3C:9C
inet addr:10.0.0.14 Bcast:10.254.1.30 Mask:255.255.255.255
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1

lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:4073 errors:0 dropped:0 overruns:0 frame:0
TX packets:4073 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:1136055 (1.0 MiB) TX bytes:1136055 (1.0 MiB)

Molt millor així :)

Més informacio aqui: http://linux.die.net/man/7/ocf_heartbeat_ipaddr2

Instal·lant graphite 0.9.10 a debian squeeze

El sistema de gràfiques que més m’agrada es el graphite. És molt útil per molts motius (és agil, es senzill, es escalable, consumeix molt pocs recursos, etc, etc). Avui parlaré de com s’instal·la el graphite 0.9.10 en Debian squeeze.

Primer de tot instal·lem els requisits:

apt-get install python apache2 python-twisted python-memcache libapache2-mod-python python-django libpixman-1-0 python-cairo python-django-tagging

I ens assegurem que no tenim instal·lat el whisper del repositori de debian, que és antic i pot tenir incompatibilitats amb la ultima versió de graphite:

apt-get remove python-whisper

Després instal·lem l’aplicació. Jo he fet uns .deb que poden fer-se servir directament:

wget http://www.tomas.cat/blog/sites/default/files/python-carbon_0.9.10_all.deb
wget http://www.tomas.cat/blog/sites/default/files/python-graphite-web_0.9.10_all.deb
wget http://www.tomas.cat/blog/sites/default/files/python-whisper_0.9.10_all.deb
dpkg -i python-carbon_0.9.10_all.deb python-graphite-web_0.9.10_all.deb python-whisper_0.9.10_all.deb

Però si no t’agrada fer servir els meus, es fàcil fer-los tu mateix amb el fpm (Effing package managers), una aplicació ruby que permet fer paquets per diferents gestors de paquets. Primer instal·lem ruby i fpm:

apt-get install ruby rubygems
gem install fpm

Després baixem el graphite i el descomprimim:

wget http://pypi.python.org/packages/source/c/carbon/carbon-0.9.10.tar.gz#md5=1d85d91fe220ec69c0db3037359b691a
wget http://pypi.python.org/packages/source/w/whisper/whisper-0.9.10.tar.gz#md5=218aadafcc0a606f269b1b91b42bde3f
wget http://pypi.python.org/packages/source/g/graphite-web/graphite-web-0.9.10.tar.gz#md5=b6d743a254d208874ceeff0a53e825c1
tar zxf graphite-web-0.9.10.tar.gz
tar zxf carbon-0.9.10.tar.gz
tar zxf whisper-0.9.10.tar.gz

I finalment creem els paquets i els instal·lem:

/var/lib/gems/1.8/gems/fpm-0.4.22/bin/fpm --python-install-bin /opt/graphite/bin -s python -t deb carbon-0.9.10/setup.py
/var/lib/gems/1.8/gems/fpm-0.4.22/bin/fpm --python-install-bin /opt/graphite/bin -s python -t deb whisper-0.9.10/setup.py
/var/lib/gems/1.8/gems/fpm-0.4.22/bin/fpm --python-install-lib /opt/graphite/webapp -s python -t deb graphite-web-0.9.10/setup.py
dpkg -i python-carbon_0.9.10_all.deb python-graphite-web_0.9.10_all.deb python-whisper_0.9.10_all.deb

Ja tenim l’aplicació instal·lada. El whisper no necessita cap configuració. El carbon si, però amb els fitxers que venen per defecte ja fem:

cp /opt/graphite/conf/carbon.conf.example /opt/graphite/conf/carbon.conf
cp /opt/graphite/conf/storage-schemas.conf.example /opt/graphite/conf/storage-schemas.conf

Aquest storache-schemas.conf fa que es guardin les dades cada minut només durant un dia. Com que segurament voldrem dades de mes temps (un mes, un any…), el que poso jo al storache-schemas.conf és el següent:

[default_1min_for_1month_15min_for_2years]
pattern = .*
retentions = 60s:30d,15m:2y

D’aquesta manera es guarden les dades cada minut durant 30 dies, i cada 15 minuts durant 2 anys. Això fa que les dades per cada gràfica ocupin en disc 1’4MB, un tamany raonable. Pots jugar amb aquests números si necessites més temps o vols ocupar menys espai en disc, és força intuitiu.

Despres s’ha d’inicialitzar la base de dades perquè es puguin començar a guardar les dades:

cd /opt/graphite/webapp/graphite
sudo python manage.py syncdb

I ara podriem engegar el carbon per començar a recollir dades executant el següent:

cd /opt/graphite/
./bin/carbon-cache.py start

Però també voldrem que s’engegi quan s’engega la màquina, per tant ho haurem d’afegir al init.d. Com que no ve cap script d’engegada amb l’aplicació, jo vaig baixar un init.d de graphite per RedHat i vaig fer quatre modificacions perque funcionés a debian:

#!/bin/bash
#
# Carbon (part of Graphite)
#
# chkconfig: 3 50 50
# description: Carbon init.d

. /lib/lsb/init-functions
prog=carbon
RETVAL=0

start() {
log_progress_msg "Starting $prog: "

PYTHONPATH=/usr/local/lib/python2.6/dist-packages/ /opt/graphite/bin/carbon-cache.py start
status=$?
log_end_msg $status
}

stop() {
log_progress_msg "Stopping $prog: "

PYTHONPATH=/usr/local/lib/python2.6/dist-packages/ /opt/graphite/bin/carbon-cache.py stop > /dev/null 2>&1
status=$?
log_end_msg $status
}

# See how we were called.
case "$1" in
start)
start
;;
stop)
stop
;;
status)
PYTHONPATH=/usr/local/lib/python2.6/dist-packages/ /opt/graphite/bin/carbon-cache.py status
RETVAL=$?
;;
restart)
stop
start
;;
*)
echo $"Usage: $prog {start|stop|restart|status}"
exit 1
esac

exit $RETVAL

Per instal·lar-ho només ho hem de baixar i posar-ho on toca:

wget http://www.tomas.cat/blog/sites/default/files/carbon.initd -O /etc/init.d/carbon
chmod 0755 /etc/init.d/carbon
chkconfig --add carbon

Ara ja podem engegar-ho des del initd (service carbon start o també /etc/init.d/carbon start). Finalment, configurem la webapp que permet accedir a les dades. Hem de crear un virtualhost al apache amb el següent contingut:


ServerName YOUR_SERVERNAME_HERE
DocumentRoot "/opt/graphite/webapp"
ErrorLog /opt/graphite/storage/log/webapp/error.log
CustomLog /opt/graphite/storage/log/webapp/access.log common


SetHandler python-program
PythonPath "['/opt/graphite/webapp'] + sys.path"
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE graphite.settings
PythonDebug Off
PythonAutoReload Off

Alias /content/ /opt/graphite/webapp/content/

SetHandler None


Configurem el virtualhost i li donem accés a les dades del whisper:

wget http://www.tomas.cat/blog/sites/default/files/graphite-vhost.txt -O /etc/apache2/sites-available/graphite
a2ensite graphite
chown -R www-data:www-data /opt/graphite/storage/
/etc/init.d/apache reload

I ja ho tenim! Un últim detall… El graphite ve configurat amb el fus horari de Los Angeles. Per canviar-ho, s’ha d’assignar la variable “TIME_ZONE” al fitxer /opt/graphite/webapp/graphite/local_settings.py. Tens un fitxer amb un munt de variables que es poden tocar a /opt/graphite/webapp/graphite/local_settings.py.example, però com que l’únic que jo necessito canviar és el fus horari, executo la comanda:

echo "TIME_ZONE = 'Europe/Madrid'" > /opt/graphite/webapp/graphite/local_settings.py

I amb aixo ja ho tenim tot. Ara només ens caldrà enviar dades al carbon (port 2003) perquè s’emmagatzemin al whisper i la webapp del graphite les pugui mostrar. A gaudir!

Bibliografia: He seguit la documentació oficial http://graphite.wikidot.com/installation i http://graphite.wikidot.com/quickstart-guide, pero el mes específic relatiu a Debian ho he tret de http://slacklabs.be/2012/04/05/Installing-graphite-on-debian/

Troubleshooting pacemaker: Discarding cib_apply_diff message (xxx) from server2: not in our membership

Ahir, en reiniciar un dels nodes que tenim en alta disponibilitat (per actualitzar les maleïdes vmware-tools que es carreguen el meu preciós uptime) vam trobar-nos amb un problema greu, i és que el pacemaker no se sincronitzava, i per tant haviem perdut l’alta disponibilitat. El node actiu veia el cluster com si no hi hagués cap problema:

[[email protected]]# crm status
============
Last updated: Wed Nov 7 12:36:01 2012
Last change: Tue Nov 6 18:33:15 2012 via crmd on server2
Stack: openais
Current DC: server2 - partition with quorum
Version: 1.1.7-6.el6-148fccfd5985c5590cc601123c6c16e966b85d14
2 Nodes configured, 2 expected votes
6 Resources configured.
============

Online: [ server2 server1 ]
(...)

En canvi, el node passiu veia el cluster com si tots els nodes, inclòs ell mateix, estigues off-line:

[[email protected] ]# crm status
============
Last updated: Wed Nov 7 12:36:27 2012
Last change: Wed Nov 7 12:35:57 2012 via cibadmin on server1
Stack: openais
Current DC: NONE
2 Nodes configured, 2 expected votes
6 Resources configured.
============

OFFLINE: [ server2 server1 ]

Mirant els logs del node passiu vèiem que l’arrencada anava be, pero en cert moment començàven a sortir errors del tipus:

Nov 6 16:40:29 server1 cib [4607]: warning: cib_peer_callback: Discarding cib_replace message (776) from server2: not in our membership
Nov 6 16:40:29 server1 cib[4607]: warning: cib_peer_callback: Discarding cib_apply_diff message (777) from server2: not in our membership

En el node actiu no sortia cap missatge que ens semblés estrany. Mirant el corosync, vam comprobar que els nodes es podien veure entre ells sense problema. Els dos nodes tornàven el mateix:

[[email protected] ]# corosync-objctl | grep member
runtime.totem.pg.mrp.srp.members.200.ip=r(0) ip(10.10.10.10)
runtime.totem.pg.mrp.srp.members.200.join_count=1
runtime.totem.pg.mrp.srp.members.200.status=joined
untime.totem.pg.mrp.srp.members.201.ip=r(0) ip(10.10.10.11)
runtime.totem.pg.mrp.srp.members.201.join_count=1
runtime.totem.pg.mrp.srp.members.201.status=joined

Amb un tcpdump escoltant el port del corosync vam comprobar que hi havia trànsit (cosa evident, pero en aquests casos ho proves tot), amb la qual cosa semblava clar que el problema era de pacemaker i també molt clar que no teniem ni idea del què era. Investigant vam trobar uns quants enllaços (per exemple aquest: http://comments.gmane.org/gmane.linux.highavailability.pacemaker/13185) on deien que es un bug, que se soluciona amb aquest commit https://github.com/ClusterLabs/pacemaker/commit/03f6105592281901cc10550b8ad19af4beb5f72f que entrava a la versio 1.1.8 de pacemaker. I nosaltres tenim la 1.1.7. Glups.

Per assegurar, en comptes d’actualitzar la màquina existent, vam crear una nova i vam instal·lar pacemaker de zero, seguint les instruccions de http://www.clusterlabs.org/rpm-next/ i de http://www.clusterlabs.org/wiki/Install. Bàsicament vam fer:

wget -O /etc/yum.repos.d/pacemaker.repo http://clusterlabs.org/rpm-next/rhel-6/clusterlabs.repo
yum install -y corosync corosynclib corosynclib-devel pacemaker cman

Vam copiar el corosync.conf adaptant-lo (bàsicament, canviant-li el nodeid) i el vam engegar, i va integrar-se al cluster sense cap problema:

[[email protected]]# crm status

Last updated: Wed Nov 7 18:14:08 2012
Last change: Wed Nov 7 18:07:01 2012 via cibadmin on balance03
Stack: openais
Current DC: balance03 - partition with quorum
Version: 1.1.8-1.el6-394e906
3 Nodes configured, 3 expected votes
6 Resources configured.

Online: [ server3 server2 ]
OFFLINE: [ server1 ]
(...)

Vam poder fer un migrate al nou node i tot va funcionar perfectament. Vam actualitzar els altres i vam recuperar la nostra alta disponibilitat de nou.

Però la nova versió ve amb inconvenients, i és que crm, l’eina que feiem servir per configurar pacemaker, ara es distribueix per separat, a petició del mantenidor. S’ha convertit en un projecte per si mateix amb el nom crmsh, i té la seva propia web: http://savannah.nongnu.org/projects/crmsh/. El paquet compilat es pot descarregar d’aquí http://download.opensuse.org/repositories/network:/ha-clustering/ pero té dependència del paquet pssh, que al seu torn té algunes altres dependències. En resum, vam haver de fer el següent:


wget http://apt.sw.be/redhat/el6/en/i386/rpmforge/RPMS/pssh-2.0-1.el6.rf.noarch.rpm
rpm -Uvh pssh-2.0-1.el6.rf.noarch.rpm
yum -y install python-dateutil.noarch
yum -y install redhat-rpm-config
wget http://download.opensuse.org/repositories/network:/ha-clustering/CentOS_CentOS-6/x86_64/crmsh-1.2.5-55.3.x86_64.rpm
rpm -Uvh crmsh-1.2.5-55.3.x86_64.rpm

I amb això ja ho teniem tot en marxa de nou