Für Wartungszwecke und um Ausfallsicherheit sicherzustellen führen wir heute den Aufbau eines hochverfügbaren Apache Cluster mit 2 Knoten auf Basis von Debian 12 durch.

Ich habe das Setup auf virtuellen Maschinen gebaut. Genauso funktionieren aber auch Raspberry Pi´s oder ein Mini-PC mit z.B. Proxmox.

Wir haben folgende Ausgangslage:

  • Knoten 1: IP: 192.168.1.21/24
  • Knoten 2: IP: 192.168.1.22/24
  • Virtuelle floating IP: 192.168.1.200/24

Vorbereiten der beiden Knoten

Zunächst loggen wir uns auf den beiden Knoten per SSH ein. Die allermeisten Schritte führen wir auf beiden Knoten aus – es sei denn ich erwähne explizit, dass es nur auf einem der beiden Knoten gemacht werden soll.

apt update
apt upgrade -y

Anschließend installieren wir Heartbeat

apt install heartbeat -y

Und den eigentlichen Apache2 Webserver:

apt install apache2 -y

Entferne nun apache2 aus dem „Autostart“. Das ist wichtig, sonst funktioniert das Heartbeat nicht korrekt:

update-rc.d -f apache2 remove

Nun müssen wir Datei /etc/sysctl.conf editieren und eine Zeile einfügen und anschließend mittels sysctl -p übernehmen

nano /etc/sysctl.conf
net.ipv4.ip_nonlocal_bind=1
sysctl -p

Jetzt legen wir die Datei /etc/ha.d/authkeys an und füllen sie mit dem nachfolgenden:

#nano /etc/ha.d/authkeys
auth 3
3 md5 somerandomstring

„somerandomstring“ ersetzt du mit einem persönlichen „Kennwort“. Anschließend setzen wir die Berechtigung der Datei auf „600“.

chmod 600 /etc/ha.d/authkeys

Jetzt legen wir die heartbeat Konfiguration an. Dazu erstellen wir die ha.cf neu.

# nano /etc/heartbeat/ha.cf
keepalive 2
#
#       deadtime: seconds-to-declare-host-dead
#
deadtime 10
#
#       What UDP port to use for udp or ppp-udp communication?
#
udpport        694
bcast  ens192
mcast ens192 225.0.0.1 694 1 0
ucast ens192 192.168.1.21 #die IP des anderen Knotens
#       What interfaces to heartbeat over?
udp     ens192
#
#       Facility to use for syslog()/logger (alternative to log/debugfile)
#
logfacility     local0
#
#       Tell what machines are in the cluster
#       node    nodename ...    -- must match uname -n
node    apache01
node    apache02

Bei ucast passt du die IP Adresse entsprechend an. Auf Knoten 2 wird die IP des 1. eingetragen und anders herum. Unten hinter „node“ schreibst du die Hostnamen der beiden teilnehmenden Knoten. Stelle sicher, dass sich beide über den Namen erreichen können. Falls dein Netzwerkinterface (ip addr) nicht ens192 ist, passe es an (z.B. eth0).

Erstelle jetzt wieder auf beiden Nodes die Datei /etc/ha.d/haresources. Bei beiden Knoten kommt exakt der gleiche Inhalt rein.

#nano /etc/ha.d/haresources
apache01  IPaddr::192.168.1.200/24/ens192 apache2

Sowohl auf Knoten 1 als auch Knoten 2 kommt der gleiche Inhalt rein. Den Hostnamen vorne passt du auf deinen Primären Knoten an und IPaddr. auf deine Floating IP, sowie ens192 ggf. auf das Interface, wie es bei dir heißt.

Konfiguration abgeschlossen – jetzt testen

Die Basis-Konfiguration für das Apache Cluster ist fertig. Jetzt müssen wir alles starten und testen.

Dazu starten wir zunächst Heartbeat:

/etc/init.d/heartbeat start

Jetzt prüfst du mit „ip addr“ ob der erste Knoten die Floating IP Adresse bekommen hat, während der Zweite Knoten diese nicht bekommen hat.

ens192: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:50:56:03:07:44 brd ff:ff:ff:ff:ff:ff
    altname enp11s0
    inet 192.168.1.21/24 brd 192.168.1.255 scope global ens192
       valid_lft forever preferred_lft forever
    inet 192.168.1.200/24 brd 192.168.1.255 scope global secondary ens192:0
       valid_lft forever preferred_lft forever
    inet6 fe80::250:56ff:fe03:744/64 scope link
       valid_lft forever preferred_lft forever

Ist das der Fall funktioniert das schon mal korrekt. Nun können wir testen, ob der Apache auch erreichbar ist. Dazu eignet sich auf die schnelle z.B. cURL auf den Nodes zu installieren.

apt install curl

Danach können wir vom 2. Knoten die VIP aufrufen:

curl 192.168.1.200

Jetzt bekommen wir, wenn alles klappt den HTML Quellcode der Website zurückgeliefert.

Failover des Apache Cluster testen

Damit wir jetzt wissen, ob auch beide Knoten funktionieren, testen wir das Failover. Dazu können wir den Knoten 1 natürlich brutal ausschalten, oder aber einfach den Heartbeat Dienst stoppen.

Sobald der Heartbeat nicht mehr antwortet, „schwenkt“ die Floating IP auf den anderen Knoten und der Apache2 Dienst wird gestartet.

/etc/init.d/heartbeat stop

Anschließend können wir auf dem 2. Knoten „ip addr“ aufrufen und sehen, dass die Floating IP jetzt dort am Interface angehängt ist. cURL vom 1. Knoten aus auf die Floating IP funktioniert.

ens192: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:50:56:03:07:45 brd ff:ff:ff:ff:ff:ff
    altname enp11s0
    inet 192.168.1.22/24 brd 192.168.1.255 scope global ens192
       valid_lft forever preferred_lft forever
    inet 192.168.1.200/24 brd 192.168.1.255 scope global secondary ens192:0
       valid_lft forever preferred_lft forever
    inet6 fe80::250:56ff:fe03:745/64 scope link
       valid_lft forever preferred_lft forever
curl 192.168.1.200

Zu beachten beim Apache Cluster

In dieser Konfiguration ist es notwendig, dass die Webseiten-Daten auf beiden Knoten gepflegt werden. Also beide Apache Server müssen den gleichen Content unter /var/www/ (oder wo auch immer euer Web-Root ist) haben. Diese Daten werden nicht gespiegelt. Wenn man das machen möchte kann man das bestehende Setup mit DRBD erweitern. Siehe auch meine Anleitung zum Hochverfügbaren NFS Server. Dort ist der Einsatz Heartbeat + DRBD mit Floating IP und Replizierenden Datenlaufwerken beschrieben.

Ansonsten musst du nun nur noch deine Public IP auf die Floating IP weiterleiten und schon ist alles erreichbar.

P.S. ein sehr ähnliches Konstrukt mit ziemlich identischem Ausgang erreichst du auch mit einem Loadbalancer/Reverse Proxy davor. Die hier beschriebene Konfiguration spart allerdings eine Maschine.