Cluster in High Availability e Load Balancing – parte 1

Cluster di tre server in HA + LB con drbd
Parte 1

Premessa.
Per utilizzare questo sistema sono necessari tre server, fisici o virtuali. Uno sarà lo smistatore di traffico e lo chiamerò balancer, due saranno i nodi su cui sarà smistato il traffico dal blanacer e li chiamerò relay-01 e relay-02.
Il balancer deve avere un ip pubblico e un ip privato, i relay possono avere solo l’ip privato. Tutti e tre i server è meglio che siano dislocati dallo stesso provider, risiedano sulla stessa sottorete e siano sullo stesso rack, interconnessi tra loro in fibra (chiedete al vostro fornitore questi dettagli), ma il tutto può funzionare abbastanza bene anche se i server sono dislocati lontani, geograficamente parlando e se sono connessi con una normale rete 100 Mb.

Per lo scopo di questa guida, balancer ha ip pubblico 1.2.3.4 e ip privato 10.0.0.10, relay-01 ha ip privato 10.0.0.21 e relay-02 ha ip privato 10.0.0.22. Si userà drbd come sistema raid e ocfs2 come file system per la partizione da tenere sincronizzata. /data è la partizione che sarà sincronizzata e montata sui due relay. Come sistema operativo si utilizzerà Ubuntu server 10.04 LTS su tutti e tre i server.

Su tutti e tre i server si comincia installando il sistema operativo base, con solo ssh installato (solo successivamente si installeranno i pacchetti necessari).

Inizialmente configureremo i due relay.
Nel mio caso ho partizionato i dischi con LVM per avere un po’ di flessibilità aggiuntiva

UUID=6c0cb2ff-14ea-49b7-910c-276dae634220 — 228 MB /boot
/dev/mapper/relay–01-root — 1700 GB /
/dev/mapper/relay–01-swap — 1000 MB swap
/dev/mapper/relay–01-drbd — 150 MB unmounted
/dev/mapper/relay–01-dati — 3000 MB unmounted

ma si può procedere con un normale partizionamento come il seguente

/dev/sda1 — 100 MB /boot (primary, ext3, Bootable flag: on)
/dev/sda5 — 5000 MB / (logical, ext3)
/dev/sda6 — 1000 MB swap (logical)
/dev/sda7 — 150 MB unmounted (logical, ext3) (conterrà i meta dati di DRBD)
/dev/sda8 — 26 GB unmounted (logical, ext3) (conterrà la directory /data)

Ovviamente è possibile variare le dimensioni e i nomi dei device per adattarsi al proprio disco. L’importante è che /dev/sda7 (nel mio caso /dev/mapper/relay–01-drbd) abbia una dimensione di almeno 128Mb (150 consigliati, non serve usare una dimensione maggiore di 200 Mb) e che sia /dev/sda7 che /dev/sda8 (nel mio caso /dev/mapper/relay–01-drbd e /dev/mapper/relay–01-dati) abbiano identica dimensione su ambo i relay. Inoltre è importante che queste due partizioni NON siano montate.
Ricordate che se il vostro partizionamento è del tipo /dev/hda1, /dev/hda5 eccetera, nel proseguo di questa guida dovete tenerne conto!

E’ fondamentale che ambo i relay abbiano l’orario perfettamente sincronizzato. A tale scopo è necessario installare un client NTP su entrambi

relay-01/relay-02

apt-get install ntp ntpdate

A questo punto passiamo all’installazione di DRBD (gli headers potrebbero già essere installati. Installate se necessario quelli corretti per il vostro kernel: uname -r).

relay-01/relay-02

apt-get install linux-headers-2.6.32-22-generic drbd8-utils

Ora configuriamo drbd. Con vi (o nano o l’editor che preferite) editate il file /etc/drbd.conf su ambo i relay e rendetelo come il seguente

# You can find an example in  /usr/share/doc/drbd…/drbd.conf.example

include “drbd.d/global_common.conf”;
include “drbd.d/*.res”;

Il file /etc/drbd.d/global_common.conf deve essere come questo (sempre su ambo i relay)

global {
usage-count yes;
# minor-count dialog-refresh disable-ip-verification
}

common {
protocol C;

handlers {
pri-on-incon-degr “/usr/lib/drbd/notify-pri-on-incon-degr.sh; /usr/lib/drbd/notify-emergency-reboot.sh; echo b > /proc/sysrq-trigger ; reboot -f”;
pri-lost-after-sb “/usr/lib/drbd/notify-pri-lost-after-sb.sh; /usr/lib/drbd/notify-emergency-reboot.sh; echo b > /proc/sysrq-trigger ; reboot -f”;
local-io-error “/usr/lib/drbd/notify-io-error.sh; /usr/lib/drbd/notify-emergency-shutdown.sh; echo o > /proc/sysrq-trigger ; halt -f”;
# fence-peer “/usr/lib/drbd/crm-fence-peer.sh”;
# split-brain “/usr/lib/drbd/notify-split-brain.sh root”;
out-of-sync “/usr/lib/drbd/notify-out-of-sync.sh root”;
# before-resync-target “/usr/lib/drbd/snapshot-resync-target-lvm.sh -p 15 — -c 16k”;
# after-resync-target /usr/lib/drbd/unsnapshot-resync-target-lvm.sh;
}

startup {
# wfc-timeout degr-wfc-timeout outdated-wfc-timeout wait-after-sb;
degr-wfc-timeout 120;
outdated-wfc-timeout 100;
become-primary-on both;
}

disk {
# on-io-error fencing use-bmbv no-disk-barrier no-disk-flushes
# no-disk-drain no-md-flushes max-bio-bvecs
on-io-error detach;
}

net {
# snd‐buf-size rcvbuf-size timeout connect-int ping-int ping-timeout max-buffers
# max-epoch-size ko-count allow-two-primaries cram-hmac-alg shared-secret
# after-sb-0pri after-sb-1pri after-sb-2pri data-integrity-alg no-tcp-cork
allow-two-primaries;
after-sb-0pri discard-zero-changes;
after-sb-1pri discard-secondary;

}

syncer {

# rate after al-extents use-rle cpu-mask verify-alg csums-alg
rate 10M;
al-extents 257;
}
}

Questo file contiene la configurazione generale di default di drbd. Alcune informazioni riguardo i vari settaggi.
“protocol C” indica il tipo di sincronizzazione che drbd attuerà. C indica Synchronous replication protocol. Le scritture locali sul nodo primario sono considerate complete dopo che ambo i nodi, locale e remoto, hanno confermato la scrittura. Come risultato, la perdita di un singolo nodo garantisce che non ci sia perdita di dati. Ovviamente è inevitabile che si possa verificare una perdita di dati anche con questo protocollo di replicazione se AMBO i nodi (o il loro sistema di storage) è irrimediabilmente corrotto nello stesso momento.

“become-primary-on both” indica che alla partenza del sistema drbd, su entrambi i nodi, drbd stesso diventerà primario. Insieme alla direttiva “allow-two-primaries” è importantissima, perchè ci permetterà in seguito di poter lavorare indifferentemente sui dati, più precisamente sulla partizione drbd montata, di relay-01 o di relay-02 senza perdere in sincronismo e soprattutto ci permette, appunto, di montare la partizione drbd su ambo i nodi.
Le altre impostazioni possono essere lasciate come sono. Se volete approfondire, leggete questa documentazione.
E’ importantissimo che sia questo file che il successivo che andremo a creare siano perfettamente identici su ambo i relay!

Ora dobbiamo creare la configurazione per i nostri due nodi. Sempre con vi creiamo il file /etc/drbd.d/relay.res (sempre su ambo i relay) che conterrà le seguenti righe

resource r0 {
on relay-01 {                                # ** EDIT ** inserire l’host name del server 1 (uname -n)
device     /dev/drbd0;                #
disk       /dev/relay-01/dati;      # ** EDIT ** la partizione data del server 1
address    10.0.0.21:7788;         # ** EDIT ** IP privato del server 1
meta-disk  /dev/relay-01/drbd[0];          # ** EDIT ** la partizione da 128MB per DRBD sul server 1
}

on relay-02 {                                # ** EDIT ** inserire l’host name del server 2 (uname -n)
device    /dev/drbd0;                 #
disk      /dev/relay-02/dati;              # ** EDIT ** la partizione data del server 2
address   10.0.0.22:7788;          # ** EDIT ** IP privato del server 2
meta-disk /dev/relay-02/drbd[0];           # ** EDIT ** la partizione da 128MB per DRBD sul server 2
}
}

Ricordatevi di adattare sia i percorsi che gli ip in base alla vostra situazione!

E’ il momento di far partire drbd e di sincronizzare i dati.

relay-01/relay-02

modprobe drbd
drbdadm up all

Potrebbe essere necessario inizializzare i dati, se vi appare questo errore:

Failure: (119) No valid meta-data signature found.

==> Use ‘drbdadm create-md res’ to initialize meta-data area. <==

Command ‘drbdsetup 0 disk /dev/relay-02/dati /dev/relay-02/drdb 0 –set-defaults –create-device –on-io-error=detach’ terminated with exit code 10

Diamo quindi, solo in caso di un errore come quello sopra descritto, i seguenti comandi

drbdadm down all
drbdadm create-md all

Solo sul secondo relay, indipendentemente dalla presenza o meno dell’errore, eseguiamo questo comando

drbdadm — –discard-my-data connect r0

Se si verificassero errori del tipo “detach first” e simili, eseguite sul relay relativo

drbdadm down all

e poi rieseguite il comando di discard

Ultimo passaggio da eseguire sul primo relay

cat /proc/drbd

Quest’ultimo comando dovrebbe darvi un output simile a questo

0: cs:SyncSource st:Primary/Primary ld:Consistent
ns:13441632 nr:0 dw:0 dr:13467108 al:0 bm:2369 lo:0 pe:23 ua:226 ap:0
[==========>………] sync’ed: 53.1% (11606/24733)M
finish: 1:14:16 speed: 2,644 (2,204) K/sec

Quando la sincronizzazione è terminata invece l’output dovrebbe essere simile al seguente

0: cs:Connected st:Primary/Primary ld:Consistent
ns:37139 nr:0 dw:0 dr:49035 al:0 bm:6 lo:0 pe:0 ua:0 ap:0

Per finire, al termine della sincronizzazione, anche il relay-02 deve diventare primario, quindi su ambo i relay, per sicurezza, eseguiamo quest’ultimo comando

drbdadm primary all

Terminati tutti questi passaggi, i due relay sono in “cluster” con i dati delle due partizioni (/dev/mapper/relay–01-dati e /dev/mapper/relay–02-dati) che si sincronizzano in background. Allo stato dell’arte attuale non è ancora possibile lavorare realmente sui dati perchè non abbiamo ancora creato nè il mount point condiviso nè tantomeno abbiamo creato un file system sulle partizioni.

Vediamo come procedere con i passaggi finali.
Cluster in High Availability e Load Balancing – parte 2


Introduzione: Cluster in High Availability e Load Balancing (concetti di base)
Parte uno: Cluster in High Availability e Load Balancing – parte 1 (DRBD)
Parte due: Cluster in High Availability e Load Balancing – parte 2 (ocfs2)
Parte tre: Cluster in High Availability e Load Balancing – parte 3 (cosa e come condividere)