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/24
  • Gateway => 10.0.0.1
  • OK
  • 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.

Nächster Beitrag Vorheriger Beitrag