Gluster-Storage bei Laune halten
Unser Beitrag im Linux-Magazin 2019-06.
Wenn Gluster nicht mehr tut, wie es soll, ist der Ausfall eines damit umgesetzten File-Servers ärgerlich. Schmerzhaft wird es, wenn Gluster das Storage-Rückgrat einer Virtualisierungslösung ist.
Gluster eignet sich hervorragend als fehlertolerantes Storage-Backend für einen Hypervisor wie oVirt. Damit haben aber auch Probleme und Ausfälle in Gluster besondere Auswirkungen auf den Betrieb. Ein mit sich selbst beschäftigter Gluster im inkonsistenten Zustand kann darauf laufende VMs massiv in ihrer Performance beeinträchtigen. Als Admin steht man dann unter besonders starkem Druck und fragt sich, was zu tun ist und welche Folgen die Ausführung eines Kommandos haben kann, will man nicht in Minuten um Jahre altern. Eine kleine Auswahl.
Die Lernkurve ist nicht so steil wie bei Ceph: wer Gluster einsetzt, muss zunächst nur einige wenige Konzepte und Begriffe kennen.
Die Teilnehmer eines Gluster-Clusters bilden einen „Trusted Server Pool“ (TSP) und werden Host, Node oder Peer genannt.
Die in Gluster eingebundenen Disks mit ihren Partitionen und Dateisystemen heissen „Bricks“.
Bricks können lokal oder idealerweise über das Netzwerk mit je eigenem TCP-Port eingebunden werden.
Zwei oder mehr Bricks werden zu einem Gluster-„Volume“ zusammengefasst.
Gluster kann Daten n-fach repliziert über die Bricks verteilt ablegen und lesen.
Da Gluster also einzelne, bestehende Dateisysteme zu einem oder mehreren Volumes kombiniert, ist es kein Dateisystem im eigentlichen Sinne, auch wenn das „FS“ in „GlusterFS“ anderes vermuten lässt.
Seit Anfang April 2019 ist Gluster 6 ab CentOS 6 und höher verfügbar und kann auf CentOS 7 wie folgt installiert werden:
yum install centos-release-gluster
yum install glusterfs-server
systemctl enable glusterd
systemctl start glusterd
oVirt 4 verlangt nach der älteren Version 3.12 (offiziell EOL), welches über die oVirt-Repos bezogen wird.
Ein Volume namens data
mit drei Disks, die jeweils auf einem Host
liegen, mit dreifacher Redundanz und ohne weitere Optimierungen, ist
schnell eingerichtet.
Auf host1
:
gluster peer probe host2
gluster peer probe host3
gluster volume create data replica 3 \
host1:/gluster/brick/data \
host2:/gluster/brick/data \
host3:/gluster/brick/data
gluster volume start data
Hausaufgaben
Wer Gluster verteilt betreibt, kommt um zwei Voraussetzungen nicht
herum: korrekte DNS-Einträge für die Gluster-Nodes (Forward und Reverse)
sowie ein zuverlässiges NTP-Setup. Für den Fall, dass die
DNS-Infrastruktur nicht verfügbar ist, sollte der Admin vorsichtshalber
alle beteiligten Gluster-Nodes in der /etc/hosts
eintragen.
Gegen den Reflex - Host-Firewalls abschalten
Host-Firewalls sind super - ausser wenn sie stören. Da die Gluster-Nodes meist in einer vertrauenswürdigen Umgebung laufen, sollte man deren lokale Firewalls deaktivieren. Was sich im ersten Moment unvernünftig anhört, hat einen handfesten Grund: Storage-Server sollen Daten schnell und vor allem zuverlässig verarbeiten können. Sind durch eine versehentlich aktivierte und falsch konfigurierte Host-Firewall Bricks auf ihren Netzwerk-Ports nicht erreichbar, kann das zur Inkonsistenz und im schlimmsten Fall zum Ausfall des Storage-Systems führen. Messbare Performance-Zuwächse oder Entlastung der Nodes durch das Abschalten der Host-Firewall sind dagegen kaum zu erwarten.
Für den Fall, dass die Firewall aus Versehen aktiviert wird, sollte sie so tolerant und auskunftsfreudig wie möglich konfiguriert werden:
firewall-cmd --set-log-denied=all
firewall-cmd --permanent --zone=public --add-source=192.168.100.0/24
firewall-cmd --permanent --zone=public --add-port=1-65535/tcp
firewall-cmd --permanent --zone=public --add-port=1-65535/udp
firewall-cmd --reload
firewall-cmd --list-all
systemctl stop firewalld
systemctl disable firewalld
Mein Name ist Bond
Falls die Kommunikation zwischen den Gluster-Nodes zickt oder die VMs auf dem Hypervisor nicht funktionieren, sollte man prüfen, ob und in welcher Form Bonding-Interfaces eingesetzt werden. Falls ja, sollte dem Bonding-Mode besondere Aufmerksamkeit geschenkt werden: er hängt davon ab, ob Gluster dediziert auf den Hosts zum Einsatz kommt (egal ob virtuell oder auf Bare Metal), oder ob Gluster sich die Maschine mit einem Hypervisor wie Red Hat Enterprise Virtualization (RHEV) oder dessen Upstream-Pendant oVirt teilen muss und eine „Hyperconverged Infrastructure“ bildet.
Das Gluster-Projekt empfiehlt für die Gluster-Nodes zunächst einmal den Bonding-Mode 6 (Adaptive Load Balancing, balance-alb). Damit können Clients die meisten Schreibanfragen parallel über alle verbundenen Netzwerk-Interfaces der Gluster-Nodes senden. Das Problem: Bonding Mode 6 kann nicht zusammen mit Bridges verwendet werden, und ist daher nicht mit logischen Netzwerken in VMs kompatibel. Wer also eine Hyperconverged Infrastruktur betreibt, setzt bei oVirt/RHEV auf den dort empfohlenen Bonding Mode 4 (IEEE 802.3ad policy).
Auch schon vorgekommen: ein Switch war fälschlicherweise der Meinung, dass sich die Interface-Geschwindigkeit von beispielsweise 10 Gbps auf 1 Gbps geändert hat, und handelte die Verbindung neu aus - um sich kurz danach wieder umzuentscheiden. Ein Node im stark ausgelasteten Gluster-Cluster wurde dadurch zweimal kurz abgehängt, was anschliessend zur Synchronisation und noch stärkerer Auslastung führte. Man kann sich daher überlegen, auf dem Switch die Geschwindigkeit der Netzwerk-Interfaces fix auf den zu erwartenden Wert einzustellen.
Bemerkung
Restart des glusterd
Ein systemctl restart glusterd
führt dazu, dass der Node und
dessen Bricks kurzzeitig abgehängt werden. Alle ab sofort im
Gluster-Cluster stattfindenden Schreibvorgänge werden protokolliert
und, sobald der Node wieder verfügbar und die Selbstheilung
angestossen ist, synchronisiert, was je nach Schreiblast und
Infrastruktur Stunden in Anspruch nehmen kann. Wird glusterd
auf
dem Host neu gestartet, mit dem man per FUSE-Mount verbunden ist,
geht kurz die Verbindung verloren.
Jumbo-Performance
Jumbo-Frames sind ein oft eingesetztes Mittel, um den Netzwerkdurchsatz signifikant zu steigern. Wer mit Netzwerkproblemen zwischen den Gluster-Nodes zu kämpfen hat, sollte daher prüfen, ob Jumbo-Frames aktiviert sind und noch funktionieren.
Jumbo-Frames sind aktiv, wenn die Gluster-Nodes über ip a | grep mtu
eine MTU grösser als 1500 melden, üblicherweise 9000. Allerdings müssen
auch alle dazwischen liegenden Netzwerkkomponenten Jumbo-Frames
unterstützen. Das Senden überlanger Frames von einem Gluster-Node zum
nächsten testet man mit ping -s 1600 -M do <gluster-node-n>
, wobei
-s
die Paketgrösse ohne Header festlegt, und -M do
die
Fragmentierung auf dem Weg zum Empfänger verhindert.
yum
Falls das erste Mal yum update
auf einem Node ausgeführt wird, kann
die Fehlermeldung „GPG key retrieval failed: [Errno 14] Could not
open/read file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-auxiliary“ für
Unbehagen sorgen, aber getrost ignoriert werden; beim zweiten Aufruf von
yum update
wird die Meldung nicht mehr erscheinen.
Schlimmer wird es, wenn nach einem yum update
ein Gluster-Host zwar
noch erreichbar ist, aber dessen Bricks nicht mehr. Hier hilft eine
schnelle Analyse der Log-Files. So wurden schon Shared Object Libraries
(.so
-Dateien) entfernt, die je nach Konfiguration für den Betrieb
von Gluster notwendig sind, was sich in den Log-Dateien in der Art
/usr/lib64/glusterfs/3.12.6/rpc-transport/rdma.so: cannot open shared object file: No such file or directory
äussert. Wer in diesem Fall auf RDMA, also Speicherdirektzugriff über
das Netzwerk, verzichten kann, deaktiviert RDMA in der
/etc/glusterfs/glusterd.vol
und startet den Gluster-Daemon neu.
Nach einem Update darauf achten: wer die Host-Firewall auf seinen Gluster-Nodes deaktiviert hatte, sollte vor einem Reboot prüfen, ob sie immer noch deaktiviert ist.
Selbstheilungsmechanismus
Der Gluster-Cluster befindet sich in einem inkonsistenten Zustand? Wer
sich wundert, wann der Gluster „Self-heal Daemon“ (glustershd
)
endlich mit dem Selbstheilungsprozess beginnt, wirft einen Blick in das
Setting gluster volume get <volname> cluster.heal-timeout
, was
standardmässig auf 600 Sekunden steht - im Produktivbetrieb meiner
Meinung nach zu lang, in der Zeit laufen die Bricks zu stark
auseinander. Um den Mechanismus von Hand anzustossen, genügt der Aufruf
von gluster volume heal <volname>
, der Fortschritt wird mit
gluster volume heal <volname> info
überwacht. Viele Volume-Settings
lassen sich übrigens zur Laufzeit ändern, ohne die Gluster-Daemons neu
starten zu müssen. Ist das Self-Healing angestossen, heisst es, sich in
Geduld zu üben.
Bemerkung
Gluster-Brick in zwei verschiedenen Zuständen
# konsistent
Brick host42:/gluster/arb2/data
Status: Connected
Number of entries: 0
# inkonsistent
Brick host42:/gluster/arb2/data
/.shard/6aa1460a-298b-45b9-972d-39dfc4400ac1.35
/.shard/6aa1460a-298b-45b9-972d-39dfc4400ac1.82
/.shard/6aa1460a-298b-45b9-972d-39dfc4400ac1.30
/.shard/6aa1460a-298b-45b9-972d-39dfc4400ac1.93
/.shard/6aa1460a-298b-45b9-972d-39dfc4400ac1.18
Status: Connected
Number of entries: 5
Je nach Grad der Replikation hat ein inkonsistenter Zustand oder die
Replikation keine Auswirkungen auf die Datenintegrität, jedoch auf die
Performance angeschlossener Clients oder VMs, denn ähnlich einem
klassischen RAID wird Gluster die inhaltlich auseinandergelaufenen
Bricks synchronisieren. Die Load geht dabei teilweise extrem hoch,
limitierender Faktor ist in fast allen Fällen I/O, also Disk und/oder
Netzwerk.
kernel:NMI watchdog: BUG: soft lockup - CPU#0 stuck for 22s!
oder
ata2.00: exception Emask 0x0 ... frozen
sind die typischen Kernel
Ring Buffer-Meldungen, die VMs produzieren, wenn sie auf
hochausgelasteten Gluster-Systemen laufen, z.B. in einem
Hyperconverged-Setup.
Für die Ablage von VM-Disks wird Gluster in der Regel so konfiguriert, dass es „Shards“ verwendet - eine grosse VM-Disk wird so in kleinere Häppchen fixer Grösse aufgeteilt und gleichmässig auf die Gluster-Nodes repliziert und verteilt. Die Gluster-Bricks sind damit in der Lage, nur die gerade angeforderten oder sich ändernden Bereiche einer VM-Disks sequentiell zu lesen bzw. zu schreiben, was die Geschwindigkeit erhöht.
Je nachdem, welcher Anleitung man zu welchem Zeitpunkt gefolgt ist,
werden zu grosse Shards verwendet. Shards mit beispielsweise 512 MB
Grösse verringern zwar die Anzahl der zu verwaltenden Dateien im
Gluster-Volume, führen aber dazu, dass bei der kleinsten Änderung in der
VM-Disk jeweils 512 MB gelesen, geschrieben oder repliziert werden
müssen, was den Heal-Prozess verlangsamt. Das Gluster-Projekt empfiehlt,
64 MB grosse Shards einzusetzen. Die für ein Volume gesetzte
Shard-Grösse lässt sich mit
gluster volume get <volname> features.shard-block-size
abfragen.
Eine nachträgliche Änderung ist nicht möglich - dazu muss das Volume neu
aufgesetzt werden.
Wer das Gefühl hat, dass das Healing kein Ende nimmt, hält nach sich
wiederholenden UUIDs (also Zeichenktten der Form
„14fb48a6-c192-4c3f-a588-44c80cc36711“) im Gluster Self Heal Daemon Log
sowie den Brick-Logs Ausschau. Shards erhalten eine UUID;
zusammenhängende Shards werden um eine fortlaufende Nummer ergänzt. Die
Datei .shard/14fb48a6-c192-4c3f-a588-44c80cc36711.3599
ist der
3599ste Shard einer VM-Disk. Tauchen immer wieder die gleichen
Shard-UUIDs auf, dann schreibt eine VM, und Gluster kommt aufgrund von
Last, limitierter Disk- oder Netzwerkbandbreite nicht mit der
Synchronisation auf die anderen Nodes hinterher. Hier hilft es, die VMs
zu identifizieren und herunterzufahren.
Migration
Um Bricks von einem Host zum anderen zu verschieben, wird
gluster replace-brick
genutzt. Dabei werden keinerlei Daten vom
alten Brick auf den neuen Brick kopiert oder verschoben. Gluster macht
es sich viel einfacher: der alte Brick wird abgehängt, und der neue
durch den Self-heal-Daemon repariert. Es empfiehlt sich also, das
Healing sofort nach replace-brick
anzustossen. Die derzeit korrekte
Form des Kommandos lautet
gluster volume replace-brick <volname> host1:/gluster/brick/data host4:/gluster/brick/data commit force
.
Wer VMs von einer Storage-Domain auf eine andere umziehen möchte, arbeitet am besten mit den Bordmitteln seiner Virtualisierungslösung, z.B. mit der Weboberfläche der oVirt-Engine. Nach Möglichkeit sollten nur ausgeschaltete VMs migriert werden - das ist bedeutend schneller und weniger fehleranfällig, insbesondere bei Servern, die irgendeine Form von Datenbanksystem fahren. oVirt erzeugt beim Umzug eingeschalteter VMs zunächst einen Snapshot der Maschine, verschiebt die Disk, und führt am Ende die migrierte Disk und den Snapshot zusammen. Bei ausgeschalteter VM wird deren Disk dagegen einfach nur von oVirt verschoben. Das Vorgehen hat zwar überhaupt nichts mit Gluster an sich zu tun, funktioniert aber hier auch nicht besser oder schlechter als bei auf anderen Techniken basierenden Storage-Domains.
Nicht mehr verwendete, gestoppte Volumes können mit
gluster volume delete <volname>
gelöscht werden. Die Daten auf den
Bricks bleiben erhalten.
Split Brain
Gluster ist kaum aus dem Tritt zu bringen: in seinen Replikationsmodi
und mit Hilfe seiner Self-heal Daemons läuft es bewundernswert stabil.
Schlimm wird es, wenn der Aufruf von
gluster volume heal <volname> info
Meldungen in der Form
Brick host7:/gluster/brickf/data
/.shard/40643186-66de-4e2d-900a-b2bdcc762cdc.1000 - Is in split-brain
Brick host9:/gluster/arb2/data
/.shard/40643186-66de-4e2d-900a-b2bdcc762cdc.1000 - Is in split-brain
bringt. Einfachstes Beispiel für „Split Brain“ sind zwei sich replizierende Nodes, die untereinander getrennt werden, jedoch weiterlaufen und Schreibanfragen von aussen beantworten können. Werden die Nodes wieder zusammengeführt, ist die Datenintegrität verloren.
Gluster wird Split Brain-Dateien zunächst einmal nicht selbständig reparieren, hier muss der Admin ran. Falls eine VM betroffen ist, muss diese vorher heruntergefahren werden (Poweroff). Zur Lösung jedes einzelnen Split Brain-Problems gibt es drei Möglichkeiten:
Man entscheidet sich für die Datei, die zuletzt geändert wurde:
gluster volume heal <volname> split-brain latest-mtime <filename>
Man wählt die grössere der beiden Dateien aus:
gluster volume heal <volname> split-brain bigger-file <filename>
Man bestimmt aus der Menge an Bricks, die diese Datei führen, einfach einen Brick als Quelle zur Wiederherstellung:
gluster volume heal <volname> split-brain source-brick <host:brickname>
Die Dateien untersucht man auf den betroffenen Hosts mit
stat <filename>
, um eine Entscheidungsgrundlage zu haben.
Wer dagegen weiss, dass es beispielsweise immer auf die neueste Datei
ankommt, kann Gluster auch zur automatischen Korrektur von Split Brains
bewegen. Standardmässig steht die Einstellung
cluster.favorite-child-policy
auf none
, lässt sich aber analog
zur obigen Aufzählung auf mtime
, ctime
oder size
setzen. Die
Policy majority
verwendet die Dateiversion als Quelle, die mit
identischer mtime
und size
auf mehr als der Hälfte aller Bricks
vorkommt.
Bemerkung
Die hilfreichsten Gluster-Logfiles
Gluster Daemon:
/var/log/gluster/glusterd.log
Gluster Self-heal Daemon:
/var/log/gluster/glustershd.log
Gluster Bricks:
/var/log/glusterfs/bricks/gluster-<brickname>-<volname>.log
Monitoring
Gluster bietet wesentlich mehr als die klassische Logfile-Überwachung.
Mit dem gluster
-Befehl kann man sich unter anderem
Statusinformationen zu Volumes, Bricks oder Self-heal Daemons anzeigen
lassen oder Volumes debuggen. gluster
kann unter anderem folgende
Fragen beantworten:
Welche Volumes gibt es?
gluster volume list
Sind die Bricks der Volumes online, laufen die Self-heal Daemons?
gluster volume status all
Wie steht es um den Plattenplatz der Bricks, freie Inodes usw.?
for volname in gluster volume list; do gluster volume status $volname detail; done
Wer greift auf das Volume zu?
gluster volume status <volname> clients
Wie fällt der Memory-Verbrauch der Bricks aus?
gluster volume status <volname> mem
Bemerkung
Netzwerk-Ports auf einem Gluster-Node mit vier aktiven Bricks
Address:Port Peer Address:Port
*:24007 users:(("glusterd",pid=9518,fd=10))
*:49152 users:(("glusterfsd",pid=10063,fd=11))
*:49153 users:(("glusterfsd",pid=10069,fd=11))
*:49154 users:(("glusterfsd",pid=10081,fd=11))
*:49155 users:(("glusterfsd",pid=10087,fd=11))
Fazit
So einfach sich Gluster installieren lässt, bedarf es - wie jedes andere Storage-System auch - eine für den Einsatzzweck ausgelegte Konfiguration sowie laufende Überwachung. Zudem sollte man einige Stolpersteine kennen und in Teilen wissen, wie Gluster unter der Haube arbeitet. Geplante Arbeiten sowie Troubleshooting lassen sich an kleinen virtuellen Testsystemen üben. Das wichtigste im Ernstfall ist aber, auch unter Druck Ruhe zu bewahren und besonnen die nächsten Schritte durchzuführen.