Seit vielen Jahren haben wir Ceph im Einsatz. Unser erstes produktives Cluster begleitet uns seit 2015. Auch wenn die ersten Major-Updates des Clusters holprig verliefen ist die nötige Pflege des Clusters mit jedem Release von Ceph geringer geworden. Abgesehen vom Einspielen der Updates oder dem Tauschen von kaputten Festplatten ist wenig am Ceph Cluster zu tun, umso unerwarteter traf uns ein Fehler in der Replikation der Snapshots. Die Lösung des Problems hat sich über eine längere Zeit gezogen und mit diesem Blogpost hoffe ich anderen Ceph-Administratoren schneller auf den richtigen Weg zu verhelfen. Aber zuerst eine kleine Begriffserklärung.
Wie werden Daten im Ceph gespeichert?
Speichert man Daten (z.B. Objekt O) in ein Ceph Cluster wird dieses einer Placementgruppe (PG 1.1) zugeordnet. PG 1.1 besteht aus drei Festplatten (wir nennen diese OSDs) und das Objekt O wird auf alle drei OSDs (osd.1, osd.2, osd.3) gespeichert.
Fällt nun osd.3 aus, wird eine andere Festplatte (osd.4) zu der PG 1.1 zugeordnet und Daten werden von osd.1 auf osd.4 kopiert. Dieser Prozess heißt backfilling. Die Verfügbarkeit und die Integrität der Daten ist währenddessen nie gefährdet und der Ausfall von osd.3 ist schnell wieder behoben. Die Bereitschaft wird nicht geweckt und die kaputte Festplatte wird zu normalen Betriebszeiten ersetzt.
Was ist schief gelaufen?
Beim backfilling einer PG kam es zu einem ceph_assert(clone_overlap.count(clone)) mit dem sich die OSDs der Placementgruppen selbst stoppen. In Kombination mit systemd wurden die OSDs mehrfach neu gestartet (bis zum erreichen der StartLimitsBurst) und sind immer wieder in den assert gelaufen wodurch wir folgende Ausgangslage vorfanden:
- PG 1.1 hatte nur noch osd.1 mit vollständigen aktuellen Daten
- osd.2 und osd.4 konnten auf Grund des Bugs nicht mit den aktuellen Daten versorgt werden (backfilling)
- Tools zum debuggen des Problems lieferten keine Informationen
- deep-scrub (und damit auch repair) haben den gleichen Bug ausgelöst
Wie das Cluster genau in den Zustand kam ist uns unklar. Wir vermuten eine Kombination aus einer kaputter Festplatte, durch den Bug verursachten Crashes der OSDs und dem gleichzeitigen erstellen und löschen von Snapshots.
Was bedeutet das für die Datenintegrität und Verfügbarkeit?
- osd.1 hat alle aktuellen Objekte und ist voll funktionsfähig
- ein Ausfall von osd.1 führt zu Datenverlust
- ein temporärer Ausfall bzw. Neustart von osd.1 führt zur nicht Verfügbarkeit der Objekte in PG 1.1 (down)
- eine automatische Replikation der Daten ist nicht möglich
- Snapshots auf PG 1.1 werden nicht gelöscht und häufen sich an
- Scrubbing für PG 1.1 wird nicht durchgeführt
Lösung
Lösungsansätze waren dort auch zu finden, welche teilweise positiv aber auch negativ bestätigt wurden. Einige Betroffene konnten das Problem nur mit dem löschen der PG lösen, was mit Datenverlust einhergeht und natürlich zu vermeiden ist. In unserem Fall hatten wir die aktuelle Daten verfügbar und ein weiteres unabhängiges Ceph Cluster welches im Disasterfall ein maximal 24 Stunden altes Backup bereitstellt.
1. Verfügbarkeit des PG 1.1 gewährleisten
Damit der letzte verbleibende osd.1 nicht regelmäßig auf den Bug trifft und sich neu startet haben wir das backfilling verhindert (ceph daemon osd. config set osd_max_backfills 0). Damit ist osd.1 und damit PG 1.1 dauerhaft verfügbar und für alle Clients wie gewohnt nutzbar. Hiermit wird aber auch das backfilling für alle anderen PGs auf osd.0 verhindert.
2. Wiederherstellung der Replikation
Zur manuelle wiederherstellen der Replikation gibt es die Möglichkeit Placementgruppen aus einem gestoppten OSD zu exportieren und in andere OSDs wieder zu importieren. Man führt das backfilling sozusagen manuell aus. Hierbei spielt es eigentlich auch keine Rolle auf welchen OSD die PG eingespielt wird. Ceph erkennt selbstständig die PG (pg[…] transitioning to Stray) und kopiert die Daten selbstständig zum richtigen OSD. Je nach Situation kann es auch nötig sein die PG von allen OSDs zu entfernen. ceph pg 1.1 query liefert hier genauere Information zu den OSDs mit Objekten aus der PG.
Für die Prozedur benötigt man drei Befehle:
ceph-objectstore-tool --data-path /var/lib/ceph/osd/ceph-1 --no-mon-config --pgid 1.1 --op export --file /tmp/pg-1.1.export ceph-objectstore-tool --data-path /var/lib/ceph/osd/ceph-2 --no-mon-config --op import --file /tmp/pg-1.1.export
Die OSDs müssen dazu gestoppt sein und sollte die PG schon vorher auf dem OSD vorhanden sein muss diese zuerst gelöscht werden:
ceph-objectstore-tool --data-path /var/lib/ceph/osd/ceph-2 --pgid 1.1 --op remove --force
Wer noch Filestore OSDs betreibt muss den Befehl um --type filestore --journal-path /var/lib/ceph/osd/ceph-1/journal
erweitern.
Mit Filestore sollten auch owner und group kontrolliert werden. Im Beispiel muss /var/lib/ceph/osd/ceph-2/current/omap und /var/lib/ceph/osd/ceph-2/current/1.1_head und mit chwon -R ceph:ceph wieder angepasst werden.
Durch diese Maßnahme konnten wir osd.2 und osd.4 wieder auf den aktuellen Stand bringen was folgende Verbesserungen bringt:
- alte Snapshots auf PG 1.1 werden wieder gelöscht
- backfilling kann wieder aktiviert werden, wovon alle anderen PGs auf osd.1 profitieren
- scrubbing und repair funktioniert wieder
Im Vergleich zum Anfang ist das Cluster wieder in einem guten Zustand. Alle Objekte werden wieder repliziert, die Verfügbarkeit und Integrität der Daten ist gewährleistet und PG 1.1 häuft nicht weiterhin alte Snapshots an. Allerdings sind die ursprünglichen Probleme noch nicht gelöst, da wir nur eine exakte Kopie der Daten an anderen Stellen eingespielt haben. Sollte ein backfilling für PG 1.1 nötig sein würde das Problem weiterhin auftreten.
3. Erkennen und löschen der fehlerhaften Clones
rados list-inconsistent-snapset 1.1 –format=json-pretty zeigt gefundene Fehler, Inkonsistenzen und die dazugehörigen Metadaten wie Objektnamen, SnapIDs (dezimal) und Fehlerbeschreibungen. Wir mussten hier die Fehler clone_missing und extra_clones manuell beheben. Weiter Fehler wie z.B. mismatch kann Ceph selbst im repair beheben.
rbd_data.dad3d1238e1f28.00000000000062d5:107BE
rbd_data.dad3d1238e1f28 ist der block name prefix. 0000000000062d5 der Objektname. 107BE die SnapID (wird manchmal auch als Dezimalzahlen angezeigt).Sind die Objekte identifiziert zeigt einem das ceph-objectstore-tool die nötigen Details um die Fehler zu beheben.
ceph-objectstore-tool --data-path /var/lib/ceph/osd/ceph-1 --op list rbd_data.dad3d1238e1f28.00000000000062d5 ["1.1",{"oid":"rbd_data.dad3d1238e1f28.00000000000062d5","key":"","snapid":2225964,"hash":2449849216,"max":0,"pool":1,"namespace":"","max":0}] ["1.1",{"oid":"rbd_data.dad3d1238e1f28.00000000000062d5","key":"","snapid":2226131,"hash":2449849216,"max":0,"pool":1,"namespace":"","max":0}] ["1.1",{"oid":"rbd_data.dad3d1238e1f28.00000000000062d5","key":"","snapid":2224480,"hash":2449849216,"max":0,"pool":1,"namespace":"","max":0}] ["1.1",{"oid":"rbd_data.dad3d1238e1f28.00000000000062d5","key":"","snapid":-2,"hash":2449849216,"max":0,"pool":1,"namespace":"","max":0}]
Jede Zeile beschreibt einen Clone oder das Objekt selbst und wird als Parameter zum bereinigen der Fehler gebraucht.
Bereinigen von clone_missing
Im Fall von clone_missing kann man Metadaten eines Clones manuell vom Objekt entfernen. Hierfür wird remove-clone-metadata verwendet. Das Objekt des Snapshots wurde bereits entfernt.
ceph-objectstore-tool --pgid <pgid> '<Objektzeile>' remove-clone-metadata <snapid-decimal> ceph-objectstore-tool --data-path /var/lib/ceph/osd/ceph-1 --pgid 1.1 '["1.1",{"oid":"rbd_data.dad3d1238e1f28.00000000000062d5","key":"","snapid":-2,"hash":2449849216,"max":0,"pool":1,"namespace":"","max":0}]' remove-clone-metadata 2225750
Bereinigen von extra_clones
Bei extra_clones handelt es sich um Clones welche im Filesystem noch zu finden sind, aber eigentlich schon gelöscht sein sollten. Man findet diese auch direkt im Filesystem. Diese kann man mit dem ceph-objectstore-tool entfernen:
ceph-objectstore-tool 'Snapshotzeile' remove ceph-objectstore-tool --data-path /var/lib/ceph/osd/ceph-1 '["1.1",{"oid":"rbd_data.dad3d1238e1f28.00000000000062d5","key":"","snapid":2224480,"hash":2449849216,"max":0,"pool":1,"namespace":"","max":0}]' remove
Résumé
Das Bereinigen der Inkonsitenzen im Snapshot war der letzte Schritt zum wiederherstellen des Clusters. Diese Lösung zu finden hat mehrere Tage gedauert unter anderem auch weil wir natürlich das Löschen und wieder einspielen der PlacementGroup in einem anderen Cluster ausführlich getestet haben.
Brauchst Du Hilfe bei mit deinem Ceph Cluster? Schreibe uns gerne eine Nachricht oder melde Für mehr Inhalte zu dem Thema abonniere unser Newsletter.

0 Kommentare