rpm

Cluster@OVH: Basculare gli IP Failover di OVH via API

Nei cluster tradizionali con IP condiviso una macchina per diventare primaria deve assicurarsi che la secondaria sia offline e poi autoassegnarsi l’IP.

In OVH questa cosa non è sufficiente poichè spesso le macchine sono in classi C differenti e separate da router. E’ necessario quindi comunicare ad OVH che vogliamo “oscillare” un IP failover da un server ad un altro così che OVH possa aggiornare le regole di routing interne.

Normalmente questa operazione viene fatta dall’interfaccia web del manager OVH, ma è possibile farla anche tramite le API che OVH mette a disposizione con il protocollo SOAP.

Gestione IP Failover su Manager v3 OVH

Gestione IP Failover su Manager v3 OVH

Requisiti

Le api vengon utilizzate via SOAP e quindi quasi tutti i linguaggi di programmazione che dispongono di una libreria client SOAP possono essere utilizzati.

Nel mio piccolo ho provato python 2.4 con la libreria SOAPpy e PHP 5.1.6 con il SoapClient integrato ed ho riscontrato problemi con entrambe.

Sembra che il SoapClient di PHP abbia un bug critico che gli impedisce di funzionare con il wsdl di OVH. Il bug sembra corretto in PHP 5.2.6 che però non posso utilizzare.

Procedo quindi con python così da non interferire con PHP che è già presente nel sistema e configurato correttamente.

Questi i pacchetti presenti nella mia Centos 5.3:
SOAPpy-0.11.6-5.el5 e python-2.4.3-24.el5

Esempio e Problema

Prendendo ad esempio il generatore di codice client di OVH generiamo il codice python per vedere l’elenco dei failover associati

#!/usr/bin/python
import pprint
from SOAPpy import WSDL

soap = WSDL.Proxy('https://www.ovh.com/soapi/soapi-re-1.3.wsdl')
#login
session = soap.login('###NIC###-ovh', '###PASS###', 'it', 0)
print "login successfull"
#dedicatedFailoverList
result = soap.dedicatedFailoverList(session, '###NOMEDEDICATO###')
print "dedicatedFailoverList successfull"
pp = pprint.PrettyPrinter(indent=4)
pp.pprint(result) # your code here ...
#logout
soap.logout(session)
print "logout successfull"

ottenendo però questo risultato inaspettato:

login successfull
Traceback (most recent call last):
File "./example.py", line 13, in ?
result = soap.dedicatedFailoverList(session, '###NOMEDEDICATO###')
File "/usr/lib/python2.4/site-packages/SOAPpy/Client.py", line 453, in __call__
return self.__r_call(*args, **kw)
File "/usr/lib/python2.4/site-packages/SOAPpy/Client.py", line 475, in __r_call
self.__hd, self.__ma)
File "/usr/lib/python2.4/site-packages/SOAPpy/Client.py", line 379, in __call
p, attrs = parseSOAPRPC(r, attrs = 1)
File "/usr/lib/python2.4/site-packages/SOAPpy/Parser.py", line 1006, in parseSOAPRPC
t = _parseSOAP(xml_str, rules = rules)
File "/usr/lib/python2.4/site-packages/SOAPpy/Parser.py", line 985, in _parseSOAP
parser.parse(inpsrc)
File "/usr/lib/python2.4/site-packages/_xmlplus/sax/expatreader.py", line 109, in parse
xmlreader.IncrementalParser.parse(self, source)
File "/usr/lib/python2.4/site-packages/_xmlplus/sax/xmlreader.py", line 123, in parse
self.feed(buffer)
File "/usr/lib/python2.4/site-packages/_xmlplus/sax/expatreader.py", line 216, in feed
self._parser.Parse(data, isFinal)
File "/usr/lib/python2.4/site-packages/_xmlplus/sax/expatreader.py", line 363, in end_element_ns
self._cont_handler.endElementNS(pair, None)
File "/usr/lib/python2.4/site-packages/SOAPpy/Parser.py", line 234, in endElementNS
kind = (self._prem[kind[:i]], kind[i + 1:])
KeyError: u'typens'

Segnalando il problema a bugkillers@ml.ovh.net mi viene risposto velocemente che si tratta di un bug della libreria SOAP di Python (SOAPpy) presente fino alla versione 0.20 compresa. Da notare che mentre scrivo l’ultima release di SOAPpy è la 0.19 e risale al 2005. Si trovano alcuni rpm della 0.20 che probabilmente si riferiscono alla rc1 rilasciata nel 2007 ma anche questi contengono il bug di cui sopra!

L’unica è quindi utilizzare la versione di sviluppo che scarichiamo e della quale facciamo un tarball:

svn export https://pywebsvcs.svn.sourceforge.net/svnroot/pywebsvcs/trunk/SOAPpy/ SOAPpy-0.12.0
tar -zcf SOAPpy-0.12.0-dev.tar.gz SOAPpy-0.12.0
rm -rf SOAPpy-0.12.0
mv SOAPpy-0.12.0-dev.tar.gz /usr/src/redhat/SOURCES

A questo punto inseriamo il file spec appositamente creato e facciamo il build dei pacchetti (sorgente e binario) e installiamo il pacchetto appena creato.

cd /usr/src/redhat/SPECS
wget http://digg.it/wp-content/uploads/2009/06/SOAPpy-0.12.0.spec
rpmbuild --define="dist .el5" --define "centos 5" -ba SOAPpy-0.12.0.spec
rpm -Uvh /usr/src/redhat/RPMS/noarch/SOAPpy-0.12.0-dev.el5.noarch.rpm

Il pacchetto risultante lo trovate qui: SOAPpy-0.12.0-dev.el5.noarch.rpm

Altri problemi

Un ulteriore inconveniente del metodo API utilizzabile è che per basculare un IP dobbiamo prima sapere a quale server è assegnato in questo momento.

La mia necessità, invece, è quella che un server, in autonomia e senza conoscenze esterne possa richiedere un IP failover ed ottenerlo.

Per far questo quindi ho creato uno script che una volta loggato sulle API richiede l’elenco dei dedicati associati al cliente e cerca l’IP specificato in tutti i server. Se lo trova già associato al server giusto non fa nulla, se invece lo trova associtato ad un altro server effettua la chiamata per oscillarlo verso se stesso.

Conclusioni

Lo script creato lo trovate qui: getfailover.py

E’ abbastanza spartano ma per ora fa quello che mi serve. Utilizzo questo script in combinazione con heartbeat per permettere al mio cluster OVH di oscillare automaticamente in caso di problemi.

Tags: , , , , ,

mercoledì, Giugno 24th, 2009 Sysadmin Nessun commento

Installare DRBD su un RPS di OVH e Fedora

Configurazione standard DRBD

Configurazione standard DRBD

Premessa

DRBD (Distributed Replicated Block Device) è una sorta di disco virtuale che gestice un RAID 1 via rete. In pratica due dischi installati su due macchine fisiche diverse possono essere visti come unico disco. DRBD è uno dei mattoni fondamentali per la gestione di un cluster HA (High Availability) low cost.

Requisiti

Esistono gli RPM di DRBD già fatti per Centos e si possono usare anche con la Fedora, però funzionano solo con i kernel ufficiali delle rispettive distribuzioni, quindi dovremo crearci il nostro pacchetto.

Innanzitutto dovete assicurarvi di avere installato un kernel che supporta i moduli e che supporta la funzionalità “Connector”.

Inoltre è consigliabile che abbiate riservato una partizione, identica sulle due macchine che vorrete mantenere sincronizzate, da utilizzare con DRBD.
Se non ne avete una potrete comunque provare creando un loop device (questo crea un loop device da 10GB):

shell# dd if=/dev/zero of=/home/drbdloop bs=1024 count=10485760
shell# losetup /dev/loop0 /home/drbdloop

In questo modo avrete un device (/dev/loop0) da utilizzare come disco per DRBD.

Compilazione di DRBD

shell# cd /usr/src
shell# wget http://oss.linbit.com/drbd/8.3/drbd-8.3.1.tar.gz
shell# tar -zxf drbd-8.3.1.tar.gz
shell# cd drbd-8.3.1
shell# make rpm

Nel mio caso mi è stato dato un errore perchè nel mio sistema mancava flex.

errore: Compilazione dipendenze fallita:
flex necessita di drbd-8.3.1-3.i386

In realtà l’errore italiano è tradotto male. Il problema è l’esatto opposto. E’ sufficiente installare flex e ripetere il make:

shell# yum install flex
Installato:
  flex.i386 0:2.5.35-2.fc9
shell# make rpm
[ COMPILAZIONE ]
+ exit 0
You have now:
-rw-r--r-- 1 root root 185530  3 apr 11:23 dist/RPMS/i386/drbd-8.3.1-3.i386.rpm
-rw-r--r-- 1 root root 304874  3 apr 11:23 dist/RPMS/i386/drbd-debuginfo-8.3.1-3.i386.rpm
-rw-r--r-- 1 root root 154010  3 apr 11:23 dist/RPMS/i386/drbd-km-2.6.28.4_custom_std_ipv4_32_mod-8.3.1-3.i386.rpm

A questo punto sarà sufficiente installare drbd (i tools) e drbd-km (il modulo del kernel).

Installazione di DRBD

shell# rpm -Uvh --force dist/RPMS/i386/drbd-8.3.1-3.i386.rpm dist/RPMS/i386/drbd-km-2.6.28.4_custom_std_ipv4_32_mod-8.3.1-3.i386.rpm
errore: Dipendenze fallite:
        kernel necessita di drbd-km-2.6.28.4_custom_std_ipv4_32_mod-8.3.1-3.i386

La distribuzione di fedora core 9 fatta da OVH non include un pacchetto kernel, ma noi abbiamo installato il kernel manualmente e quindi forziamo l’installazione.

shell# rpm -Uvh --nodeps dist/RPMS/i386/drbd-8.3.1-3.i386.rpm dist/RPMS/i386/drbd-km-2.6.28.4_custom_std_ipv4_32_mod-8.3.1-3.i386.rpm
Preparazione in corso...    ########################################### [100%]
   1:drbd                   ########################################### [ 50%]
   2:drbd-km-2.6.28.4_custom########################################### [100%]
shell#

Ogni volta che cambierete il kernel dovrete ripetere questa procedura ed installare il nuovo modulo del kernel (ne possono coesistere più di uno).

Failover di un sistema con DRBD

Failover di un sistema con DRBD

Configurazione DRBD

D’ora in poi ipotizzerò che le due macchine siano rXXXX1.ovh.net e rXXXX2.ovh.net, che l’IP delle due macchine sia rispettivamente 87.98.XXX.101 e 87.98.XXX.102 e che per entrambe le macchine la partizione di cui tenere il mirror sia /dev/sda5.

Innanzitutto dovremo configurare la risorsa (che chiamo “r0” ma alla quale potrete assegnare il nome che preferite) su /etc/mrtg.conf

resource r0 {
  protocol C;
  startup { degr-wfc-timeout 120; }
  syncer { rate 3M; al-extents 257; }
  on rXXXX1.ovh.net {
    device /dev/drbd0;
    disk /dev/sda5;
    address 87.98.XXX.101:7789;
    meta-disk internal;
  }
  on rXXXX2.ovh.net {
    device /dev/drbd0;
    disk /dev/sda5;
    address 87.98.XXX.102:7789;
    meta-disk internal;
  }
}

Una volta configurato possiamo preparare il disco con i metadati di DRBD ed attivare la risorsa:

shell# drbdadm create-md r0
shell# drbdadm up r0

Fate la stessa cosa sul secondo server e poi, sul server che volete sia il primario (quello che potrà montare la partizione) fate:

shell# drbdadm -- -o primary r0

Ora /dev/drbd0 è un dispositivo a blocchi (disco virtuale) valido e possiamo procedere nella formattazione:

shell# mkfs.ext3 /dev/drbd0

A questo punto potrete montare il disco ed utilizzarlo

shell# mkdir /mnt/discoha
shell# mount /dev/drbd0 /mnt/discoha

Se non volete rischiare di perdere tutti i dati per un comando errato è d’obbligo la lettura del manuale, per una buona comprensione dello stato di connessione, dello stato dei dischi e dello stato della sincronizzazione.

Se vi interessano configurazioni master-master in cui entrambi gli host possono usare contemporaneamente il disco allora avrete bisogno di una filesystem distribuita come OCFS2 o GFS: leggete l’articolo di GuiGui che riporto in fondo all’articolo per un esempio.

Riferimenti

Dal manuale – Building a DRBD RPM package
Articolo di GuiGui –
Mise en oeuvre d’un système de fichier distribué et accès concurrents en SAN avec DRBD, ISCSI ,OCFS2 et DM-Multipath

Tags: , , , , ,

lunedì, Aprile 6th, 2009 Sysadmin Nessun commento