IT security, FreeBSD, Linux, mail server hardening, post-quantum crypto, DNS, retro computing & hands-on hardware hacks. Privater Tech-Blog seit 2003.

Schlagwort: Storage (Seite 1 von 2)

Tiered Storage live: Wie ein ZFS special vdev den HDD-Flaschenhals an der Wurzel packt

Ein einzelner ZFS-Pool aus zwei 7200-rpm-Platten war durch Metadaten-Random-I/O ausgebremst. Lösung ganz ohne Neuaufbau: die vorhandenen SSDs zu einem gespiegelten special vdev für Metadaten plus gespiegeltem SLOG umgebaut, zwei zpool add-Befehle im laufenden Betrieb. Resultat: Metadaten-Leselatenz von rund 46 ms auf rund 455 µs, also etwa Faktor hundert, bei voll erhaltener Verschlüsselung und Redundanz.

Drehende Platten sind ein ehrliches Stück Technik. Sie speichern viele Terabyte für wenig Geld und liefern bei sequenziellem Zugriff ordentlichen Durchsatz. Ihre Achillesferse ist der zufällige Zugriff auf viele kleine Blöcke, denn jede Kopfbewegung kostet Latenz im zweistelligen Millisekundenbereich aus Seek und Rotationswartezeit. Und genau dieses ungünstigste Muster produziert ein Copy-on-Write-Dateisystem wie ZFS am laufenden Band: Metadaten. Verzeichnis-ZAPs, dnodes, indirekte Blöcke, also die Block-Pointer-Bäume, dazu Spacemaps. Jedes ls, jedes stat, jeder Snapshot-Vergleich, jeder Scrub und jede find-Traversierung wühlt sich durch viele kleine, über die ganze Platte verstreute Metadatenblöcke. Auf einer HDD ist das der teuerste Spaß, den man haben kann.

Symbolische Darstellung eines ZFS-HDD-Mirrors mit SSD-special-vdev: Metadaten-I/O wird von Festplatten auf schnelle SSDs ausgelagert.

Ich hatte genau diesen Schmerz auf einem dedizierten Server: ein bewusst simpel gehaltener ZFS-Pool, zwei Enterprise-SATA-Platten im Mirror als Kapazitätsspeicher, und ein nagender Verdacht, dass die Spindeln der Flaschenhals sind. Die spannende Frage war nicht, ob man das beheben kann, sondern wie elegant. Die Antwort heißt allocation classes, konkret ein special vdev. Und das Schöne daran: Der Umbau lief komplett im laufenden Betrieb, ohne den Pool neu aufzubauen, ohne Downtime, mit zwei Befehlen. Dieser Beitrag zeigt den ganzen Weg, inklusive der Baseline-Messung, die den Engpass erst beweist, eines Verschlüsselungs-Stolpersteins beim Umbau und der ehrlichen Frage, was so ein special vdev wirklich bringt.

Die Ausgangslage

Der Server läuft auf FreeBSD 15.1-RELEASE (amd64, 12 CPU-Threads, 64 GiB RAM). Ein einziger ZFS-Pool, 2023 ganz bewusst als schlichter Mirror angelegt:

zpool create -o altroot=/mnt -O compress=lz4 -O atime=off -m none -f zroot mirror ada0p3 ada1p3
  • Das Daten-vdev sind zwei 7200-rpm-Enterprise-SATA-Platten mit je 2 TB als Mirror (mirror-0, rund 1,8 TiB nutzbar), der eigentliche Kapazitätsspeicher.
  • Dazu zwei Datacenter-SATA-SSDs mit je 240 GB und Power-Loss-Protection. Die waren vorher suboptimal genutzt: eine als einzelner, nicht gespiegelter SLOG, die andere als L2ARC.
  • ARC-Limit anfangs 16 GiB, poolweit compression=lz4 und atime=off von Anfang an.
  • ashift=12 erzwungen über vfs.zfs.vdev.min_auto_ashift=12, also 4K-Sektor-Alignment, korrekt auch dann, wenn die Platten brav 512-Byte-Sektoren melden.

Die Power-Loss-Protection der SSDs ist kein Detail am Rande, sondern später für die SLOG-Sicherheit relevant: Eine SSD ohne Pufferschutz darf bei einem synchronen Write nicht behaupten, die Daten lägen sicher, solange sie noch im flüchtigen Cache stehen. Datacenter-SSDs mit Kondensator-gestütztem Cache dürfen das, und genau das braucht ein SLOG.

Erst messen, dann bauen

Bevor ich auch nur eine Partition angefasst habe, kam die wichtigste Phase: messen. Ohne Baseline kauft man Hardware nach Bauchgefühl und tunt am falschen Ende. Also lief ein eigener, delta-basierter Sampler über 30 Minuten, 90 Samples zu je 20 Sekunden. Er liest sysctl-Counter für CPU, ARC und Netz sowie iostat -x für die Platten-Busy und die Latenzen. Die wichtigste Spalte zur Einordnung der Last ist net-out, also der ausgehende Netzdurchsatz als Proxy dafür, was während des Laufs tatsächlich los war.

Das Ergebnis der Baseline (16 GiB ARC, alte SSD-Rollen) war eindeutig:

  • Der Flaschenhals ist der HDD-Mirror. Busy im Mittel 58 bis 62 %, Spitzen bis 100 bis 104 %, Latenz im Mittel rund 8 ms, unter Last bis 20 bis 24 ms. In 16 % der Samples war die HDD zu 95 % oder mehr ausgelastet, also gesättigt.
  • Die CPU war zu rund 95 % idle, RAM frei, der Netz-Peak lag bei rund 68 Mbit/s, also nur etwa 7 % des Gigabit-Links. Weder CPU noch RAM noch Netz waren das Limit.
  • Der ARC klebte an seinem 16-GiB-Limit (Mittel 15,7 GiB) bei einer Hit-Rate von rund 94,7 %. Der ARC war schlicht ausgehungert und hätte mehr RAM sofort genutzt.
  • Der einzelne SLOG lief bei rund 42 % Busy, war also nicht gesättigt. Die Spindeln waren das Limit, nicht der SLOG.

Das ist die didaktische Pointe, die ich jedem ans Herz lege: Ohne diese Messung wüsste ich nicht, ob CPU, RAM, Netz oder Platten klemmen, und ich wüsste nicht, ob das Problem auf der Lese- oder der Schreibseite liegt. Messen ist kein Nice-to-have, sondern die Voraussetzung dafür, das richtige Bauteil zu kaufen und am richtigen Hebel zu drehen.

Was ein special vdev ist, und warum nicht einfach All-SSD

Allocation classes sind ein OpenZFS-Feature (feature@allocation_classes), mit dem ein Pool mehrere Klassen von vdevs führen kann. Das special vdev ist die Klasse für Metadaten: ZFS legt dnodes, indirekte Blöcke und poolweite Metadaten bevorzugt dort ab statt auf dem normalen Daten-vdev. Über die Dataset-Property special_small_blocks kann man zusätzlich kleine Datenblöcke unterhalb einer einstellbaren Schwelle aufs special vdev ziehen. Im Kern verschiebt man also genau die Datenklasse, die eine HDD am schlechtesten beherrscht, auf ein Medium, das genau dafür gebaut ist.

Dass das hier der richtige Hebel ist, ist nicht geraten, sondern messbar: Der ARC dieses Servers besteht zu rund 85 % aus Metadaten, konkret 17,4 GB Metadaten gegenüber 3,0 GB Daten im ARC. Der Workload ist also metadaten-dominiert. Metadaten auf SSD zu verlagern trifft den Engpass damit an der Wurzel, denn das ist exakt der Random-I/O, an dem die Platten am meisten leiden. Bevor ich mich für das special vdev entschieden habe, standen aber andere Optionen auf dem Tisch:

  • Kompletter All-SSD-Pool aus zwei großen SSDs: der sauberste Komplettfix, aber teuer und ein großer Umbau mit Pool-Neuaufbau und vollständiger Datenmigration. Overkill, wenn der Großteil der Kapazität aus kalten, überwiegend sequenziell gelesenen Daten besteht.
  • Mehr RAM und ARC: hilft nur der Leseseite und nur, solange der Working Set in den ARC passt. Schreib-Metadaten müssen trotzdem auf stabilen Speicher, daran ändert RAM nichts.
  • L2ARC behalten: abgeschafft. Bei 24 GiB ARC lag die Lese-Hit-Rate schon bei rund 98,5 %. Der L2ARC brachte nur rund 1,3 % zusätzliche Reads, ist flüchtig (nach einem Reboot leer) und kostet sogar ARC-RAM für seine Header. Das Kosten-Nutzen-Verhältnis war negativ.
  • special vdev: die gewählte Lösung. Nutzt die vorhandenen SSDs, kein Pool-Neuaufbau, adressiert exakt den gemessenen Metadaten-Schmerz, inkrementell und live im Betrieb machbar.

Der Umbau Schritt für Schritt

Aus dem alten Zustand mit einem einzelnen SLOG und einem L2ARC sollte ein SLOG-Mirror plus ein special-vdev-Mirror werden. Beide SSDs werden also jeweils zur Hälfte für beide Zwecke genutzt, jeweils gespiegelt. Zuerst die alten Single-Rollen entfernen:

zpool remove zroot ada3p1     # alter L2ARC
zpool remove zroot ada2p1     # alter (einzelner) SLOG

Und hier kam der erste Stolperstein, der so lehrreich ist, dass er einen eigenen Absatz verdient. Das SLOG-Remove schlug zunächst fehl:

cannot remove ada2p1: Mount encrypted datasets to replay logs

Die Ursache: Es existierten verschlüsselte Datasets, deren Keys in diesem Boot nie geladen waren. Der SLOG lässt sich nicht entfernen, solange potenziell noch nicht abgespielte ZIL-Einträge für gesperrte Datasets vorliegen, denn ZFS müsste diese Einträge zum Replay erst entsperren. Erst nach dem Aufräumen und Entsperren ließ sich der SLOG sauber entfernen. Das ist gleichzeitig die perfekte Überleitung zum Verschlüsselungskapitel weiter unten, denn es zeigt, wie tief native ZFS-Encryption in den ZIL-Pfad eingreift.

Danach die SSDs neu partitionieren, sauber 1-MiB-aligned. Pro SSD wird p1 16 GiB groß (SLOG) und p2 rund 208 GiB (special). Das Ergebnis von gpart show ada2 ada3:

=>       40  468862048  ada2  GPT  (224G)
         40       2008        - free -  (1004K)
       2048   33554432     1  freebsd-zfs  (16G)     # p1 -> SLOG
   33556480  435304448     2  freebsd-zfs  (208G)    # p2 -> special
  468860928       1160        - free -  (580K)

Jetzt der eigentliche Akt: gespiegelter SLOG und gespiegeltes special vdev werden hinzugefügt.

zpool add zroot log     mirror ada2p1 ada3p1
zpool add zroot special mirror ada2p2 ada3p2

Beide Befehle bewusst ohne -f. So bleibt der Redundanz-Schutz von ZFS als Sicherheitsnetz aktiv: ZFS verweigert ein nicht-redundantes special oder log neben einem Mirror, solange man es nicht ausdrücklich erzwingt. Und genau dieses Verweigern ist hier gewollt.

Die wichtigste Warnung dieses Beitrags: Ein special vdev ist nicht optional für die Pool-Integrität. Verliert man ein nicht gespiegeltes special vdev, ist der gesamte Pool verloren, denn die Metadaten liegen dort, und ohne sie ist der Rest unlesbar. Das special vdev muss mindestens so redundant sein wie das Daten-vdev, hier also als Mirror. Für den SLOG gilt das in dieser Schärfe nicht, ein verlorener SLOG kostet nur die letzten Sekunden async-bestätigter sync-Writes, aber ein SLOG-Mirror verhindert, dass ein einzelner SSD-Ausfall den ZIL-Schutz aushebelt.

Das fertige Layout sieht in zpool status und zpool list -v dann so aus:

zroot       mirror-0   ada0p3 + ada1p3   1.80T  (Daten, HDD-Mirror)
            special    mirror-3: ada2p2 + ada3p2   206G  (Metadaten, SSD-Mirror)  NEU
            logs       mirror-2: ada2p1 + ada3p1   15.5G (ZIL/SLOG, jetzt gespiegelt)

Zum SLOG-Sizing noch ein Wort, weil es oft falsch gemacht wird. Der SLOG puffert nur die dirty data eines, maximal zweier txg-Flush-Intervalle. Bei vfs.zfs.dirty_data_max = 4 GiB reichen 16 GiB SLOG mit großzügigem Polster, mehr bringt schlicht nichts. Genauso wichtig: Der SLOG beschleunigt nichts direkt. Er ist nur ein schnelles, stromausfallsicheres Zwischenlager für den ZIL, greift ausschließlich bei synchronen Writes (fsync oder O_SYNC) und wird im Normalbetrieb nie gelesen, sondern erst nach einem Crash zum Replay. Wer das verwechselt, sollte sich die Trennung einprägen: Der ZIL ist immer da, das ist das Konzept. Der SLOG ist nur ein optionales separates Gerät dafür.

Die unbequeme Wahrheit: nur neue Metadaten wandern

Hier muss ich ehrlich sein, denn es ist der am häufigsten missverstandene Punkt. Ein special vdev migriert keine bestehenden Metadaten. Es nimmt nur auf, was nach dem Hinzufügen geschrieben wird. Alte Metadaten bleiben auf der HDD liegen, bis sie durch Copy-on-Write ohnehin neu geschrieben werden. Der volle Effekt entsteht also erst über die Zeit oder durch einen optionalen zfs send | zfs recv-Rebuild der großen Datasets. Kein Sofort-magisch-alles-schneller, sondern ein Mechanismus, der sich befüllt. Dass er sich befüllt, sieht man an der Belegung, die mit jedem neuen Metadaten-Write wächst:

special   mirror-3   206G   alloc 5.38G   free 201G   FRAG 27%   CAP 2.60%

Die Messung danach, und wie man sie ehrlich liest

Jetzt kommt der Teil, an dem viele Tuning-Berichte unsauber werden, weil sie einen Vorher-Nachher-Durchsatz behaupten, der unter unterschiedlicher Last gemessen wurde und damit nichts beweist. Ich gehe einen anderen Weg und zeige die Wirkung über drei Argumente, von denen zwei komplett lastunabhängig sind.

Erstens der Latenz-Split pro vdev, das stärkste und lastunabhängige Argument. zpool iostat -lv zeigt die Latenzen getrennt pro vdev. Die folgende Tabelle sind seit-Boot-kumulierte Mittelwerte, also langzeit-repräsentativ und kein zufälliger Augenblick:

                  capacity     operations     bandwidth    total_wait
vdev            alloc   free   read  write   read  write   read   write
mirror-0        1.22T   595G     45      7   434K   601K   46ms   34ms    # HDD (Daten)
  ada0p3                         22      3   217K   300K   56ms   39ms
  ada1p3                         23      3   217K   300K   36ms   29ms
special/mirror-3 5.38G  201G      0     67  5.28K  3.24M  455us    6ms    # SSD (Metadaten)
  ada2p2                          0     33  2.67K  1.62M  447us    5ms
  ada3p2                          0     33  2.61K  1.62M  464us    6ms
logs/mirror-2   31.6M  15.5G      0     45      3   947K    2ms    1ms    # SSD (SLOG/ZIL)

Die Kernaussage steht in zwei Zahlen: Metadaten-Leselatenz 455 µs auf der special-SSD gegen 46 ms auf der HDD, das ist etwa Faktor hundert. Jeder Metadaten-Zugriff, der nicht ohnehin aus dem RAM bedient wird, ist seitdem rund hundertmal schneller. Zu den -l-Spalten kurz: total_wait ist die Gesamtwartezeit inklusive Queue, disk_wait die reine Gerätelatenz, syncq_wait und asyncq_wait die Zeit in den ZFS-internen Queues. Wer ein echtes Zeitfenster statt des Boot-Mittels sehen will, nimmt zpool iostat -lv zroot 10 2 und liest das zweite Sample, denn das erste ist immer der Seit-Boot-Durchschnitt.

Zweitens die ARC-Metadaten-Aufteilung, also die Struktur des Workloads. Sie erklärt, warum es gerade hier so viel bringt:

arcstats.metadata_size          = 17.4 GB     # rund 85 % des ARC sind Metadaten
arcstats.data_size              =  3.0 GB
arcstats.demand_metadata_hits   = 1,133,349,218
arcstats.demand_metadata_misses =    11,594,376   # müssen auf Platte ... jetzt SSD
arcstats.demand_data_hits       =   220,864,693
arcstats.demand_data_misses     =       672,908

Der Workload ist metadaten-dominiert. Die Lifetime-ARC-Hit-Rate liegt bei rund 98,9 %, aber die über 11,5 Millionen Metadaten-Misses müssen zwangsläufig auf Platte, und sie landen jetzt auf SSD statt auf HDD. Hier multipliziert sich der Faktor-hundert-Latenzvorteil mit der schieren Menge an Metadaten-Operationen. Das ist die quantitative Begründung dafür, warum ausgerechnet ein special vdev der wirksamste Hebel war und nicht etwa nur mehr ARC. Begleitend habe ich das ARC-Limit von 16 auf 24 GiB angehoben, weil RAM frei war. Die Folge war eine Hit-Rate von rund 95 % auf rund 99 %. Zwei Hebel, die zusammenwirken: weniger Misses überhaupt, und die verbliebenen sind jetzt SSD-schnell.

Das Herzstück: die 8,5-MB/s-Rechnung

Drittens, und das ist der eigentliche Aha-Moment, eine logische Schlussfolgerung statt eines Durchsatz-Vergleichs. Die Ausgangsmessung lief unter einer ganz konkreten Last: Ein Client lud zeitgleich größere Dateien herunter, ein klassischer Datei-Download. Der Netzdurchsatz dabei lag bei rund 68 Mbit/s, also etwa 8,5 MB/s. Und genau hier wird es interessant.

Eine einzelne 7200-rpm-HDD liefert sequenziell 150 bis 200 MB/s. Ein Download mit 8,5 MB/s ist also kaum 5 % dessen, was eine Platte im Schlaf kann, und hier zogen sogar zwei davon im Mirror mit. Trotzdem zeigte die Messung, dass der HDD-Mirror im Mittel rund 60 % ausgelastet war und in 16 % der Messintervalle voll gesättigt (95 % Busy oder mehr), mit Latenzen bis 20 bis 24 ms.

Das ist ein Widerspruch, und der Widerspruch ist der Beweis. Für sequenzielle 8,5 MB/s darf eine HDD niemals an die Sättigung kommen. Wenn sie es doch tut, dann waren diese Zugriffe nicht sequenziell, sondern seek-gebunden. Die Köpfe wurden permanent quer über die Platte gerissen. Wofür? Für das, was dieses System zu rund 85 % beschäftigt: Metadaten-Random-I/O, also dnodes, indirekte Blöcke und Verzeichnis-Lookups, die sich auf denselben zwei Spindeln mit dem Download um die Köpfe prügelten, verschärft durch die damals hohe Fragmentierung. Ein eigentlich harmloser Download zerfiel so in ein Seek-Gewitter.

Genau diese Konkurrenz wurde mit dem special vdev eliminiert. Die Metadaten-Zugriffe laufen jetzt auf den SSDs mit rund 455 µs statt zig Millisekunden. Die HDD-Köpfe können auf dem Datenstrom bleiben, statt ständig für Metadaten wegzuspringen. Derselbe Download belastet die Spindeln damit nur noch einen Bruchteil. Nicht, weil die Dateidaten schneller kämen, die liegen weiter auf HDD, sondern weil der Lärm daneben weg ist. Diese Schlussfolgerung steht ohne erfundenen Vergleich, sie ist wasserdicht: 8,5 MB/s sättigt physikalisch keine HDD, also waren es Seeks, also Metadaten-Kontention, und genau die habe ich verlagert.

Wie sich der Pool im ruhigen Normalbetrieb anfühlt, zeigt eine zweite, entspannte Momentaufnahme. Sie ist ausdrücklich kein Vorher-Nachher-Vergleich, sondern nur ein Blick auf den Alltag:

CPU idle 96.9 %   ARC hit 99.7 %   ARC 23.3 GiB
HDD busy ~2 %     HDD-Sättigung 0 %   HDD-Latenz ~1.5 ms
SSD busy 4.3 % / 4.5 % (gleichmäßig über beide Mirror-Member)
net-out-Peak 2.0 Mbit/s

Im ruhigen Normalbetrieb langweilt sich der HDD-Mirror, fast alle Reads kommen aus ARC oder SSD. Das illustriert den Alltag. Die eigentliche Wirkung des Umbaus zeigen aber die 8,5-MB/s-Rechnung oben sowie der Latenz-Split und die ARC-Aufteilung, und die gelten unabhängig von der Last.

Sicherheit und Verschlüsselung, die entscheidende Nuance

Die wichtigen Datasets dieses Systems sind nativ mit ZFS verschlüsselt (encryption = aes-256-gcm), die System- und Boot-Datasets nicht. Sobald man ein special vdev einführt, stellt sich sofort die sicherheitskritische Frage: Landet jetzt unverschlüsselter Klartext auf den SSDs, nur weil dort die Metadaten liegen? Die Antwort ist ein klares Nein, und die Begründung ist wichtig genug, um sie sauber auszuführen.

  • ZFS native encryption verschlüsselt Dateiinhalte und die sensiblen Objekt-Metadaten, also Dateinamen, Verzeichnisstruktur, dnodes, Attribute und ACLs. Diese Blöcke sind bereits Ciphertext, bevor der Allocator überhaupt entscheidet, auf welches vdev sie wandern. Ein special vdev ist nur ein anderer Ablageort und ändert an der Verschlüsselung nichts. Verschlüsselte Metadaten bleiben auf der special-SSD verschlüsselt.
  • Was ZFS-Encryption ohnehin nicht verbirgt, special vdev hin oder her, sind die Metadaten auf Pool- und Dataset-Ebene: Dataset-Namen, Pool-Struktur, Anzahl und Größe von Snapshots, die Blockpointer-Struktur. Das ist eine Eigenschaft von ZFS-Encryption und keine neue Schwäche durch das special vdev.
  • aes-256-gcm ist authenticated encryption (AEAD), liefert also Vertraulichkeit und gleichzeitig Integritäts- und Authentizitätsschutz der verschlüsselten Blöcke.

Ein schöner Praxisbezug schließt sich hier zum Umbau-Kapitel: Genau weil verschlüsselte Datasets im Spiel sind, blockierte das zpool remove mit der Meldung über das Mounten verschlüsselter Datasets zum Replay. Das zeigt anschaulich, wie tief Encryption in den ZIL- und SLOG-Pfad eingreift, denn der ZIL kann Einträge für verschlüsselte Datasets enthalten, die sich nur nach dem Entsperren abspielen lassen. Das Fazit zur Sicherheit ist damit eindeutig: Ein special vdev ist verschlüsselungs-neutral. Wer verschlüsselte Datasets nutzt, bekommt verschlüsselte Metadaten auf der special-SSD, kein Klartext-Leak.

Abwägung: Vorteile, Nachteile, Risiken

Was unterm Strich für das special vdev spricht:

  • Es adressiert den gemessenen Engpass, Metadaten-Random-I/O, direkt an der Wurzel.
  • Es nutzt vorhandene SSDs, also keine Neuanschaffung, kein Pool-Neuaufbau, live im laufenden Betrieb hinzugefügt.
  • Rund hundertfach niedrigere Metadaten-Leselatenz (455 µs gegen 46 ms), spürbar bei ls, stat, find, Snapshots, Scrub und allen Workloads mit vielen kleinen Dateien.
  • Über special_small_blocks später fein justierbar, um kleine Datenblöcke nachzuziehen, ohne Downtime und nur für neue Writes.
  • Verschlüsselungs-neutral.
  • Der I/O verteilt sich jetzt gleichmäßig über beide Mirror-Member. Vorher lag eine SSD als einzelner SLOG bei rund 42 % Busy, die andere als L2ARC quasi brach.

Und ehrlich auch die andere Seite, denn ein special vdev ist kein Selbstläufer:

  • Redundanz ist Pflicht, nicht Kür. Ein nicht-redundantes special vdev bedeutet Totalverlust des Pools bei SSD-Ausfall. Mirror ist zwingend.
  • Keine Migration bestehender Metadaten. Nur neue Writes wandern, der volle Effekt kommt erst per send und recv-Rebuild.
  • Das special vdev kann volllaufen. Ist es voll, fallen neue Metadaten auf das langsame Daten-vdev zurück. Das ist kein Fehler, aber der Effekt lässt nach, also Füllgrad mit zpool list -v überwachen.
  • special_small_blocks zu hoch gesetzt verstopft das special vdev mit Datenblöcken und lässt es schneller volllaufen. Vorsichtig hochtasten (von 0 über 4K und 8K bis vielleicht 32K) und dabei den Füllgrad beobachten.
  • Mehr vdevs bedeuten mehr Komplexität und mehr Teile, die ausfallen können. Den SSD-Wear im Blick behalten, hier bewusst Datacenter-SSDs mit Power-Loss-Protection gewählt, weil sie Dauerlast und sync-Writes aushalten.
  • Der zpool remove-Stolperstein mit verschlüsselten Datasets gehört dokumentiert, damit man im Ernstfall nicht in Panik gerät.

Die eigentliche Botschaft

ZFS erlaubt es, die Storage-Architektur inkrementell und im laufenden Betrieb an einen gemessenen Engpass anzupassen, ohne Pool-Neuaufbau, ohne Downtime, ohne Datenmigration als Vorbedingung. Aus einem simplen HDD-Mirror wurde durch zwei zpool add-Befehle ein hybrider, mehrstufiger Pool: kalte Massendaten auf günstigen Spindeln, heiße Metadaten und optional kleine Blöcke auf schnellen SSDs, synchrone Writes über einen gespiegelten SLOG. Diese Flexibilität, tiered storage als Live-Operation, kombiniert mit Checksumming, Compression, Snapshots und nativer Verschlüsselung im selben Dateisystem, ist der eigentliche Kern. Man kauft sich SSD-Speed genau dort, wo die Messung den Schmerz zeigt, und lässt den Rest günstig auf HDD. Kein anderes verbreitetes Dateisystem macht das so geradlinig.

Ausblick

  • special_small_blocks schrittweise anheben, um kleine Dateien und nicht nur Metadaten auf SSD zu ziehen, live und nur für neue Writes.
  • Ein optionaler send und recv-Rebuild der großen Datasets, um bestehende Metadaten auf das special vdev zu migrieren und so den vollen Effekt zu heben.
  • Eine lastgleiche Wiederholungsmessung in einem Hochlast-Fenster für eine saubere Zahl auf der Schreibseite.

Spickzettel

Die Befehle, mit denen man Layout, Latenzen und ARC-Komposition selbst nachsieht:

# Pool-Layout und Auslastung pro vdev
zpool status zroot
zpool list -v zroot

# Latenzen pro vdev (das Geld-Kommando), 2. Sample lesen für ein echtes Zeitfenster:
zpool iostat -lv zroot 10 2

# ARC: Größe und Metadaten/Daten-Split plus Demand-Hits und -Misses
sysctl kstat.zfs.misc.arcstats.size kstat.zfs.misc.arcstats.metadata_size kstat.zfs.misc.arcstats.data_size kstat.zfs.misc.arcstats.demand_metadata_hits kstat.zfs.misc.arcstats.demand_metadata_misses

# allocation_classes-Feature und special_small_blocks
zpool get feature@allocation_classes zroot
zfs get special_small_blocks zroot

# Verschlüsselungs-Status der Datasets
zfs get encryption,keystatus DATASET

# SSD-Partitionierung
gpart show ada2 ada3

# SLOG-Sizing-Kontext
sysctl vfs.zfs.dirty_data_max

# Pool-Historie (zeigt die echten add/remove-Befehle)
zpool history zroot

Siehe auch:

Selbst einen HDD-Pool mit einem special vdev entschärft, oder noch am Abwägen, ob sich der Umbau lohnt? Erzähl mir gern von deinem Layout, oder stell deine fragen.

FreeBSD: Unverschlüsseltes ZFS-Dataset nachträglich verschlüsseln

Bild der Bücher FreeBSD Mastery ZFS und FreeBSD Mastery Advanced ZFS

ZFS Encryption lässt sich nicht nachträglich auf ein bestehendes Dataset aktivieren. Die Daten müssen per zfs send | zfs receive in ein neues, verschlüsseltes Dataset geschrieben werden. Typischer Anwendungsfall: Jails, die in eigenen Datasets liegen und nach einem FreeBSD-Upgrade auf 13+ verschlüsselt werden sollen.

Wer die Grundlagen zu ZFS Encryption noch braucht (Dataset anlegen, Passphrase, Mount nach Reboot), findet sie im Beitrag Native ZFS Encryption einrichten.

Ausgangslage

Ein Pool zroot mit dem unverschlüsselten Dataset varta:

zfs list zroot/varta
NAME          USED  AVAIL     REFER  MOUNTPOINT
zroot/varta   100M  12.0G      100M  /zroot/varta

zfs get encryption zroot/varta
NAME         PROPERTY    VALUE   SOURCE
zroot/varta  encryption  off     default

Migration

Bei zfs send | zfs receive kann man kein Passphrase interaktiv eingeben, weil stdin durch die Pipe belegt ist. Deshalb legt man den Schlüssel temporär in einer Datei ab:

echo 'MeinGeheimesPassphrase' > /tmp/keyfile.txt
chmod 600 /tmp/keyfile.txt

Snapshot erstellen und in ein neues verschlüsseltes Dataset senden:

zfs snapshot zroot/varta@migration

zfs send zroot/varta@migration | \
  zfs receive -F \
  -o encryption=on \
  -o keyformat=passphrase \
  -o keylocation=file:///tmp/keyfile.txt \
  zroot/en-varta

Das neue Dataset zroot/en-varta enthält jetzt dieselben Daten, verschlüsselt mit AES-256-GCM:

zfs list zroot/varta zroot/en-varta
NAME             USED  AVAIL     REFER  MOUNTPOINT
zroot/en-varta   100M  11.8G      100M  /zroot/en-varta
zroot/varta      100M  11.8G      100M  /zroot/varta

Aufräumen

Die Keyfile-Referenz auf Passphrase-Abfrage umstellen und die temporäre Datei löschen:

zfs set keylocation=prompt zroot/en-varta

zfs get keylocation zroot/en-varta
NAME            PROPERTY     VALUE   SOURCE
zroot/en-varta  keylocation  prompt  local

rm /tmp/keyfile.txt

Dann das alte Dataset entfernen und das neue umbenennen:

zfs destroy -r zroot/varta
zfs rename zroot/en-varta zroot/varta

Fertig. Das Dataset liegt jetzt verschlüsselt am selben Mountpoint wie vorher:

zfs get encryption,keylocation,keyformat zroot/varta
NAME         PROPERTY     VALUE        SOURCE
zroot/varta  encryption   aes-256-gcm  -
zroot/varta  keylocation  prompt       local
zroot/varta  keyformat    passphrase   -

Stolperfallen

Keyfile in /tmp ist ein Kompromiss. Auf FreeBSD-Default ist /tmp zwar ein tmpfs im RAM, aber bei Speicherdruck kann das System swappen. chmod 600 schützt gegen andere Benutzer, nicht gegen root, Backup-Prozesse oder einen Crash-Dump. Sauberer ist eine keylocation auf einem schon verschlüsselten Dataset oder ein FIFO statt einer regulären Datei. In beiden Fällen existiert die Passphrase nie persistent auf der Platte.

Properties gehen beim Send verloren. Ohne -R (Replication Stream) oder explizite -o-Optionen werden compression, recordsize, quota, reservation, atime und eigene Properties nicht mitübertragen. Wer compression=zstd oder recordsize=1M gesetzt hatte, muss die beim receive wieder setzen oder direkt einen Replication Stream nutzen.

Mountpoint nach dem Rename prüfen. Lag das alte Dataset auf /var/jails/varta, muss der Mountpoint nach dem Rename wieder explizit gesetzt werden, sonst landet das Dataset am Default-Pfad des Pools:

zfs set mountpoint=/var/jails/varta zroot/varta

Jail vorher stoppen. service jail stop <name> bzw. iocage stop oder bastille stop. Sonst sind Dateien offen, zfs destroy -r schlägt fehl und der Rename macht keinen Spaß.

Inkrementelle Migration für große Datasets

Bei Jails mit Datenbank, Mailspool oder einfach mehreren hundert GB ist Downtime gleich Send-Laufzeit nicht akzeptabel. Besser: initial senden während der Dienst läuft, dann nur kurz stoppen und den inkrementellen Rest nachziehen.

# Phase 1: initialer Send im laufenden Betrieb
zfs snapshot zroot/varta@migration-1
zfs send zroot/varta@migration-1 | \
  zfs receive -F \
  -o encryption=on \
  -o keyformat=passphrase \
  -o keylocation=file:///tmp/keyfile.txt \
  zroot/en-varta

# Phase 2: Dienst stoppen, inkrementelles Delta senden
service jail stop varta
zfs snapshot zroot/varta@migration-2
zfs send -i @migration-1 zroot/varta@migration-2 | \
  zfs receive zroot/en-varta

# Phase 3: Rename und Neustart
zfs destroy -r zroot/varta
zfs rename zroot/en-varta zroot/varta
zfs set mountpoint=/var/jails/varta zroot/varta
service jail start varta

Die Downtime reduziert sich so auf den inkrementellen Send plus Rename, bei einer typischen Mailbox sind das Sekunden statt Minuten. Bei sehr aktiven Datasets kann man mehrere inkrementelle Snapshots nacheinander schieben, bis das Delta klein genug für die gewünschte Zielzeit ist.

Update 2026: was heute dazugekommen ist

OpenZFS 2.x ist auf FreeBSD 14 und 15 stabil. Der eigentliche Migrationspfad hat sich nicht geändert, drumherum ist einiges dazugekommen:

Raw encrypted send/receive. Mit zfs send -w wird ein verschlüsseltes Dataset ohne Entschlüsselung übertragen. Der Remote-Host lagert den Stream, kennt den Schlüssel nicht und sieht keinen Klartext. Für Offsite-Backups der saubere Weg, sobald die Migration durch ist:

zfs snapshot zroot/varta@backup
zfs send -w -R zroot/varta@backup | \
  ssh backup@remote zfs receive backuppool/varta

Andere Keyformate. Statt keyformat=passphrase gehen auch keyformat=raw (32-Byte-Keyfile, z.B. aus HSM oder TPM) oder keyformat=hex (64 Zeichen Hex). keylocation=https://... holt den Schlüssel beim Pool-Import von einer URL, praktisch für headless Systeme, bei denen die Passphrase-Abfrage beim Boot stört.

Kompression vor Verschlüsselung. ZFS komprimiert zuerst, verschlüsselt danach. compression=zstd zusammen mit encryption=on wirkt also wie erwartet, und der komprimierte Zustand bleibt auch im Raw Stream erhalten.

Nur für Datenpools und Non-Root-Datasets. Diese Anleitung deckt Jails, Home-Verzeichnisse, Mailspools und ähnliches ab. Verschlüsseltes Root-on-ZFS ist ein eigenes Thema und braucht zusätzlich Boot-Environment-Handling (bectl) sowie ein geli-verschlüsseltes Swap.

Siehe auch

Native ZFS Encryption einrichten und nutzen für die Grundlagen zu Dataset, Passphrase und Mount nach Reboot. Verschlüsseltes ZFS-Backup auf USB-Platte mit geli für die Offline-Sicherung. Linux Mint mit verschlüsseltem ZFS-Root-Pool installieren für das Linux-Pendant mit Root-Pool.

Eine Übersicht über alle ZFS-Funktionen gibt es im ZFS-Überblick. Fragen? Einfach melden.

FreeBSD: Native ZFS Encryption einrichten und nutzen

Seit FreeBSD 13 steht native ZFS Encryption zur Verfügung. Datasets lassen sich mit AES-256-GCM verschlüsseln, ohne dass der gesamte Pool verschlüsselt sein muss. Die Verschlüsselung greift pro Dataset und vererbt sich auf Kind-Datasets.

Verschlüsseltes Dataset anlegen

Ein neues Dataset mit Passphrase-Abfrage:

zfs create -o encryption=aes-256-gcm -o keyformat=passphrase usbpool/test01
Enter passphrase:
Re-enter passphrase:

Das Dataset wird sofort gemountet und ist einsatzbereit. Alles was hineingeschrieben wird, liegt verschlüsselt auf der Platte:

zfs list usbpool/test01
NAME             USED  AVAIL     REFER  MOUNTPOINT
usbpool/test01    99K   899G       99K  /usbpool/test01

zfs get encryption usbpool/test01
NAME            PROPERTY    VALUE        SOURCE
usbpool/test01  encryption  aes-256-gcm  -

Nach einem Reboot

Bei einem Passphrase-geschützten Dataset hat ZFS nach einem Reboot den Schlüssel nicht mehr. Das Dataset existiert, ist aber nicht gemountet:

zfs get mounted usbpool/test01
NAME            PROPERTY  VALUE    SOURCE
usbpool/test01  mounted   no       -

Mit zfs mount -l wird der Schlüssel geladen und das Dataset eingehängt:

zfs mount -l usbpool/test01
Enter passphrase for 'usbpool/test01':

zfs get mounted usbpool/test01
NAME            PROPERTY  VALUE    SOURCE
usbpool/test01  mounted   yes      -

Keyfile statt Passphrase

Statt einer Passphrase-Abfrage kann der Schlüssel auch in einer Datei liegen. Praktisch für Server die ohne Interaktion booten sollen:

zfs create -o encryption=aes-256-gcm \
  -o keyformat=passphrase \
  -o keylocation=file:///root/keys/pool.key \
  zroot/encrypted-data

Die Key-Datei enthält das Passphrase als Text. Wichtig: Die Datei muss beim Boot erreichbar sein, also auf einem unverschlüsselten Dataset liegen. Berechtigungen auf 0400 setzen.

Bestehende Datasets verschlüsseln

Verschlüsselung lässt sich nicht nachträglich auf ein bestehendes Dataset aktivieren. Man muss die Daten per zfs send | zfs receive in ein neues, verschlüsseltes Dataset migrieren. Die komplette Anleitung dafür steht im Beitrag ZFS-Dataset nachträglich verschlüsseln.

Eine Übersicht über alle ZFS-Funktionen gibt es im ZFS-Überblick. Wer sich für ZFS Encryption unter Solaris/OpenIndiana interessiert, findet die Anleitung unter ZFS Encryption unter Solaris. Fragen? Einfach melden.

ioping: Read- und Write-Latency schnell messen

Für ausführliche Storage-Benchmarks gibt es Tools wie bonnie++ oder fio. Wenn man nur schnell die Read- oder Write-Latency eines Dateisystems prüfen will, reicht ioping — ein einzelner Befehl, Ergebnis in Sekunden.

Installation

# FreeBSD
pkg install ioping

# Debian/Ubuntu
apt install ioping

Read-Latency messen

ioping -s 256k -T 120 -D -c 20 ./
256 KiB <<< ./ (zfs tanksmeer/usr/home): request=1 time=16.0 us (warmup)
256 KiB <<< ./ (zfs tanksmeer/usr/home): request=2 time=35.7 us
256 KiB <<< ./ (zfs tanksmeer/usr/home): request=3 time=45.8 us
...

--- ./ (zfs tanksmeer/usr/home) ioping statistics ---
19 requests completed in 853.7 us, 4.75 MiB read, 22.3 k iops, 5.43 GiB/s
generated 20 requests in 19.0 s, 5 MiB, 1 iops, 269.2 KiB/s
min/avg/max/mdev = 35.7 us / 44.9 us / 52.8 us / 3.85 us

Die Parameter im Detail:

  • -s 256k — Blockgröße pro Request (hier 256 KiB)
  • -T 120 — Timeout in Sekunden, Requests die länger brauchen werden ignoriert
  • -D — Direct I/O, umgeht den Kernel-Cache (misst die echte Disk-Latency)
  • -c 20 — Anzahl der Requests
  • ./ — Pfad zum Dateisystem das gemessen werden soll

Die Summary am Ende zeigt min/avg/max/mdev — genau wie bei ping. Hier: durchschnittlich 44,9 µs Read-Latency auf einem ZFS-Dataset.

Write-Latency messen

Für die Write-Latency kommt ein einziger Parameter dazu — -W:

ioping -s 256k -T 120 -D -W -c 20 ./
256 KiB >>> ./ (zfs tanksmeer/usr/home): request=1 time=27.0 us (warmup)
256 KiB >>> ./ (zfs tanksmeer/usr/home): request=2 time=54.4 us
256 KiB >>> ./ (zfs tanksmeer/usr/home): request=3 time=60.6 us
...

--- ./ (zfs tanksmeer/usr/home) ioping statistics ---
19 requests completed in 3.86 ms, 4.75 MiB written, 4.93 k iops, 1.20 GiB/s
generated 20 requests in 19.0 s, 5 MiB, 1 iops, 269.5 KiB/s
min/avg/max/mdev = 51.6 us / 202.9 us / 2.65 ms / 577.9 us

Write ist hier erwartungsgemäß langsamer — 202,9 µs im Schnitt gegenüber 44,9 µs beim Lesen. Die höhere Standardabweichung (577,9 µs vs. 3,85 µs) zeigt, dass einzelne Writes deutlich länger dauern können (hier ein Ausreißer mit 2,65 ms — vermutlich ein ZFS Transaction Group Commit).

Weitere nützliche Optionen

# Fortlaufend messen (wie ping ohne -c)
ioping -D ./

# Nur die Summary nach 10 Requests
ioping -D -c 10 -q ./

# Bestimmte Blockgröße (4k für Random I/O)
ioping -s 4k -D -c 20 ./

# Netzlaufwerk / NFS-Mount testen
ioping -D -c 20 /mnt/nfs-share/

Praktisch für einen schnellen Vergleich: Lokale SSD, NFS-Share und USB-Platte mit dem gleichen Befehl messen — die Unterschiede werden sofort sichtbar. Fragen? Einfach melden.

Citrix XenServer: Festplattenpriorität im Storage-Pool konfigurieren​

Veraltet: Citrix XenServer wird seit 2024 nicht mehr in dieser Form angeboten. Die Storage-Pool-Konfiguration hat sich grundlegend geändert. Alternativen: Proxmox VE oder XCP-ng.

Hat man in seinem Citrix XenServer mehrere virtuelle Festplatte in einem Storage liegen, kann es vorkommen dass man einzelnen davon eine höhere Priorität zuweisen möchte als anderen.

Leider gibt es diese Option nicht klickbar im Citrix XenCenter, sondern man muss die Konsole (CLI) bemühen.

Das Einstellen dieser Prioritäten ist etwas komplexer, ich beschränke mich in meinem Beispiel auf die „schnell und einfach“ Version. Damit möchte ich sagen, bitte selbst damit beschäftigen.

Zum Thema… Es gibt verschiedene Algorithmen, welche man für sein QOS der virtuellen Festplatten wählen kann. Ich nehme gerne ionice, da es bei mehreren Systemen eher um IO-Probleme als reine Durchsatzprobleme geht. Diesem Algorithmus gebe ich die Information mit das es hier um realtime geht und die Klasse in welche die virtuelle Festplatte gesteckt werden soll. Bei der Klassifizierung ist zu beachten, dass es ein ganzzahliger Wert zwischen 0 und 7 sein muss. Die Klasse 0 hat dabei die höchste Priorität und die Klasse 7 die geringste.

Kleines Beispiel gefällig?

Wir sind auf der root Konsole des XenServers. Ich lasse mir die VMs mit ihren Platten anzeigen, in diesem Fall gibt es keine Snapshots. Würde es welche geben, gleiches Vorgehen, es sieht nur etwas „unübersichtlicher“ aus.

[root@fra.srv.ha.xen.05 ~]# xe vbd-list
uuid ( RO)             : 66a3903c-8eba-4d8a-92d9-c435d399d3ac
          vm-uuid ( RO): 577e39d4-e771-477b-8829-8648b05b682b
    vm-name-label ( RO): VM-Kennzeichnung
         vdi-uuid ( RO): <not in database>
            empty ( RO): true
           device ( RO):

uuid ( RO)             : 4e004302-c32e-4c90-b986-9efc0b1995a1
          vm-uuid ( RO): 577e39d4-e771-477b-8829-8648b05b682b
    vm-name-label ( RO): Laufwerkskennzeichnung
         vdi-uuid ( RO): 47e5ab14-9cf8-4e7f-88b8-fe20247efa85
            empty ( RO): false
           device ( RO): xvdb

uuid ( RO)             : 5b4f70ec-07cb-47a5-aa05-91647cf38b78
          vm-uuid ( RO): 577e39d4-e771-477b-8829-8648b05b682b
    vm-name-label ( RO): Laufwerkskennzeichnung
         vdi-uuid ( RO): e6796376-995f-4a99-8ba6-893c30aa6a14
            empty ( RO): false
           device ( RO): xvda

Zu erkennen ist ein System (577e39d4-e771-477b-8829-8648b05b682b) mit zwei virtuellen Festplatten (4e004302-c32e-4c90-b986-9efc0b1995a1 / 5b4f70ec-07cb-47a5-aa05-91647cf38b78).

Versorgt mit diesen Informationen kann ich nun direkt die beiden Platten mit neuer Priorität versehen.

$ xe vbd-param-set uuid=4e004302-c32e-4c90-b986-9efc0b1995a1 qos_algorithm_type=ionice
$ xe vbd-param-set uuid=4e004302-c32e-4c90-b986-9efc0b1995a1 qos_algorithm_paramsched=rt
$ xe vbd-param-set uuid=4e004302-c32e-4c90-b986-9efc0b1995a1 qos_algorithm_params:class=5

$ xe vbd-param-set uuid=5b4f70ec-07cb-47a5-aa05-91647cf38b78 qos_algorithm_type=ionice
$ xe vbd-param-set uuid=5b4f70ec-07cb-47a5-aa05-91647cf38b78 qos_algorithm_paramsched=rt
$ xe vbd-param-set uuid=5b4f70ec-07cb-47a5-aa05-91647cf38b78 qos_algorithm_params:class=5

Als Test lasse ich mir nun noch einmal die gesetzten Einstellungen auf der Konsole ausgeben. Einmal den gewählten QOS-Algorithmus und dann dessen gesetzte Optionen.

$ xe vbd-param-get uuid=5b4f70ec-07cb-47a5-aa05-91647cf38b78 param-name=qos_algorithm_type
ionice
$ xe vbd-param-get uuid=5b4f70ec-07cb-47a5-aa05-91647cf38b78 param-name=qos_algorithm_params
class: 5; sched: rt

Noch Fragen? Dann fragen…

 

Contabo VPS

Lange habe ich nach einem ordentlichen Anbieter für einen neuen vServer gesucht. Dabei galt es folgende Kriterien zu erfüllen:

– Min. 2 IPv4 Adressen
– Ein kleines IPv6 Netz
– Unbegrenzter Traffic
– Min. 100Mbit/s Anbindung
– Min. 2 CPUs
– Min. 4 GB RAM
– Min. 200 GB HDD
– Linux als OS

Natürlich habe ich zuerst die Großen abgeklappert.

– 1und1 kein IPv6 (warum nicht? Ich meine 2014 HALLO!?!?)
– Strato nur EINE IPv6 Adresse (Ö_ö eine IPv6 Adresse…. eine?)
– Host Europe kein IPv6 bei den vServer nur bei den Root Server EINE (tz..)
– 1blue kein IPv6
– Server4you kein IPv6 beim vServer, sonst soll es wohl gehen…
– Serverloft… Joar, die Kosten sind mir zu hoch. Sind aber auch keine vServer.
– usw. usw. usw…

IPv6 scheint noch immer ein größeres Problem zu sein, ist nicht voll integriert oder ist (wie auch meherer IPv4 Adressen) hochpreisigen Produkten vorbehalten.

Dann bin ich auf Contabo gestoßen. Ich war Opfer der Werbung im Linux Magazin 🙁 Preis/Leistung sah dabei einfach zu gut aus. Daher habe ich angerufen. Ohne lange Hoteline sprach ich mit einem Menschen. Diesem stellte ich direkt meine Fragen und er konnte sie überraschenderweise direkt und sicher beantworten. Mit sicher meine ich, dass man nicht das Gefühl hatte er würde es irgendwo nachlesen oder wäre nach einer kurzen Schulung auf die Hotline losgelassen worden. Nein, es war wirklich gut!

Natürlich habe ich abschließend die Frage gestellt wie es klappt dass die angegebene Leistung so gut ist, der Support so schön zu funktionieren scheint und die Ausstattung und Randbedingungen ebenfalls so gut erscheinen. Nach hörbarem Schmunzeln bekam ich die Antwort: Das würde oft gefragt…. Ich müsse es so sehen. Contabo selbst stellt wirklich nur die Hardware und die Infrastruktur. Für das System selbst ist man selbst verantwortlich. Wenn es da mal Probleme gibt, könnte der Support zwar helfen diese wäre dann aber Kostenpflichtig (er meinte damit wenn man seine Kiste mal zerfriemelt hat). Man müsse schon wissen was man tut, dieses würden Contabo bei seinen Produkten einfach voraussetzten.

Schien also genau das zu sein was ich gesucht habe! Daher habe ich bestellt… Wobei ich genau eine solche Antwort von jedem Root-Server erwarten würde.

Alles ging schnell und für mich verständlich online. Ich bekam eine E-Mail mit der Bitte Geld zu überweisen (wer konnte damit nur rechnen. ). Kurz nach meiner Überweisung flatterten bereits die Zugangsdaten in mein Postfach.

Wie bei der Bestellung angeklickt hatte ich schon eine zweite IPv4 Adresse und konnte die PTR-Records flott im Webmenü eintragen. Um die PTR-Records der IPv6 Adressen zu ändern musste ich kurz den Support per E-Mail bemühen. Freitags um 23:36 Uhr habe ich ihn angemailt als ich morgens aufgewacht bin hatte ich schon die Bestätigung in meinem Postfach. Das System selbst ist genau wie bestellt und hat mehr Leistungsreserven als erwartet. Ich habe 8GB Arbeitsspeicher, 400Gb Festplattenplatz und zwei CPUs mit 3,4GHz. Auf der Webseite war nur etwas von 3,2GHz zu lesen. Ok ok… die paar MHz machen den Braten jetzt nicht fett, das es Core I7 CPUs sind hat mich denn noch überrascht!

Ich habe natürlich Speicher und CPU mal mit Arbeit beworfen um zu testen ob es nicht nur Schein ist. Alles prima…. Die Storage Anbindung ist ja gerne mal etwas zu genau auf den Punkt dimensioniert. Bei meinem System kann ich nicht klagen. Performance und I/Os sind wunderbar und mehr als ausreichend.

100Mbit/s sind auch 100Mbit/s… Wobei man hier auf das „Kleingedruckte“ achten muss: Keine zusätzlichen Kosten durch Traffic (bei einem Durchschnittsverbrauch über 40 Mbit/s in einem zusammenhängenden Zeitraum von mindestens 5 Tagen erfolgt eine Umstellung der Anbindung auf 10 Mbit/s).

Zu dem Thema muss ich dann wohl mal eine kleine Auswertung vom Support anfordern. Sollte doch machbar sein, oder?

Ob mich dieses noch ärgert, werde ich herausfinden. Ob mich noch mehr ärgert wird sich zeigen!

Fragen? Einfach melden.

Warum keine Windows Server Sicherung?

Eine gute Frage, oder? Nun ja, man bekommt diese tolle Windows Server Image oder Image Server Sicherung ja kostenlos von Microsoft dazu. Mit ihr lassen sich auch tatsächlich komplette Server sichern. Dieses sogar zuverlässig.

Ich muss aber sicher nicht erwähnen, dass ich im Grunde keine Ahnung von Microsoft Systemen und vor allem der Windows Server Sicherung habe, oder? Egal, mal weiter! Ich wollte ja die Frage beantworten….

Die Windows Server Sicherung kann nicht mit Bandlaufwerken oder ähnlichem umgehen. Natürlich kann man auf einen Netzwerk Share -eine Freigabe- sichern. Da die Sicherung in diesem Fall leider keine Volume Shadow Copy vom Ziel erstellen kann, würde die laufende Sicherung also die bestehende Überschreiben. Bricht die Sicherung als „unvollständig“ ab, hat man nichts mehr.

Volume Shadow Copy…. Weist man der Windows Server Sicherung ein spezielles Backup Volume zu, gibt es der Windows Sicherung die Möglichkeit solche Schattenkopien vom Ziel anzulegen. Man verliert also bei einer unvollständigen Sicherung nicht unbedingt die alten Sicherungen.. Damit sind wir also bei einer im Rechner verbauten Platte, einer externen USB Platte (bis hier eine schlechte Idee) oder auch bei einer ISCSI Platte. Ersteinmal ok, oder? Jain, warum erkläre ich später! Erst noch etwas zu den Schattenkopien. Windows selbst hat natürlich die Möglichkeit einzelne Schattenkopie von seinen Dateien anzulegen. Diese werden sogar noch von der Serversicherung gesichert. So könnte man also nach dem Zurückspielen einer Vollsicherung sogar noch zu einem etwas älteren Stand zurückspringen. Denn noch muss zuerst die Vollsicherung zurückgespielt werden und dann geht es auf einen älteren Stand. Das ist im Falle einer Rücksicherung sehr langwierig. Funktioniert denn noch sehr gut…

Vollsicherung… Die Windows Server Sicherung kann nur Vollsicherungen erstellen, also keine inkrementell oder differentielle Datensicherung. Das bedeutet man muss jeden Tag die kompletten Daten zum Sicherungsziel „pumpen“. Nutzt man nun als Ziel ein intelligentes Storage System wie ein NetApp oder ein ZFS basiertes System (Nexenta, OpenIndiana, Solaris, FreeNas)… Vielleicht noch zusammen mit ISCSI…. dann bringen einem sehr viele der feinen Zusatzfunktionen des Storage Servers kaum noch etwas. Mal angenommen man möchte sein Storage System mit einem anderen abgleichen, dann wird ebenfalls wieder alles kopiert, da sich ja leider immer alles ändert. Dumme Sache das 🙁

Möchte man also seine Sicherung nicht im Unternehmen liegen haben (Feuer / Flugzeug / Wasser / ..) würde so jeden Tag die vollständige Sicherung bewegt werden müssen. Denkt man nun an ein paar TB wird schnell klar, das man sich schon extreme Anbindungen an seinen Standort mieten muss, nur um die Sicherung überhaupt in einem gewissen Zeitfenster aus dem Haus zu bekommen.

Hier kommen dann wieder die etwas teureren Sicherungsprogramme anderer Hersteller ins Spiel .-)

Um es also auf den Punkt zu bringen… Die Windows Server Sicherung funktioniert und hält was sie verspricht, ohne die Möglichkeit einer differentielle Sicherung wird sie denn noch von mir in fast allen Fällen eine Abfuhr bekommen.

Oh ja, sobald es die Möglichkeit einer differentiellen Datensicherung gibt, bitte melden!

Fragen? Einfach melden.

Citrix XenServer local storage größer >2TB

Veraltet: Citrix XenServer wird seit 2024 nicht mehr in dieser Form angeboten. Die Storage-Konfiguration hat sich grundlegend geändert. Alternativen: Proxmox VE oder XCP-ng.

Hat man in seinem Citrix XenServer eine Festplatte welche größer ist als 2 Terabyte, egal ob logisch durch RAID oder physikalisch als echte Hardware. So wird diese vom XenServer nicht vollständig genutzt. Das liegt daran, dass der XenServer noch aufs alte Pferd MBR setzt. Der eingesetzte Kernel kann aber bereits mit GUID Partition Table (GPT) partitionierten Speichern umgehen. Alleine die mitgelieferten Boardmittel (fdisk….) können es auch nicht. Zusammengefasst bedeutet es: –    Ich kann am Citrix XenServer einen lokalen Speicher der größer ist als 2TB einbinden und benutzen. –    Ich kann diesen Speicher aber nicht anlegen 🙁 Damit wäre also nur das Problem des Anlegens zu lösen! Voraussetzung ist dass es sich dabei um eine weitere HDD handelt, also nicht die Platte auf welcher das eigentliche Hostsystem Dom0 installiert wurde. Diesen weitern Speicher schraubt man nun also in seinen XenServer. Nun bootet man diesen mit der Hilfe von Parted Magic. Dieses Livesystem ist darauf ausgelegt mit Platten und Partitionen umzugehen. Daher ist es selbst kein Problem auf ein bereits eingerichtetes Linux Sofwareraid zuzugreifen und es bringt das Programm gparted mit. Gparted wird nun die Hauptarbeit übernehmen, denn es ist schon länger in der Lage GUID Partition Tables (GPT) anzulegen.   Festhalten, es geht los… –    gparted öffnen –    den >2TB Datenspeicher auswählen Cirtix Xen Server local Storage lokaler Speicher bigger 2TB groesser 2TB GUID GPT –    über den Menüpunkt Device den Unterpunkt Create Partition Table auswählen  Cirtix Xen Server local Storage lokaler Speicher bigger 2TB groesser 2TB GUID GPT –    unter Advanced den Type der neuen Partitionstabelle auf gpt setzten und (Warnung beachten) anwenden –    den neuen unallocated Speicher markieren Cirtix Xen Server local Storage lokaler Speicher bigger 2TB groesser 2TB GUID GPT –    über den Menüpunkt Partition den Unterpunkt New auswählen Cirtix Xen Server local Storage lokaler Speicher bigger 2TB groesser 2TB GUID GPT –    nun den File system Type auf lvm2 pv setzten und Hinzufügen Cirtix Xen Server local Storage lokaler Speicher bigger 2TB groesser 2TB GUID GPT –    Abschließend noch diese Änderungen anwenden über den Button Apply Jetzt haben wir eine GUID Partitionstabelle auf der großen Festplatte mit einer Partition größer 2TB und diese bereits mit dem Dateisystem Logical Volume Manager (LVM). Nun können wir wieder den Citrix XenServer booten und ihn mit seinem neuen 3TB oder 4TB oder was weiß ich Storage bekannt machen. Nachdem der XenServer hochgefahren ist melden wir uns als Root auf der Shell an. Um den Speicher nutzbar zu machen genügen nun zwei kleine Befehle:
$ pvcreate /dev/sda1
$ xe sr-create type=lvm content-type=user device-config:device=/dev/sda1 name-label="4TB-SPEICHER"
 Ab jetzt ist der Store wie jeder andere nutzbar.
* U-P-D-A-T-E * Zusammen mit gdisk lassen sich nun auch GPT Partitionen anlegen.

Siehe auch: Citrix XenServer Updates manuell über Bash installieren, XenServer mit Nagios überwachen, XenServer Linux Softwareraid

XenServer Linux Softwareraid

Veraltet: Citrix XenServer wird seit 2024 nicht mehr in dieser Form angeboten. XenServer 8 hat ein anderes Lizenzmodell, Software-RAID wird dort anders gehandhabt. Alternativen: Proxmox VE oder XCP-ng.

Wer die Freie Version des Citrix XenServers einsetzt hat in den meisten Fällen seine virtuellen Maschinen im Local Storage liegen. Natürlich hat ein Hardwareraid für diesen Speicherplatz Vorteile, aber er hat auch Nachteile.
Wie man hier dem XenServer nun einen Local Storage auf der Basis eine Softwarraids unterschieben kann, darum geht es hier!

Alle nötigen Schritte lassen sich direkt auf der Konsole des XenServers ausführen und ist vollständig mit Boardmitteln realisierbar. Die Konfiguration überlebt auch jegliche Updates/Upgrades von der Citrix XenServer Version 5.6 bis 6.1.0.

Wir gehen nun mal davon aus, eine 60GB SSD als Systemplatte für den eigentlichen Citrix XenServer zu haben und ein Softwareraid Level 5 aus drei Festplatten bauen zu wollen.
Damit hätten wir folgende Konfiguration:

/dev/sda    =>    Systemplatte
/dev/sdb    =>    Erste Festplatte RAID
/dev/sdc    =>    Zweite Festplatte RAID
/dev/sdd    =>    Dritte Festplatte RAID

Die für das Softwareraid vorgesehenen Festplatten sollten natürlich keine Daten enthalten und keine Informationen im MBR (Master Boot Record) haben. Diesen löschen wir also zur Sicherheit mit:

$ dd if=/dev/zero of=/dev/sdb bs=1 count=1024
$ dd if=/dev/zero of=/dev/sdc bs=1 count=1024
$ dd if=/dev/zero of=/dev/sdd bs=1 count=1024

Auf den drei Festplatten muss anschließend jeweils eine neue Partition angelegt werden. Diese Partition muss vom Type FD (Linux Raid Autodetect) sein.

$ fdisk /dev/sd[b,c,d]
N => neue Partition
T => Type setzten => FD
W => neue Partitionstabelle auf Platte schreiben
Q => fdisk beenden

Mit diesen vorbereiteten Platten kann nun das eigentliche Softwarraid erstellt werden:

$ mdadm --create /dev/md0 --level=5 --raid-devices=3 /dev/sdb1 /dev/sdc1 /dev/sdd1

Nun heißt es warten bis das Resilvering durchgelaufen ist. Wie weit es fortgeschritten ist lässt sich so beobachten:

$ watch –n 1 'cat /proc/mdstat'

Natürlich können wir jetzt schon auf das neue Softwareraid Laufwerk zugreifen. Ein Reboot sollte man aber erst nach dem ersten korrekten Resilvering durchführen.

Damit nun der Citrix XenServer Kenntnis von diesem neuen Speicherplatz erzählt, müssen wir es ihm noch „schmackhaft“ machen!
Zuerst legen wir auf diesem neuen Laufwerk nun eine Partition vom Type 8E (Linux LVM) an:

$ fdisk /dev/md0
N => neue Partition
T => Type setzten => 8E
W => neue Partitionstabelle auf Platte schreiben
Q => fdisk beenden

Wunderbar. Dann schieben wir es mal dem XenServer unter:

$ mdadm --examine --scan > /etc/mdadm.conf
$ pvcreate /dev/md0p1
$ xe sr-create type=lvm content-type=user device-config:device=/dev/md0p1 name-label="RAID-5"

Fertig…. Nun kann man schon im XenCenter den neuen lokalen Speicher RAID-5 finden und nutzen.

Citrix XenCenter management console showing software RAID

Es ist auch möglich dem Citrix XenServer einen lokalen Storage auf dieser Basis unter zu schiebe, der größer ist als 2TB. Dieses geht leider nicht mehr ganz mit Boardmitteln, da fdisk einfach die nötige Struktur nicht mehr anlegen kann. Der eingesetzte Kernel kann es aber sehr wohl ansprechen und verwalten. Hierzu schreibe ich sich später noch mal was..


* U-P-D-A-T-E *

Zusammen mit gdisk lassen sich nun auch GPT Partitionen anlegen.

Siehe auch: Citrix XenServer Updates manuell über Bash installieren, Citrix XenServer local storage größer >2TB, XenServer mit Nagios überwachen

Local ISO Repository

Veraltet: OpenIndiana und Solaris werden kaum noch eingesetzt. Lokale Paketquellen lassen sich unter FreeBSD mit poudriere und unter Linux mit apt-mirror oder createrepo einrichten.

Citrix XenServer und local ISO Repository

Man kann zwar über das „klickbunit“ Interface XenCenter für seinen einzelnen XenServer neue ISO libarays anlegen, diese können dann leider nur auf einem Windows File Shareing (CIFDS) oder NFS ISO Share liegen. Klar, man könnte nun eine VM auf dem XenServer installieren und dort einen solchen Share anlegen. oder eine Kiste neben den Server stellen, welcher die ISOs vorhält. In größeren Umgebungen kein Problem… Im „Kleinen“ schon mal nervig.

Ich habe für mich eine einfache Lösung gefunden. Ich schraube einfach eine weitere kleine Platte in den Server, lege dort die für mich wichtigen ISOs ab und baue mir eine lokale ISO library. So habe ich die nötigen ISOs immer auf der Kiste, selbst wenn alles andere aus sein sollte.

Also lokalen Speicherplatz für die ISOs habe ich an eine 160GB SATA Platte von WD gedacht. Diese wird nicht gespiegelt oder ähnliches, da die ISO Files für mich erstmal keinen Wert haben. Brennt die Platte wirklich ab, kopiere ich die ISO Files halt auf eine neue.

Nach dem Einbau ist die WD Platte in meinem System als /dev/sde zu finden. Als erstes werde ich nun auf ihr eine primäre Patrion vom Type 83 (Linux) anlegen:

$ fdisk /dev/sde

The number of cylinders for this disk is set to 19457.
There is nothing wrong with that, but this is larger than 1024,
and could in certain setups cause problems with:
1) software that runs at boot time (e.g., old versions of LILO)
2) booting and partitioning software from other OSs
   (e.g., DOS FDISK, OS/2 FDISK)

Command (m for help):

Die Hilfe zu fdisk kann sicher jeder selbst lesen… Ich schaue als erstes über p nach ob ich wirklich auf der richtigen Platte bin, denn p listet mir die Partitionen auf der Platte auf. Dann erstell ich mit n ==> p ==> 1 eine neue primäre Partition und schreibe am Ende alles mit w auf die Platte. q beendet als letztes fdisk.

Nun muss ich die neue Partition noch formatieren. Als Dateisystem finde ich ext3 ganz passend:

$ mkfs.ext3 -L ISO-Store /dev/sde1
mke2fs 1.39 (29-May-2006)
Filesystem label=ISO-Store
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
19546112 inodes, 39072080 blocks
1953604 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=0
1193 block groups
32768 blocks per group, 32768 fragments per group
16384 inodes per group
Superblock backups stored on blocks:
    32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
    4096000, 7962624, 11239424, 20480000, 23887872

Writing inode tables: done                            
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done

This filesystem will be automatically checked every 26 mounts or
180 days, whichever comes first.  Use tune2fs -c or -i to override.

Nun erstelle ich einen Mountpoint unter welchem ich die Platte einbinden möchte:

$ mkdir /ISOs

Schon kann ich die Platte mounten:

$ mount /dev/sde1 /ISOs

Noch schnell eine kontrolle ob alles dort ist wo es hin soll:

$ mount|grep ISO
/dev/sde1 on /ISOs type ext3 (rw)

Mit einem Eintrag in die fstab (ich muss immer aufpassen nicht vfstab zu schreiben) sorge ich nun dafür dass die neue Platte bei jedem Start des Servers wieder eingebunden wird.

$ vi /etc/fstab

und dann folgende Zeile einfügen:

/dev/sde1    /ISOs    ext3    defaults    0 0

Jetzt kommt das wirklich spannende. XEN die neue Platte als localen ISO Speicher schmackhaft zu machen:

$ xe sr-create name-label=ISOs type=iso device-config:legacy_mode=true device-config:location=/ISOs content-type=iso
00da02b3-8b46-bade-6d00-e109e262ede9

Schaut doch schon gut aus, oder? Dann lassen wir uns mal die neue ISO library anzeigen:

$ xe sr-list uuid=00da02b3-8b46-bade-6d00-e109e262ede9
uuid ( RO)                : 00da02b3-8b46-bade-6d00-e109e262ede9
          name-label ( RW): ISOs
    name-description ( RW):
                host ( RO): xenserver01-kernel-error.local
                type ( RO): iso
        content-type ( RO): iso

Warum auch immer, wird die Platte bei mir an diesem Punkt immer ausgehangen. Ich könnte es jetzt einfach wieder mounten und nutzen, würde denn noch vorschlagen hier den Server selbst einmal zu rebooten. So kann man gleich sehen ob die Platte wieder richtig eingebunden wird. Nach dem Reboot schaue ich also nach ob die Platte wieder richtig eingehangen wurde:

$ mount|grep ISO/dev/sde1 on /ISOs type ext3 (rw)

Jetzt kopiere ich das nötige ISO auf die Platte:

scp WindowsSvrStd2008R2.iso root@10.44.2.88:/ISOs
WindowsSvrStd2008R2. 100% |******************************************************************************************************************************************************************************************|  3052 MB    01:28

Im XenCenter sollte man nun schon das neue SR mit dem Namen „ISOs“ sehen. Klicke man nun am Reiter Storage auf Rescan wird das hochgeladene ISO gefunden und kann verwendet werden. Ich muss nun also nur noch alle meine ISOs dort hochschieben und fertig ist!

Citrix XenCenter SR local ISO library

Siehe auch: Citrix XenServer Updates manuell über Bash installieren, Citrix XenServer local storage größer >2TB, XenServer mit Nagios überwachen, XenServer Linux Softwareraid

« Ältere Beiträge

© 2026 -=Kernel-Error=-RSS

Theme von Anders NorénHoch ↑