de DevOps Software KeepaliveD

Mit keepalived die Verfügbarkeit von Diensten erhöhen

Bei wichtigen Diensten ist es immer Sinnvoll diese auf mehreren Servern zu installieren. Das reicht allerdings meistens nicht, da der Dienst bei einem Ausfall des Servern trotzdem nicht mehr erreichbar ist und daher im Idealfall unter der gleichen IP-Adresse zur Verfügung stehen müsste. Das ganze geht relativ leicht ohne mit großen und komplexen Programmen wie Heartbeat. Pacemaker und Corosync hantieren zu müssen. Die drei Anwendungen sind sehr mächtig was Umfang und Konfiguration angeht und sind daher schon fast zu komplex für unseren einfachen Anwendungsfall, da geht es nämlich auch eine Nummer kleiner: Mit keepalived

Was ist keepalived

keepalived ist ein Service, der fast in jeder Linux-Distribution enthalten ist oder aber nahezu immer über die Standard-Paketquellen bezogen werden kann. Mit diesem Dienst kann man nun sogenannte Floating IPs (IP-Adressen die im Netzwerk reserviert sind um dynamisch zwischen Servern zu wechseln) den beteiligten Servern zuweisen. Die IPs werden nun durch den keepalive-Prozess überwacht und verwaltet.

Vorbereitung

Als Vorbereitung habe ich hier zwei Ubuntu 18.04 Server mit folgenden Namen und IP-Adressen:

  • server1 => 192.168.1.2
  • server2 => 192.168.1.3
  • floatingIP => 192.168.1.10 Genauere Angaben zu den Versionen sind hier noch zu lesen
 1root@server1:~# cat /etc/lsb-release
 2DISTRIB_ID=Ubuntu
 3DISTRIB_RELEASE=18.04
 4DISTRIB_CODENAME=bionic
 5DISTRIB_DESCRIPTION="Ubuntu 18.04.5 LTS"
 6root@server2:~# cat /etc/lsb-release
 7DISTRIB_ID=Ubuntu
 8DISTRIB_RELEASE=18.04
 9DISTRIB_CODENAME=bionic
10DISTRIB_DESCRIPTION="Ubuntu 18.04.5 LTS"

Außerdem habe ich keepalived schon installiert mittels apt install keepalived und steht mir in folgender Version zur Verfügung

1root@server1:~# keepalived --version
2Keepalived v1.3.9 (10/21,2017)
3Copyright(C) 2001-2017 Alexandre Cassen, <acassen@gmail.com>
4Build options:  PIPE2 IPV4_DEVCONF LIBNL3 RTA_ENCAP RTA_EXPIRES RTA_NEWDST RTA_PREF RTA_VIA FRA_OIFNAME FRA_SUPPRESS_PREFIXLEN FRA_SUPPRESS_IFGROUP FRA_TUN_ID RTAX_CC_ALGO RTAX_QUICKACK FRA_UID_RANGE LWTUNNEL_ENCAP_MPLS LWTUNNEL_ENCAP_ILA LIBIPTC LIBIPSET_DYNAMIC LVS LIBIPVS_NETLINK IPVS_DEST_ATTR_ADDR_FAMILY IPVS_SYNCD_ATTRIBUTES IPVS_64BIT_STATS VRRP VRRP_AUTH VRRP_VMAC SOCK_NONBLOCK SOCK_CLOEXEC GLOB_BRACE OLD_CHKSUM_COMPAT FIB_ROUTING INET6_ADDR_GEN_MODE SNMP_V3_FOR_V2 SNMP SNMP_KEEPALIVED SNMP_CHECKER SNMP_RFC SNMP_RFCV2 SNMP_RFCV3 DBUS SO_MARK
5root@server2:~# keepalived --version
6Keepalived v1.3.9 (10/21,2017)
7Copyright(C) 2001-2017 Alexandre Cassen, <acassen@gmail.com>
8Build options:  PIPE2 IPV4_DEVCONF LIBNL3 RTA_ENCAP RTA_EXPIRES RTA_NEWDST RTA_PREF RTA_VIA FRA_OIFNAME FRA_SUPPRESS_PREFIXLEN FRA_SUPPRESS_IFGROUP FRA_TUN_ID RTAX_CC_ALGO RTAX_QUICKACK FRA_UID_RANGE LWTUNNEL_ENCAP_MPLS LWTUNNEL_ENCAP_ILA LIBIPTC LIBIPSET_DYNAMIC LVS LIBIPVS_NETLINK IPVS_DEST_ATTR_ADDR_FAMILY IPVS_SYNCD_ATTRIBUTES IPVS_64BIT_STATS VRRP VRRP_AUTH VRRP_VMAC SOCK_NONBLOCK SOCK_CLOEXEC GLOB_BRACE OLD_CHKSUM_COMPAT FIB_ROUTING INET6_ADDR_GEN_MODE SNMP_V3_FOR_V2 SNMP SNMP_KEEPALIVED SNMP_CHECKER SNMP_RFC SNMP_RFCV2 SNMP_RFCV3 DBUS SO_MARK

Die Server konfigurieren

Hier geht es um die eigentliche Konfiguration. Dabei gibt es folgende zwei Möglichkeiten das Programm zu konfigurieren: Die erste Möglichkeit wäre ein Aktiv-Passiv zu machen. Dabei wird ein Server als aktiver Knoten eingestellt, welcher die IP-Adresse bekommt. Der Knoten verliert die IP-Adresse bei einem Fehler an den Passiven Knoten bekommt Sie allerdings sofort wieder wenn er wieder bereit steht. Das andere Szenario ist das Aktiv-Aktiv Szenario und besteht eigentlich aus nur einem Unterschied, nämlich dass der andere Knoten die IP-Adresse auch erst wieder hergibt wenn dieser einen Fehler hat.

Allgemeine Konfiguration

Hier möchte ich auf die verschiedenen Möglichkeiten eingehen welche Optionen grob zur Verfügung stehen um im Anschluss die Unterschiede der beiden Konfigurationen zu zeigen.

Die Konfiguration ist eigentlich sehr einfach. Man fängt erstmal an eine vrrp_instance mit einem Namen zu erstellen. Eine vrrp_instance ist ein keepalive Dienst (Prozess), denn man kann auch mehrere auf einem Server laufen lassen.

1vrrp_instance MASTER{
2}

leere VRRP Instanz mit dem Namen MASTER(dieser Name kann frei gewählt werden)

Als nächstes können ein paar Grundeinstellungen getätigt werden.

1vrrp_instance MASTER {
2  interface                 eth0
3  state                     MASTER
4  virtual_router_id         50
5  priority                  100
6}
  • Hier wird die Netzwerkschnittstelle (interface) angegeben auf welchem der keepalive-Daemon läuft (dient zum Nachrichtenaustausch).
  • Der state (entweder MASTER oder BACKUP) gibt den ersten State an, den ein Server hat. Ist aber erstmal nicht allzu wichtig, da es eine Wahl von allen beteiligten Nodes gibt die online kommen um einen neuen MASTER zu wählen. Die Wahl gewinnt der Node mit der höchsten Nummer.
  • Die virtuelle router id (virtual router id) kennzeichnet eine eindeutige Instanz. Daher muss Sie auf allen Servern die selbe Zahl sein und unterscheidet sich nur zwischen den verschiedenen Instanzen.
  • Die Priorität (priority) gibt an in welcher Reihenfolge oder welche Wahrscheinlichkeit es gibt, dass der Server die IP-Adresse bekommt. Nun können wir anfangen das interface anzugeben und welche IP-Adresse zugewiesen werden soll.
1virtual_ipaddress {
2  192.168.1.10/24 dev eth0
3}

Als letztes können wir noch die Priorität einer Instanz basierend auf den Status einer Schnittstelle anpassen um bei mehreren Schnittstellen bestimmte Interfaces zu bevorzugen.

1track_interface {
2  eth0
3}

Außerdem kann zusätzlich noch eine Authentifizierung angegeben werden, damit nicht einfach jeder Server sich mit dem Cluster verbinden kann und bei einem Ausfall die aktive Rolle übernehmen kann.

1authentication {
2  auth_type PASS
3  auth_pass meinGeheimnis
4}

Damit hätten wir quasi alle Einstellungen vorgestellt und können nun den ersten Server anfangen zu konfigurieren.

 1vrrp_instance MASTER {
 2  interface                 eth0
 3  state                     MASTER
 4  virtual_router_id         50
 5  priority                  100
 6  authentication {
 7    auth_type PASS
 8    auth_pass meinGeheimnis
 9  }
10  track_interface {
11    eth0
12  }
13  virtual_ipaddress {
14    192.168.1.10/24 dev eth0
15  }
16}

Aktiv-Passiv Konfiguration

Die Aktiv Passiv Konfiguration ist eine Konfiguration, bei der ein Server der Aktive ist und die Floating-IP zu gewiesen bekommt. Nachdem dieser Server ausgefallen ist wird die Floating-IP auf den zweiten Server geschwenkt um beim wiederbeleben des ersten Servers wieder auf diesen zu wechseln.

Um so ein Verhalten zu konfigurieren, müssen wir die Datei /etc/keepalived/keepalived.conf anpassen. Dafür können wir an der Standard-Konfiguration von oben alles so belassen wie es ist und lediglich bei dem anderen Server (server2 in unserem Fall) die Priorität runter stellen und zusätzlich noch den state auf BACKUP setzen, obwohl dass auch irrelevant wäre, da die Wahl zum MASTER sowieso unser Server1 gewinnen würde. Wenn man den State auf BACKUP setzt ist es lediglich direkt für jeden Sichtbar was wir vorhaben.

Die Konfiguration sieht also nun so aus:

 1root@server1:~# cat /etc/keepalived/keepalived.conf
 2vrrp_instance MASTER {
 3  interface                 eth0
 4  state                     MASTER
 5  virtual_router_id         50
 6  priority                  100
 7  authentication {
 8    auth_type PASS
 9    auth_pass meinGeheimnis
10  }
11  track_interface {
12    eth0
13  }
14  virtual_ipaddress {
15    192.168.1.10/24 dev eth0
16  }
17}
18root@server2:~# cat /etc/keepalived/keepalived.conf
19vrrp_instance MASTER {
20  interface                 eth0
21  state                     BACKUP
22  virtual_router_id         50
23  priority                  90
24  authentication {
25    auth_type PASS
26    auth_pass meinGeheimnis
27  }
28  track_interface {
29    eth0
30  }
31  virtual_ipaddress {
32    192.168.1.10/24 dev eth0
33  }
34}

Aktiv-Aktiv Konfiguration

Der Unterschied hierbei zur Aktiv-Passiv Konfiguration ist dieser, dass hierbei die Floating-IP bei dem anderen Server bleibt und nicht zurück geschwenkt wird, wenn dieser wieder belebt wurde.

Um so ein Verhalten zu konfigurieren, müssen wir die Datei /etc/keepalived/keepalived.conf anpassen. Dafür können wir an der Standard-Konfiguration von oben soweit alles so belassen wie es ist, beide Server zum BACKUP machen und bei einem die Priorität erhöhen oder bei dem anderen senken (so dass es zwei verschiedene Prioritäten gibt). Zusätzlich muss noch das Attribut nopreempt gesetzt werden.

Die Konfiguration sieht also nun so aus:

 1root@server1:~# cat /etc/keepalived/keepalived.conf
 2vrrp_instance MASTER {
 3  interface                 eth0
 4  state                     MASTER
 5  virtual_router_id         50
 6  priority                  100
 7  nopreempt
 8  authentication {
 9    auth_type PASS
10    auth_pass meinGeheimnis
11  }
12  track_interface {
13    eth0
14  }
15  virtual_ipaddress {
16    192.168.1.10/24 dev eth0
17  }
18}
19root@server2:~# cat /etc/keepalived/keepalived.conf
20vrrp_instance MASTER {
21  interface                 eth0
22  state                     BACKUP
23  virtual_router_id         50
24  priority                  90
25  nopreempt
26  authentication {
27    auth_type PASS
28    auth_pass meinGeheimnis
29  }
30  track_interface {
31    eth0
32  }
33  virtual_ipaddress {
34    192.168.1.10/24 dev eth0
35  }
36}

Den Service starten

Erstmal muss sichergestellt werden, dass der Service auch läuft. Das kann unter Ubuntu zum Beispiel mittels service keepalived status überprüft werden. Im idealfall sieht die Ausgabe wie folgt aus

1● keepalived.service - Keepalive Daemon (LVS and VRRP)
2   Loaded: loaded (/lib/systemd/system/keepalived.service; enabled; vendor preset: enabled)
3   Active: active (running) since Thu 2021-04-08 08:38:37 CEST; 1 weeks 0 days ago
4 Main PID: 1453 (keepalived)
5    Tasks: 3 (limit: 9345)
6   CGroup: /system.slice/keepalived.service
7           ├─1453 /usr/sbin/keepalived
8           ├─1457 /usr/sbin/keepalived
9           └─1458 /usr/sbin/keepalived

Die Konfiguration testen

Die Konfiguration ist sehr einfach zu testen. Dafür können wir einfach den Server herunterfahren, der aktuell die floating IP hat und schauen ob der andere Server diese IP hinzugefügt bekommt. Je nachdem welches Konzept wir benutzt haben lässt sich danach auch sicherstellen ob die floating IP bei dem Server verbleibt oder aber wieder zurück zu dem anderen Server geht.

Die IP lässt sich unter gängigen Linux-Distributionen mit ip a anzeigen. Das Kommando gibt nun folgendes Beispielhaft aus.

 1root@server1:~# ip a
 21: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
 3    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
 4    inet 127.0.0.1/8 scope host lo
 5       valid_lft forever preferred_lft forever
 6    inet6 ::1/128 scope host 
 7       valid_lft forever preferred_lft forever
 82: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
 9    link/ether 03:8f:58:4c:0d:b7 brd ff:ff:ff:ff:ff:ff
10    inet 192.168.1.2/24 brd 192.168.1.255 scope global eth0
11       valid_lft forever preferred_lft forever
12    inet 192.168.1.10/24 scope global eth0
13       valid_lft forever preferred_lft forever