ADMIN

2021

06

2021-06-01T12:00:00

Storage-Management

SCHWERPUNKT

070

Storage-Management

Cluster

Cluster-Dateisystem GFS2

Datenjonglage

von Andreas Stolzenberger

Veröffentlicht in Ausgabe 06/2021 - SCHWERPUNKT

Viele Köche verderben bekanntlich den Brei. Ähnlich würde es Daten ergehen, wenn viele Maschinen gleichzeitig auf ein und derselben Festplatte herumrühren. Abhilfe schafft ein Cluster-Dateisystem wie GFS2. Das arbeitet auf gesharten SAN-Platten oder DRBD-Spiegeln. Wir erklären die Basis des Filesystems und beschreiben dessen Installation auf RHEL-Basis.

Spätestens seit dem Siegeszug von vSphere kennt jeder Administrator ein Cluster-Dateisystem: VMFS. Dieses erlaubt mehreren Hypervisoren, gleichzeitig auf ein gemeinsam genutztes SAN-Laufwerk und die dort gesicherten virtuellen Disks zuzugreifen. Allerdings ist VMFS auf den Betrieb mit ESXi-Servern und virtuellen Disks beschränkt.
Ein etwas anderes Ziel verfolg das Open-Source-Dateisystem GFS2 (Global File System). Das soll gesharte SAN-Laufwerke bis zu 16 Linux-Rechnern zur Verfügung stellen, die dabei gleichzeitig lesen und schreiben dürfen. Anders als Netzwerkdateisysteme wie NFS, SMB/CIFS oder GlusterFS liefert GFS2 aber Features eines lokalen Dateisystems, allen voran verschiedene Caching-Funktionen. GFS wurde ursprünglich Mitte der 90er von Professoren und Studenten der University of Minesota für das kommerzielle Unix-Betriebssystem IRIX von Silicon Graphics entwickelt.
2004 landete es schließlich als GFS2 bei Red Hat und ist seither als Open-Source-Dateisystem für nahezu alle Linux-Derivate verfügbar. Es kommt in erster Linie bei Active-Active-Clustern zum Einsatz. Im Internet kursieren etliche Anleitungen, die die Installation von GFS2 sehr einfach erscheinen lassen. Allerdings beziehen sich diese simplen How-tos nahezu alle auf den Single-Node-Betrieb. Dafür braucht es jedoch kein Cluster-Dateisystem. Wer GFS2 ordnungsgemäß im Cluster-Modus betreiben möchte, kommt nicht um den Cluster-Manager Pacemaker [1] mit "STONINH"-Fencing-Konfiguration (Shoot the other Node in the Head) und zwei Lock-Managern herum.
Spätestens seit dem Siegeszug von vSphere kennt jeder Administrator ein Cluster-Dateisystem: VMFS. Dieses erlaubt mehreren Hypervisoren, gleichzeitig auf ein gemeinsam genutztes SAN-Laufwerk und die dort gesicherten virtuellen Disks zuzugreifen. Allerdings ist VMFS auf den Betrieb mit ESXi-Servern und virtuellen Disks beschränkt.
Ein etwas anderes Ziel verfolg das Open-Source-Dateisystem GFS2 (Global File System). Das soll gesharte SAN-Laufwerke bis zu 16 Linux-Rechnern zur Verfügung stellen, die dabei gleichzeitig lesen und schreiben dürfen. Anders als Netzwerkdateisysteme wie NFS, SMB/CIFS oder GlusterFS liefert GFS2 aber Features eines lokalen Dateisystems, allen voran verschiedene Caching-Funktionen. GFS wurde ursprünglich Mitte der 90er von Professoren und Studenten der University of Minesota für das kommerzielle Unix-Betriebssystem IRIX von Silicon Graphics entwickelt.
2004 landete es schließlich als GFS2 bei Red Hat und ist seither als Open-Source-Dateisystem für nahezu alle Linux-Derivate verfügbar. Es kommt in erster Linie bei Active-Active-Clustern zum Einsatz. Im Internet kursieren etliche Anleitungen, die die Installation von GFS2 sehr einfach erscheinen lassen. Allerdings beziehen sich diese simplen How-tos nahezu alle auf den Single-Node-Betrieb. Dafür braucht es jedoch kein Cluster-Dateisystem. Wer GFS2 ordnungsgemäß im Cluster-Modus betreiben möchte, kommt nicht um den Cluster-Manager Pacemaker [1] mit "STONINH"-Fencing-Konfiguration (Shoot the other Node in the Head) und zwei Lock-Managern herum.
Journaling mit an Bord
Damit GFS2 überhaupt mit mehreren Knoten gleichzeitig arbeiten kann, bedarf es besonderer Features, die XFS, BTRFS und anderen Dateisystemen fehlen. Dazu gehören ein verteilter Lock Manager und mehrere Journale. Ein Journal haben heute eigentlich alle modernen Filesysteme: Will ein Prozess etwas auf die Platte schreiben, öffnet das Dateisystem das Journal und verzeichnet dort: "Datum/ Uhrzeit: Prozess XYZ schreibt Daten in die Blöcke a, b und c". Erst dann erfolgt der eigentliche Schreibzugriff. Nach dessen Abschluss löscht das Dateisystem den Journaleintrag.
Der Grund für diesen Aufwand ist simpel: Stürzt der Computer während des Schreibens ab, führt der Rechner einen Dateisystem-Check aus. Der wiederum muss nur im Journal prüfen, was beim Absturz zum Schreiben geöffnet war und beschränkt seine Reparaturen auf genau diese Bereiche. Stundenlange Dateisystem-Checks, die die ganze Platte nach Fehlern absuchen müssen, gibt es seit der Einführung von Journal-Dateisystemen wie NTFS, ext4 oder JFS nicht mehr. GFS2 verwaltet für jeden angebundenen Cluster-Knoten ein eigenes Journal. Die gesamte Zahl der Journale legt der Nutzer beim Formatieren eines GFS2-Datenträgers fest; er kann diese aber später noch erweitern.
Kontrolliert aussperren
Um einen etwas komplexeren Dienst handelt es sich beim verteilten Lock-Manager (dlm). Dieser wacht darüber, welcher Knoten gerade auf welche Blöcke des Dateisystems zugreift. Er verhindert, dass mehrere Knoten simultan in denselben Block schreiben oder dass ein Node in einen Block schreibt, den ein anderer Knoten gerade liest. Zudem gleicht er die Dateisystem-Caches der Knoten ab. Ändert beispielsweise Knoten 1 den Block "xyz", teilt der Lock-Manager den anderen Knoten mit, dass sie diesen Block aus ihrem Cache löschen und neu laden müssen. Theoretisch können mehrere Knoten bei GFS2 in dieselbe Datei schreiben, wenn auch an anderen Stellen. Durch das aufwendige Locking und die damit verbundenen häufigen Cache-Flushes arbeitet GFS2 dann aber sehr langsam. Für eine gute Performance sollten die Applikationen auf den Knoten in eigenen Verzeichnissen und Dateien arbeiten.
Das Locking fällt beispielsweise bei VMFS deutlich simpler aus, da VMFS einfach das komplette Diskabbild einer VM jeweils für einen ESXi-Host exklusiv sperrt. Problematisch wird die Situation, falls ein Knoten abstürzt oder hängen bleibt. Er lässt dann offene Journaleinträge und Locks zurück. Somit können andere Knoten erst einmal nicht die Arbeit des ausgefallenen Nodes fortsetzen. Aus diesem Grund braucht GFS2 das Node-Fencing: Ein abgestürzter Knoten wird "abgeschossen" und somit zwangsweise vom Dateisystem getrennt. Erst dann kann der Lock-Manager dessen Journal prüfen lassen und die Locks freigeben. Das Fencing funktioniert dabei wahlweise über die Maschine direkt (abschalten) oder via SAN (vom LAN/FC trennen).
Ein weiterer Lock-Manager kümmert sich um das Logical-Volume-Management. Der Nutzer will auch im Cluster weiterhin die Möglichkeit haben, neue Dateisysteme zu erstellen oder bestehende zu vergrößern. Zum regulären "Logical Volume Manager" (LVM) gibt es daher verschiedene Cluster-Erweiterungen, wie "HA-LVM" oder "lvmlockd" als Nachfolger von "Cluster LVM" (clvm). HA-LVM kommt bei Virtualisierungslösungen wie oVirt zum Einsatz. Es bestimmt einen Knoten im Cluster als eine Art Master, der als einziger Änderungen am LVM vornehmen darf. Bei lvmlockd darf prinzipiell jeder Knoten gleichberechtigt LVM-Konfigurationen durchführen, wobei der Lock-Manager die jeweiligen Änderungen im Cluster kommuniziert. Die Kontrolle über all diese Dienste vom Dateisystem über Dateisystem-Mount und -Check bis hin zu den Lock-Managern übernimmt in einem GFS2-Verbund Pacemaker.
Wer die Kommandozeile scheut, kann Pacemaker über die Web-GUI auf Port 2224 administrieren und die Ressourcen des Clusters dort konfigurieren.
GFS2 installieren
Für ein GFS2-Test-Setup setzen wir zwei virtuelle Maschinen auf einem KVM-Host auf. Zu den individuellen Boot-Laufwerken erhalten beide VMs Zugriff auf ein gemeinsam genutztes Diskabbild. Damit das funktioniert, müssen Sie diese Disk im Format "raw" anlegen (qcow2 ist für Shared Disks nicht zulässig) und das Abbild mit der Option "shared" hinzufügen. Ähnliche Optionen gibt es bei anderen Virtualisierungsplattformen. Neben einer Shared Disk via Hypervisor funktioniert natürlich auch ein SAN-Laufwerk mit iSCSI oder FC.
Als Betriebssystem nutzen wir für dieses Setup Red Hat Enterprise Linux (RHEL) in Version 8. Denn als wir diesen Artikel verfasst haben, fehlten den aktuellen Builds von CentOS 8 und CentOS Stream 8 die RPM-Pakete des dlm, genauer gesagt das Repo "Resilient Storage". Eine Rückfrage beim Entwicklerteam von CentOS Stream ergab, dass es schlicht und einfach vergessen hat, das Repository bereitzustellen. Plan ist, das fehlende Repository nun anzulegen und auf den Mirrors von CentOS Stream 8 verfügbar zu machen. Sollte das Repository zum Erscheinen dieser Ausgabe existieren, können Sie das Setup also auch auf CentOS Streams 8 statt RHEL 8 durchführen. Ansonsten ist RHEL für den nichtkommerziellen Einsatz kostenfrei [2]. Wer kein RHEL verwenden will, muss sich die passenden Pakete (RPM oder DEB) für Distributionen wie Debian aus verschiedenen Quellen und Repositories zusammenstellen.
Installieren Sie zwei VMs mit RHEL 8, aktivieren Sie die Developer Subscription und fügen Sie die beiden Repositories "High Availability" (Pacemaker) und "Resilient Storage" (GLS & DLM) hinzu:
subscription-manager repos –enable=rhel-8-for-x86_64-highavailability-rpms --enable=rhel-8-for-x86_64-resilientstorage-rpms
Spielen Sie im Anschluss die benötigten Pakete (lvm2-lockd, gfs2-utils, dlm, pcs, pacemaker, fence-agents-all und pcp-zeroconf) über den Yum-Paketmanager auf und starten Sie den Pacemaker-Dienst "pcsd". Konfigurieren Sie dann ein Basis-Setup für Ihre beiden Knoten in Pacemaker und benennen Sie den Cluster:
passwd hacluster
Auf beiden Clustern legen Sie die Authentisierung der Cluster-Knoten fest:
pcs cluster auth <Node1> <Node2>
Authentisieren Sie sich als "hacluster"-User auf beiden Knoten:
pcs cluster setup --name <Cluster-Name> <Node1> <Node2>
Das kann wie beschrieben über das CLI-Tool "pcs" oder alternativ via Pacemaker-Web-UI auf "https://<Knoten>:2224" erfolgen. Je nachdem, auf welcher Plattform Ihre zwei Knoten arbeiten, müssen Sie das dazu passende Fencing einrichten und im Cluster aktivieren (siehe Kasten "Fencing einrichten").
Fencing einrichten
Im beschriebenen Beispiel laufen zwei VMs auf einem KVM-Hypervisor. Der Dienst "fence-virt" erlaubt, dass eine VM via Pacemaker eine andere beendet. Dazu muss auf dem Hypervisor der Dienst "fence-virtd-libvirt" laufen. Den Zugriff zum Fencing-Service sichern Sie über einen Schlüssel ab. Über den Dienst erhalten die Cluster-Knoten eine Liste der laufenden VMs vom Hypervisor. Passend zu den Cluster-Knoten generieren Sie dann Fencing-Profile für die beiden VMs des Clusters. Betreiben Sie das Setup nicht auf KVM, müssen Sie den passenden Pacemaker-Fence-Agenten für Ihre Plattform finden. Agenten gibt es für nahezu alle virtuellen und physischen Umgebungen, wie vSphere, Dell iDRAC, HP iLO, APC Power Distribution oder IPMI.
Mit folgendem Kommando stellen Sie für den Cluster sicher, dass ein Knoten ohne Quorum den Betrieb einstellt:
pcs property set no-quorum-policy=freeze
Danach legen Sie die Ressource-Gruppen für die Lock-Manager an:
pcs resource create dlm --group locking ocf:pacemaker:controld op monitor interval=30s on-fail=fence
 
pcs resource clone locking interleave=true
 
pcs resource create lvmlockd --group locking ocf:heartbeat:lvmlockd op monitor interval=30s on-fail=fence
Laufwerke anlegen
Pacemaker startet nun den lvmlockd-Service auf beiden Knoten. Danach können Sie auf der gesharten Disk den Volume Manager und logische Laufwerke erstellen. Im aufgeführten Beispiel legen wir die Volume Group "gfsvg" und darauf zwei gleich große Volumes "gfs1" und "gfs2"mit jeweils 50 Prozent der VG-Kapazität an.
vgcreate --shared gfsvg /dev/vdb
 
vgchange --lock-start gfsvg
 
lvcreate --activate sy -l50%FREE -n gfs1 gfsvg
 
lvcreate --activate sy -l100%FREE -n gfs2 gfsvg
Die beiden logischen Laufwerke formatieren Sie mit dem GFS2-Dateisystem. Bei "Cluster-Name" fügen Sie den Namen ein, den Sie beim initialen Pacemaker-Setup festgelegt haben.
mkfs.gfs2 -j2 -p lock_dlm -t <Cluster-Name>:gfs1 /dev/gfsvg/gfs1
mkfs.gfs2 -j2 -p lock_dlm -t <Cluster-Name>:gfs2 /dev/gfsvg/gfs2
Legen Sie auf beiden Knoten Mount Points für die Dateisysteme an. In unserem Beispiel sind das "/mnt/gfs1" und "/mnt/gfs2". Abschließend benötigt Pacemaker die entsprechenden Ressourcen für die Dateisysteme und Mount-Points, siehe hierzu Listing 1. Nach dem Abschluss der Konfiguration mounted Pacemaker die GFS2-Dateisysteme auf beiden Knoten. Jetzt können Sie die gewünschten Applikationen einrichten und deren Ressourcen zu Pacemaker hinzufügen.
Listing 1: Ressourcen bereitstellen
pcs resource create sharedlv1 --group gfsvg ocf:heartbeat:LVM-activate lvname=gfs1 vgname=gfsvg activation_mode=shared vg_access_mode=lvmlockd pcs resource create sharedlv2 --group gfsvg ocf:heartbeat:LVM-activate lvname=gfs2 vgname=gfsvg activation_mode=shared vg_access_mode=lvmlockd pcs resource clone gfsvg interleave=true pcs constraint order start locking-clone then gfsvg-clone pcs constraint colocation add gfsvg-clone with locking-clone pcs resource create fs1 --group gfsvg ocf: heartbeat:Filesystem device="/dev/gfsvg/gfs1" directory="/mnt/gfs1" fstype="gfs2" options=noatime op monitor interval=10s on-fail=fence pcs resource create fs2 --group gfsvg ocf: heartbeat:Filesystem device="/dev/gfsvg/gfs2" directory="/mnt/gfs2" fstype="gfs2" options=noatime op monitor interval=10s on-fail=fence
GFS2 ohne SAN
Alternativ können Sie GFS2 ohne ein gemeinsames SAN-Laufwerk nutzen. Dann findet ein Netzwerkspiegel Verwendung, wie ihn das freie DRBD des österreichischen Anbieters LINBIT bereitstellt. Die Abkürzung DRDB steht für "Distributed Replicated Block Device". Vereinfacht gesprochen klinkt sich der DRDB-Kernel-Treiber zwischen das Dateisystem und den Logical Volume Manager ein. Alle schreibenden I/Os, die via Dateisystem an die Festplatte gehen, spiegelt DRBD über das Netzwerk an weitere Knoten. Die sekundären Knoten arbeiten normalerweise passiv und erlauben dem lokalen OS keinen Zugriff auf das Dateisystem, solange der Spiegel arbeitet. DRBD beherrscht seit der Version 9 einen Active-Active-Modus mit einem bidirektionalen Spiegel. Eine simple Active-Passive-Spiegelung mit DRBD beschreibt ebenfalls der bereits erwähnte Pacemaker-Artikel [1] im IT-Administrator.
Für die Spiegelung offeriert DRBD drei verschiedene Protokolle, mit unterschiedlicher Performance und Sicherheit. Setzt eine Applikation einen Write-IO an das Dateisystem ab, wartet sie erst auf die Bestätigung "OK, der Block wurde korrekt auf die Platte geschrieben", bevor sie den nächsten Block schickt. Das sichere DRBD-Protokoll "C" gibt das OK erst dann an die Applikation zurück, wenn der Write I/O auf der lokalen und der gespiegelten Platte geschrieben wurde. Das bremst die Schreibgeschwindigkeit des Datenträgers aus. Dafür stellt dieser Modus sicher (synchroner Spiegel), dass keine Daten während eines Ausfalls verloren gehen, weil sie zwar der primäre, nicht aber der sekundäre Knoten geschrieben hat. Ein bidirektionaler DRBD-Spiegel wie im Text beschrieben funktioniert ausschließlich mit dem Protokoll "C".
Als semi-synchron bezeichnet LINBIT das Protokoll "B". Dieses gibt das OK zurück, wenn das Datenpaket erfolgreich via Netzwerk am sekundären Knoten eingetroffen ist. Es wartet aber nicht mehr ab, bis die entfernte Platte den Vollzug meldet. Dieser Modus offeriert etwas mehr Performance und sollte den meisten Nutzern von Active-Passive-Clustern völlig ausreichen.
Das Protokoll "A" als asynchroner Spiegel schließlich meldet das OK direkt, nachdem das Datenpaket auf dem Primärknoten geschrieben und DRBD zum Spiegeln übergeben wurde. Dieses Protokoll dient zum Backup über langsame Leitungen, also zur Geo-Replication via VPN und Internet zu einem anderen Rechenzentrum. Da DRBD 9 mehrere Spiegel unterstützt, kann der primäre Cluster sein Laufwerk gleichzeitig via Protokoll "C" bidirektional spiegeln und via "A" zum Backupsystem senden.
Um unser Beispiel mit einem DRBD-Volume umzusetzen, müssten Sie wie folgt vorgehen: Die DRBD-Pakete für RHEL gehören nicht zum Standard-Repository, sondern finden sich im "Community Enterprise Linux Repository (elrepo.org)" – nicht zu verwechseln mit dem bekannteren Repository "Extra Packages for Enterprise Linux (EPEL)". Aus elrepo spielen Sie die beiden Pakete "drbd90-utils" und "kmod-drbd90" auf.
Die Konfigurationsdateien für DRBD liegen in "/etc/drbd.d/" und müssen auf allen Knoten identisch sein. Eine globale Konfiguration legt die grundlegenden Parameter fest. Für jedes DRBD-Laufwerk gibt es eine separate Ressource-Datei, die beispielsweise so aussehen kann wie im Listing 2.
Listing 2: Ressource-Datei drbd1.res
resource drbd1 {       meta-disk internal;       protocol B;       device /dev/drbd1;       disk /dev/vdc;       net {                                 protocol C;                                 allow-two-primaries yes;       }       on <node1> {                 node-id 0;       }       on <node2> {                 node-id 1;       }
Das so erzeugte DRBD-Volume starten Sie auf beiden Knoten und aktivieren den bidirektionalen Spiegel. Sobald dieser läuft, verfahren Sie mit dem LVM und GFS2-Setup und der Pacemaker-Integration wie oben beschrieben. Zusätzlich müssen Sie dann aber auch die Pacemaker-Ressourcen für DRBD selbst anlegen.
Fazit
Ein Cluster mit GFS2 und einem FC/iSCSI-SAN-Laufwerk lässt sich leider nicht in wenigen simplen Schritten aufsetzen. Sobald Sie das Setup mit dlm, lvmlockd, fencing und Pacemaker jedoch abgeschlossen haben, erhalten Sie einen robusten Active-Active-Cluster mit einem gemeinsamen Block-Device. Ob GFS2 in Ihrem Setup performant arbeitet, hängt letzten Endes davon ab, wie Ihre verteilten Workloads mit dem Dateisystem umgehen.
Arbeiten Knoten simultan schreibend mit den gleichen Dateien und Verzeichnissen, kann GFS2 den Caching-Vorteil eines lokalen Dateisystems kaum ausspielen. Ein Cluster mit überwiegend lesenden Zugriffen (zum Beispiel Webserver-Farm mit statischem HTML-Content auf GFS2) liefert jedoch eine sehr gute Performance. Das SAN-lose GFS2 mit DRBD ist noch komplizierter zu verwalten. Hier sollten Nutzer auf jedem Fall prüfen, ob etwa ein deutlich einfacheres GlusterFS-Setup nicht die bessere Lösung darstellt.
(ln)
Link-Codes
[1] IT-Administrator: "Mit Pacemaker Dienste hochverfügbar betreiben", Ausgabe 12/2020, Seite 83: https://www.it-administrator.de/magazin/heftarchiv/artikel/339201.html
[2] Red Hat Enterprise Linux Entwickler-Download: https://developers.redhat.com/products/rhel/download