Two Node Cluster mit Pacemaker und Corosync
Vor einiger Zeit habe ich bereits ein Cluster-Setup auf Pacemaker/Corosync-Basis unter Debian Wheezy hier verbloggt. Seitdem hat sich im Pacemakerumfeld ein wenig was getan und somit ist es an der Zeit für ein Update, diesmal mit CentOS7.
Die größte Neuerung (für mich) war der Wegfall des Cluster Resource Managers (crm
), er wird durch pcs
bzw. pcsd
ersetzt, letzterer stellt sogar ein komfortables Webinterface zur Verwaltung des Clusters zur Verfügung.
Aber starten wir mit unseren beiden Clustermaschinen. An dieser Stelle noch der Hinweis dass ein Cluster mit nur 2 Nodes denkbar ungünstig ist, da kein unparteiischer Dritter verfügbar ist, wenn beide Nodes sich dafür entscheiden sollten die aktive Rolle zu übernehmen, zu Demonstrations- und Lernzwecken ist dieses Setup aber gut geeignet und kommt in der Praxis erschreckend oft vor.
Unsere beiden Maschinen haben jeweils 2 Netzwerkkarten mit folgenden Eigenschaften:
-
Hostname: testnode1
- externe IP: 1.2.3.4
- interne IP: 10.0.0.121
- DRBD-Partition: /dev/xvda2
-
Hostname: testnode2
- externe IP: 2.3.4.5
- interne IP: 10.0.0.122
- DRBD-Partition: /dev/xvda2
Die externe Netzwerkkarte wurde bereits beim Setup der Maschinen konfiguriert, die Konfiguration der internen Netzwerkkarte holen wir nun nach:
Auf beiden Nodes führen wir dazu folgenden Befehl aus:
nmtui
Im nun geöffneten Netzwerkmanager gehen wir wie folgt vor:
Eine Verbindung bearbeiten
Kabelgebundene Verbindung 1
Bearbeiten
IPv4 Konfiguration
=>Manuell
Anzeigen
Adressen
=>Hinzufügen
=> 10.0.0.12x/24Gateway
=> 10.0.0.1OK
Beenden
Anschließend starten wir das Netzwerk neu:
systemctl restart network
Mittels ip addr
können wir nun prüfen ob alles funktioniert hat. Es sollten nun zwei Netzwerkinterfaces angezeigt werden. Beide Nodes sollten sich pingen können.
Wir schließen die Netzwerkkonfiguration ab indem wir auf beiden Nodes den Hostname (/etc/hostname
) setzen und beide interne Adressen in /etc/hosts
aufnehmen.
testnode1:
vi /etc/hostname
testnode1
testnode2:
vi /etc/hostname
testnode2
Auf beiden Nodes:
vi /etc/hosts
10.0.0.121 testnode1
10.0.0.122 testnode2
Damit beide Nodes später problemlos miteinander kommunizieren können geben wir das interne Netzwerk in der Firewall komplett frei:
Auf beiden Nodes:
firewall-cmd –zone=trusted –add-source=10.0.0.0/24 –permanent
firewall-cmd –reload
Nun folgt die corosync/pacemaker-Konfiguration:
yum install corosync pacemaker pcs resource-agents
systemctl start pcsd.service
systemctl enable pcsd.service
Damit pcsd
die Kontrolle übernehmen kann müssen wir nun noch ein Kennwort für den Benutzer hacluster
setzen:
Auf beiden Nodes:
passwd hacluster
pcs cluster auth testnode1
pcs cluster auth testnode2
Username: hacluster
Password: ********************
Auf einem der beiden Nodes starten wir nun die initiale Konfiguration des Clusters:
pcs cluster setup –start –name testcluster testnode1 testnode2 –transport udpu
pcs property set stonith-enabled=false
pcs property set no-quorum-policy=ignore
Nun können wir bereits die erste Resource anlegen, die sogenannte Service-IP über die dann der jeweils aktive Node von außen erreichbar sein wird.
pcs resource create VirtualIP ocf:heartbeat:IPaddr2 ip=3.4.5.6 cidr_netmask=32 nic=eth0 op monitor interval=30s
Mittels pcs status
können wir uns das Ergebnis ansehen, im Output sollten folgende Stati aufgeführt werden:
Online: [ testnode1 testnode2 ]
Full list of resources:
VirtualIP (ocf::heartbeat:IPaddr2): Started testnode1
Sollte dies nicht der Fall sein einfach einige Sekunden abwarten und pcs status
erneut ausführen, es dauert ein wenig bis beide Nodes miteinander zu sprechen beginnen.
Damit unser Cluster auch einen Neustart übersteht aktivieren wir nun noch den automatischen Start von corosync und pacemaker beim Boot:
Auf beiden Nodes:
systemctl enable corosync.service
systemctl enable pacemaker.service
Nun können wir uns an DRBD wagen. Mit Hilfe von DRBD legen wir ein Laufwerk an welches die auf ihm gespeicherten Daten vom aktiven Node automatisch auf den inaktiven Node weiterreicht, damit im Failover-Fall der gleiche Datenbestand weiterverwendet werden kann. DRBD ist nicht in den Standard-Repositories von CentOS7 vorhanden, daher binden wir elrepo
ein.
Unsere Festplatte enthält eine leere Partition die wir beim Setup für DRBD reserviert haben (/dev/xvda2
).
Auf beiden Nodes:
rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-2.el7.elrepo.noarch.rpm
yum install kmod-drbd84 drbd84-utils
Damit DRBD korrekt funktioniert muss SELinux abgeschaltet (oder mit einem entsprechenden Regelsatz versehen werden), dies geht im laufenden Betrieb mittels:
setenforce 0
Um SELinux dauerhaft zu deaktivieren setzen wir den Wert enforcing
in /etc/selinux/config
auf permissive
bzw. disabled
:
sed -i ‘s/SELINUX=enforcing/SELINUX=permissive/’ /etc/selinux/config
Anschließend erstellen wir unsere DRBD-Konfiguration in /etc/drbd.conf
:
Auf einem Node:
resource drbd0 {
protocol C;
on testnode1 {
device /dev/drbd0;
disk /dev/xvda2;
address 10.0.0.121:7788;
meta-disk internal;
}
on testnode2 {
device /dev/drbd0;
disk /dev/xvda2;
address 10.0.0.122:7788;
meta-disk internal;
}
}
Hierbei handelt es sich um ein absolutes Minimalbeispiel, eine ausführliche Beispielkonfiguration findet sich in /usr/share/doc/drbd84-utils-8.9.1/drbd.conf.example
Die Konfiguration kopieren wir nun auf den zweiten Node:
scp /etc/drbd.conf 10.0.0.122:/etc/drbd.conf
Nun können wir das DRBD-Laufwerk auf beiden Nodes initialisieren:
drbdadm create-md drbd0
drbdadm up dbd0
Auf einem Node versetzen wir das DRBD-Laufwerk in den primary
-Modus um darauf zugreifen zu können (das Laufwerk im zweiten Node wird dadurch in den secondary
-Mode versetzt und gesperrt:
drbdadm — –o primary drbd0
Nun sollten sich die beiden Laufwerke synchronisieren was wir mittels cat /proc/drbd
überprüfen können, der Output sollte folgendes enthalten:
0: cs:SyncSource ro:Primary/Secondary ds:UpToDate/Inconsistent C r—–
Außerdem sollte es einen Indikator geben wie lange der Synchronisationsvorgang noch dauert und mit welcher Geschwindigkeit er vollzogen wird.
Nun können wir auf dem DRBD-Laufwerk ein Dateisystem anlegen, dies geht nur auf dem Node im primary
-Zustand:
mkfs.ext4 -m0 /dev/drbd0
Das neue Laufwerk können wir nun in unsere Clusterkonfiguration aufnehmen:
pcs resource create p_drbd0 ocf:linbit:drbd params drbd_resource=”drbd0″
pcs resource master ms_drbd0 p_drbd0 master-max=1 master-node-max=1 clone-max=2 clone-node-max=1 notify=true
pcs resource create fs_drbd0 Filesystem device=/dev/drbd0 directory=/var/drbd fstype=ext4
pcs constraint colocation add fs_drbd0 ms_drbd0 INFINITY with-rsc-role=Master
pcs constraint order promote ms_drbd0 then start fs_drbd0
Damit das DRBD-Laufwerk auch immer auf dem Node mit der aktiven Service-IP gemountet wird erstellen wir nun noch eine Gruppe, in diese nehmen wir in Zukunft auch alle weiteren Dienste die der Cluster verwaltet (z.B. httpd) auf:
pcs resource group add grp_all VirtualIP fs_drbd
Damit ist das Setup abgeschlossen.
Der Befehl pcs status
sollte nun folgenden Output zeigen:
Cluster name: testcluster
Last updated: Tue Nov 18 22:37:00 2014
Last change: Tue Nov 18 22:36:59 2014 via cibadmin on testnode1
Stack: corosync
Current DC: testnode2 (2) – partition with quorum
Version: 1.1.10-32.el7_0.1-368c726
2 Nodes configured
4 Resources configured
Online: [ testnode1 testnode2 ]
Full list of resources:
Master/Slave Set: ms_drbd_r0 [p_drbd_r0]
Masters: [ testnode1 ]
Slaves: [ testnode2 ]
Resource Group: grp_all
VirtualIP (ocf::heartbeat:IPaddr2): Started testnode1
fs_drbd (ocf::heartbeat:Filesystem): Started testnode1
PCSD Status:
testnode1: Online
testnode2: Online
Daemon Status:
corosync: active/enabled
pacemaker: active/enabled
pcsd: active/enabled
Ist dies nicht der Fall kann für jede Resource die einen Fehler meldet der Befehl pcs resource cleanup $resource-id
ausgeführt werden, bis alles korrekt funktioniert. Bleibt ein Fehler hartnäckig sollte mittels journalctl -xn
auf Fehlersuche gegangen werden.