ADMIN

2022

07

2022-06-29T12:00:00

Mobiles Arbeiten

PRAXIS

040

Storage

Ceph

Storage mit Ceph (2)

Fotografisches Gedächtnis

von Andreas Stolzenberger

Veröffentlicht in Ausgabe 07/2022 - PRAXIS

Dank Werkzeugen wie "cephadm", dem neuen Dashboard und dem Betrieb der Dienste in Containern hat Ceph viel an Komplexität verloren. Im ersten Teil unserer Workshopserie haben wir uns die Grundlagen von Ceph, das Clustering und CephFS angesehen. Im zweiten und abschließenden Teil machen wir uns an die Installation der Umgebung sowie die Sicherung mittels Snapshots.

Ursprünglich wollten wir für diesen Workshop die nagelneue Version 17 von Ceph verwenden. Die wurde jedoch leider nicht mehr vor dem Redaktionsschluss fertig, weswegen die beschriebene Testumgebung auf dem Release "Pacific" in der Version 16.2.7 auf Fedora 35 arbeitet. Für funktionale Tests mit Ceph genügt bereits ein Single-Node-Setup. Die hier beschriebene Testumgebung setzt zwei Knoten ein – eigentlich nur um einige der verteilten Funktionen und Aufgaben vorzustellen. Der erste Knoten arbeitet als VM ohne Datenplatten, am zweiten Knoten hängen drei 500-GByte-Festplatten als OSDs. Auf dem ersten Knoten installieren Sie die benötigten Abhängigkeiten wie Podman und die Ceph-Tools:
dnf install catatonit podman ceph-common cephadm ceph-base
Bei "catatonit" handelt es sich um einen simplen Init-Dienst für Container. Dessen seltsamer Name erklärt sich aus seiner Beschreibung: "A container init that is so simple it's effectively brain-dead".
Jetzt geht es daran, den neuen Cluster zu initialisieren. Bei Ceph so wie bei allen anderen IP-basierten Speicherdiensten sollten Sie für die Konfiguration immer IP-Adressen und keine Domainnamen verwenden. Anderenfalls könnte ein simples Problem mit der DNS-Auflösung zum Ausfall des Speichersystems führen. Setzen Sie bei Ceph-Knoten als "hostname" immer den kurzen Namen ohne Domain ein, das macht das Setup übersichtlicher. Ceph benennt seine Dienste nach dem Hostnamen und da klingt "mds1.node1.123456" einfach besser als "md1.node1.ceph.abteilung.gebaeude.firma.netzwerk.123456".
Ursprünglich wollten wir für diesen Workshop die nagelneue Version 17 von Ceph verwenden. Die wurde jedoch leider nicht mehr vor dem Redaktionsschluss fertig, weswegen die beschriebene Testumgebung auf dem Release "Pacific" in der Version 16.2.7 auf Fedora 35 arbeitet. Für funktionale Tests mit Ceph genügt bereits ein Single-Node-Setup. Die hier beschriebene Testumgebung setzt zwei Knoten ein – eigentlich nur um einige der verteilten Funktionen und Aufgaben vorzustellen. Der erste Knoten arbeitet als VM ohne Datenplatten, am zweiten Knoten hängen drei 500-GByte-Festplatten als OSDs. Auf dem ersten Knoten installieren Sie die benötigten Abhängigkeiten wie Podman und die Ceph-Tools:
dnf install catatonit podman ceph-common cephadm ceph-base
Bei "catatonit" handelt es sich um einen simplen Init-Dienst für Container. Dessen seltsamer Name erklärt sich aus seiner Beschreibung: "A container init that is so simple it's effectively brain-dead".
Jetzt geht es daran, den neuen Cluster zu initialisieren. Bei Ceph so wie bei allen anderen IP-basierten Speicherdiensten sollten Sie für die Konfiguration immer IP-Adressen und keine Domainnamen verwenden. Anderenfalls könnte ein simples Problem mit der DNS-Auflösung zum Ausfall des Speichersystems führen. Setzen Sie bei Ceph-Knoten als "hostname" immer den kurzen Namen ohne Domain ein, das macht das Setup übersichtlicher. Ceph benennt seine Dienste nach dem Hostnamen und da klingt "mds1.node1.123456" einfach besser als "md1.node1.ceph.abteilung.gebaeude.firma.netzwerk.123456".
Für das simple Testsetup arbeiten wir mit nur einem Netzwerk. Größere Setups setzen ein separates Cluster-Netzwerk ein, um den Ceph-internen Traffic zu isolieren. Das Setup des Manager-Knotens erfolgt mit:
cephadm bootstrap --mon-ip <IP-Adresse des Manager Knotens>
Dieses Kommando erzeugt eine simple Basis-Ceph-Konfiguration, einen admin-Schlüssel und rollt eine Reihe von Containern aus. Darunter befindet sich auch gleich die Ceph-GUI sowie ein Gespann aus Grafana und Prometheus, das die Metriken des Clusters sammelt und darstellt. Am Ende des Setupprozesses gibt cephadm das temporäre Admin-Passwort für die UI aus. Diese erreichen Sie dann unter "https://<IP des Manager Knotens>:8443". Da Ceph mit einem selbstsignierten Zertifikat arbeitet, müssen Sie die Zertifikate der Admin-UI und von Grafana (auf https://<IP des Manager-Knotens>:3000) separat akzeptieren, damit die in die UI eingebeteten Grafana-Charts angezeigt werden.
Neben der UI können Sie auch die CLI-Kommandos wie "ceph", "cephadm" oder "rbd" für die Konfiguration nutzen. Um den Cluster aus der Ferne von einem angebundenen Linux-Server aus managen zu können, installieren sie dort einfach das ceph-common-Paket und kopieren den Inhalt des "/etc/ceph"-Verzeichnisses vom ersten Ceph-Knoten auf den angebundenen Linux-Server.
Dabei ist jedoch Vorsicht geboten, denn Sie kopieren die Admin-Credentials im "ceph.client.admin.keyring" auf das angebundene System, das dann volle Admin-Rechte erhält. Für Testzweche ist das in Ordnung und so auch gewünscht. Bei einer produktiven Installation müssen Sie natürlich mit ceph auth Schlüsseldateien mit eingeschränkten Rechten für die angebundenen Rechner erstellen (siehe Kasten "Authentifizierung").
Noch fehlt es dem Storage-System jedoch an Storage. Dafür fügen wir in unserem Setup den zweiten Knoten mit drei Platten hinzu. Zuerst müssen Sie dem ersten Knoten Admin-Rechte auf dem zweiten Knoten gewähren. Dann kann der Manager-Container des ersten Knotens die Installation einleiten. Der zweite Knoten benötigt lediglich eine Podman- oder Docker- Runtime und den catatonit-Dienst. Gewähren Sie dem ersten Knoten Admin-Rechte auf dem zweiten Knoten über den zuvor erstellten SSH-Schlüssel:
ssh-copy-id -f -i /etc/ceph/ceph.pub root@<IP-Adresse von Node2>
Und fügen Sie dann den Knoten dem Cluster hinzu:
ceph orch host add node2 <IP-Adresse des zweiten Nodes>
Jetzt verbindet sich der Manager-Dienst mit dem zweiten Knoten und rollt dort die benötigten Container aus. Darunter ist auch gleich ein zweiter Mon-Dienst. Falls erwünscht, können Sie den zweiten Knoten als "Admin"-Knoten kennzeichnen:
ceph orch host label add node2 _admin
Ein als "_admin" markierter Node erhält Kopien der Konfiguration und der Schlüssel, sodass der Administrator diese nicht bei einem Totalausfall des ersten Knotens verliert. Nun fehlen noch OSDs. Die können Sie nun händisch einpflegen oder automatisch aufspüren lassen. Dazu starten Sie den Scanner-Task:
ceph orch apply osd --all-available-devices
Die automatische OSD-Detection funktioniert jedoch nur mit leeren Platten. Erkennt Ceph auf den zusätzlichen Disks Dateisysteme oder Partitionen, wird es die Platten nicht mit Bluestor formatieren und in den Cluster aufnehmen. Sollte Ceph Platten als belegt ablehnen, können Sie diese über das "Zap"-Kommando löschen
ceph orch device zap <Node> <Disk-Pfad>
und dann händisch in den Cluster übernehmen:
ceph orch daemon add osd <Node>:<Disk-Pfad>
Bild 1: Das Dashboard listet alle erstellten CephFS-Snapshots auf.
Nach einer Weile tauchen die initialisierten OSDs in der UI auf. Die Health des Clusters bleibt jedoch auf "Warning", da es nur einen Host mit OSDs gibt und daher die Verteilung auf mehrere Knoten scheitert. Für Single-Node-Setups zu Testzwecken gibt es jedoch einen Ausweg. Die Crush-Map des Clusters lässt sich ändern, sodass sie keine Datenverteilung über mehrere Hosts, sondern nur über mehrere OSDs erzwingt. Dazu extrahieren Sie die Crush-Map aus dem Cluster:
ceph osd getcrushmap -o comp_crush_map.cm
Da Ceph die Map in einem binären Format sichert, müssen sie diese zunächst dekompilieren mit
crushtool -d comp_crush_map.cm -o crush_map.cm
Die resultierende Datei "crush_map.cm" lässt sich mit einem Texteditor anpassen. In der Datei finden Sie das Regelwerk für die Blockreplikation im Abschnitt "rule replicated_rule". Dort ändern Sie den Eintrag
step chooseleaf firstn 0 type host
auf
step chooseleaf firstn 0 type osd
und sichern Sie die Datei. Anschließend kompilieren Sie die Map zurück in das Binärformat und übergeben Sie dem Cluster mit
crushtool -c crush_map.cm -o new_crush_map.cm
ceph osd setcrushmap -i new_crush_map.cm
Kurz nachdem Sie die neue Map in Stellung gebracht haben, ändert Ceph den Status im Dashboard von "Warn" auf "OK". Bitte denken Sie daran, dass ein so modifizierter Single-Node-Cluster nur Schutz vor einzelnen Plattenausfällen, nicht aber vor dem Ausfall des ganzen Knotens bietet. Sollten Sie das Testsetup später einmal mit zusäzlichen OSD-Knoten erweitern, stellen Sie die Crush-Map einfach zurück auf "type Host" und der Cluster wird sofort die PGs neu verteilen.
Disks via RBD bereitstellen
Um SAN-Disks via RBD bereitzustellen, benötigen Sie zuerst einmal einen Pool. Den legt Ceph wie folgt an:
ceph osd pool create rbd
"rbd" steht hier für den Namen des Pools. Ohne weitere Angaben erstellt Ceph einen "replicated" Pool mit drei Kopien. Für Testumgebungen genügen jedoch zwei Kopien, daher können Sie die Size entsprechend anpassen:
osd osd pool set rbd size 2
Um den Pool für rbds nutzen zu können, initialisieren Sie ihn:
rbd pool init rbd
Alle hier aufgeführten Kommandos führen Sie wahlweise auf einem der Ceph-Knoten oder einem angebundenen Linux-Host aus. Letzterer muss dann im Besitz des "ceph.client.admin.keyring" im Verzeichnis "/etc/ceph" sein. Ist der Pool initialisiert, erstellen Sie ein Image, das dann als SAN-Lun fungiert:
rbd create lun0 –size 20G
Auf einem angebundenen Linux-Client-System mit einem passenden Key (in unserem Testsetup genügt der Admin-Key) führen Sie folgendes Kommando aus: rbd map lun0. Jetzt taucht das Blockdevice als Festplatte unter "/dev/rbd0" auf. Sie können es wie jedes andere SAN-Device dann mit einem lokalen Dateisystem wie XFS oder BTRFS formatieren und verwenden.
Soll die LUN gleich nach dem Startvorgang des Client zur Verfügung stehen, müssen sie zwei Dateien anpassen. Unter "/etc/ceph" findet sich die "rbdmap". Die enthält eine Liste aller RBDs, die der Ceph-Client beim Systemstart einbindet. Für unser Beispiel tragen Sie dort Folgendes ein:
rbd/lun0 id=admin,keyring=/etc/ceph/ceph.client.admin.keyring
Zudem brauchen Sie den passenden Eintrag in der "fstab", in diesem Beispiel für ein XFS-Dateisystem:
/dev/rbd/rbd/lun0 /mountpoint xfs _netdev,defaults 0 0
Die Syntax der Devicemap ist wie folgt: /dev/rbd/<poolname>/<imagename>.
Authentifizierung
Ceph regelt Zugriffe mit einer eigenen User/Key-Authentifizierung, die das System auch intern für alle Dienste verwendet.Die existierenden Nutzerkonten listet das Kommandoceph auth lsauf. Um einen neuen User zu erstellen, geben Sie beispielsweise folgendes Kommando einceph auth create client.user1Damit bekommt der neue User erst einmal einen Key, aber noch keine Zugriffsrechte. Diese "capabilities" erhält de Nutzer je nach Dienst und Objekt. Wichtig ist in jedem Fall, dass Nutzer zumindest lesend auf alle Mons zugreifen dürfen:ceph auth caps client.user1 mon 'allow r'Die Rechte lassen sich dann für Dienste und Objekte erweitern:ceph fs authorize fs1 client.user1 /r /home/user1 rwDieses Kommando erlaubt dem "client.user1" lesend auf das Ceph-FS-Dateisystem fs1 zuzugreifen, wobei User1 im Verzeichnis "/home/user1" dann auch über Schreibrechte verfügt. Ähnliche Regelwerke lassen sich auch für den gezielten Zugriff auf bestimmte Pools und RBDs einrichten. Die Autorisierung gilt jedoch nur für native Ceph-Protokolle. Dienste wie beispielsweise das RADOS-Gateway (S3) verwalten eigene Benutzerkonten und Schlüssel.
Sicherung über Snapshots
Das RBD unterstützt Snapshots. Wie auch bei anderen Speichersystemen sind diese natürlich wertlos, wenn sie von einem Dateisystem mit aktuell zum Schreiben geöffneten Dateien gemacht werden. Wenn Sie einen Snapshot erstellen möchten, bauen Sie zuerst ein passendes Skript, das den auf dem Volume laufenden Dienst herunterfährt, das Dateisystem synchronisert und dann den Snapshot erzeugt. Im Beispiel betreiben wir einen MySQL-Datenbankserver auf einem RBD. Das trägt den Namen "mysql1" und wird auf "/var/ lib/mysql" gemounted:
#!/bin/bash
dt=$(date '+%Y%m%d_%H%M')
systemctl stop mariadb
sync /var/lib/mysql
rbd snap create
systemctl start mariadb
Sollte nun etwas mit der Datenbank schiefgehen, könnten Sie zum einen das Block-Device auf eine frühere Version zurücksetzen mit rbd snap rollback. In der Praxis gehen viele jedoch einen anderen Weg: Sie erstellen aus dem Snapshot ein eigenständiges Volume, mounten das an anderer Stelle und kopieren von der früheren Version die benötigten Daten. Unter Ceph müssen Sie dazu den betreffenden Snapshot "schützen" und dann in ein eigenständiges Image klonen:
rbd snap protect rbd/mysql1@snapshot-20220325_1404
rbd clone rbd/mysql1@snapshot-20220325_1404 rbd/mysql1_clone
Snapshots und Klone arbeiten dabei als "linked"-Images. Nur die Blöcke, in denen der Klon vom Original abweicht, werden tatsächlich separat gespeichert. Alle identischen Blöcke verweisen auf die Original-LUN. Wer einen Klon als eigenständiges Image ohne Links erhalten will, kann es mit dem Kommando rbd flatten umwandeln.
Ceph-Filesystem
Neben der Kommandozeile können Sie Ceph auch recht komfortabel über die Admin-GUI bedienen. Im Folgenden richten Sie ein Ceph-Dateisystem via UI ein. Dazu benötigen Sie zunächst einen Metadaten-Dienst. Expandieren Sie den Tab "Cluster", wechseln nach "Services" und klicken auf "+ Create". Wählen Sie im folgenden Dialog den Typ "mds", geben ihrem Dienst via "id" einen Namen – im Beispiel ist das einfach "eins". Als Placement wählen Sie "Hosts" und den Count setzen Sie auf "1". In der Auswahl "Hosts" wählen Sie alle Ceph-Knoten aus, die den MDS-Service betreiben sollen. In der Praxis sollte das natürlich redundant arbeiten, für den Test genügt auch ein einzelner MDS auf einem einzelnen Host. Auf diese Art und Weise können Sie in Ihrem Test-Cluster auch weitere Dienste, wie beispielsweise ein iSCSI-Target für den rbd-Dienst einrichten.
Erstellen Sie zwei Pools: einen für das Dateisystem selbst und einen anderen für die Metadaten. Das kann ebenfalls über die Kommandozeile oder UI erfolgen. In der UI wechseln Sie auf "Pools" und wählen "+ Create". Geben Sie dem Pool einen Namen, wie beispielsweise "fs1.data" oder "fs1.meta", setzen Sie den Pool-Type auf "replicated" und wählen Sie als Application "cephfs" aus. Dem Dateisystem-Tab der UI fehlt leider der "+ create"-Button, weswegen Sie das Dateisystem einfach auf der CLI erstellen:
ceph fs new fs1 fs1.data fs1.meta
Schon läuft das Dateisystem. Den Zugriff zum CephFS regelt die User-Authentifizierung (siehe Kasten "Authentifizierung"). Für unser Beispiel bleiben wir wiederum einfach beim Admin-Account. Wenn Sie die Datei "ceph.client.admin. keyring" im Editor öffnen, sehen Sie in der ersten Zeile "[client.admin]" und in der zweiten Zeile den Schlüssel "key = xxxxxx". Möchten Sie Ihr CephFS nun auf einem Linux-System mounten, brauchen Sie dort zunächst das "ceph-common"-Paket mit den nötigen Treibern und Binaries. Dann können Sie CephFS im Kernel Mode einfach einbinden:
mount -o name=admin,secret=<key> -t ceph <mon ip>:/ /mountpoint
Wer den Fuse-Client aus Kompatibilitätsgründen anstatt des Kernel-Mode nutzen will, installiert zunächst das Paket "ceph-fuse" und bindet das Dateisystem dann wie folgt ein:
ceph-fuse --client_fs fs1 --id admin -k /etc/ceph/ceph.client. admin.keyring /mountpoint
CephFS unterstützt Dateisystem-Snap-shots auf Verzeichnisebene. Diese können Sie zum einen via GUI oder ganz simpel im Verzeichnis selbst mit Dateisystemtools erstellen. Zuerst müssen Sie neue Snapshots im Dateisystem erlauben:
ceph fs set fs1 allow_new_snaps true
Dann wechseln Sie auf der Kommandozeile in das Verzeichnis, von dem Sie einen Snapshot erzeugen möchten. Dort führen Sie einfach folgenden Befehl aus:
mkdir .snap/<snapshotname>
Ändern Sie nun Dateien im regulären FS, behält der Snapshot die vorhergehenden Versionen. Um auf diese zuzugreifen, welchseln Sie einfach in das Verzeichnis ".snap/snapshotname". Wenn Sie den Snapshot nicht mehr benötigen, entfernen Sie das Verzeichnis.
Bild 2: Ein S3-Browser wie "CloudBerry" gewährt dem Nutzer Zugriff zum RGW und den Buckets.
S3-kompatibles Gateway einrichten
Zu guter Letzt richten Sie noch ein S3-kompatibles Gateway ein. Das geht sehr einfach über die UI, wiederum über den Reiter "Services" und den "+ Create"-Button. Erstellen Sie, ähnlich wie beim MDS-Setup einen neuen Dienst vom Typ "rgw" mit Count "1" und einem oder beiden Nodes. Nutzen Sie für das Testsetup einen freien Port. Für unser Beispiel wählen wir einfach Port 8765 ohne SSL.
Beim ersten RGW erzeugt Ceph automatisch die benötigten Pools als "default.rgw. <typ>". Das Rados-Gateway braucht gleich fünf Pools: "control", "log", "meta index" und "data". Sie können die Pools und das Gateway auch händisch auf der CLI erstellen. Im Zusammenhang mit dem RGW dürfen Sie dann auch einen Erasure-Coded-Pool für "xx.rgw.data" nutzen. Kurz nachdem Sie das RGW angelegt haben, taucht es in der UI unter "Objec Gateway Daemons" auf. Im Tab "Users" legen Sie nun einen oder mehrere User-Accounts an. Das RGW wird für die Nutzer auf Wunsch automatisch einen Access- und einen Secret-Key erstellen. Schließlich legen Sie einen Bucket an und weisen ihn einem User und dem Pool zu. Jetzt können Sie über das S3-Protokoll via Gateway auf den Bucket zugreifen. In der Praxis verteilen Sie dabei natürlich mehrere Gateways und gruppieren diese hinter einem Loadbalancer.
Fazit
Ceph ist zwar ein umfassender, aber dafür auch komplexer Storage. Cephadm und die Verteilung auf Container macht es dem Administrator aber deutlich einfacher, einen Cluster aufzusetzen und erste Erfahrungen mit einem simplen Setup zu sammeln. Auch sind die ersten Schritte in Richtung Windows-Anbindung getan, aber in erster Linie dient Ceph als Speicher für Linux-Serverfarmen.
(dr)