Storage

Überblick

Der Cluster home-tamay-cloud verwendet Piraeus Datastore mit LINSTOR und DRBD.

Die ursprüngliche Implementierung basierte auf ZFS Thin Pools. Im praktischen Betrieb hat sich diese Lösung auf Consumer-Hardware jedoch als ungeeignet erwiesen.

Die aktuelle Storage-Plattform basiert auf LVM Thin Pools und einer Trennung von Datenspeicher und DRBD-Metadaten.

Storage Stack:

  • Piraeus Datastore

  • LINSTOR

  • DRBD

  • LVM Thin

  • NVMe für schnelle Volumes und DRBD Metadaten

  • SATA SSDs für Kapazitäts-Storage

Erfahrungen mit Consumer SSDs

Die verwendeten Patriot P220 SSDs sind günstige Consumer-SSDs ohne DRAM Cache.

Eigenschaften:

  • Geringe Schreibperformance unter Last

  • Keine optimale Eignung für dauerhafte Replikation

  • Starke Performanceeinbrüche bei zufälligen Schreibzugriffen

Zusätzlich erzeugt DRBD aufgrund der synchronen Replikation deutlich mehr IO als lokale Speicherlösungen.

Probleme mit ZFS

Die ursprüngliche Plattform verwendete ZFS Thin Pools als LINSTOR Backend.

Im Betrieb wurden folgende Nachteile beobachtet:

  • Copy-on-Write erzeugt zusätzliche Schreibvorgänge

  • Höhere Metadatenlast

  • Zusätzliche IO durch DRBD

Besonders problematisch waren SQLite-Datenbanken.

SQLite arbeitet typischerweise mit kleinen Blockgrößen, während ZFS größere Blöcke verwendet. Dadurch entstehen:

  • Read-Modify-Write Zyklen

  • Sehr hohe Write Amplification

Die Kombination aus:

  • Consumer SSD

  • ZFS

  • DRBD

  • SQLite

führte zu deutlich mehr Schreiblast als erwartet.

Talos Storage Layout

Talos reserviert auf jeder Node separate Raw Volumes für LINSTOR.

Verwendet wird RawVolumeConfig, was Partitionen auf der Talos SystemDisk erzeugt. Diese Partitionen werden als BlockDevice von LINSTOR vzur Provisionierung von LVM Thinpools verwendet.

  • linstor dient als schnellen nvme Storage im Cluster. Er ist begrenzt und wird daher nur für workload verwendet, die das benötigt.

  • linstor-metadata wird als DRBD Metadaten Pool für Volumes verwendet, die auf der SATA Festplatte erzeugt werden

apiVersion: v1alpha1
kind: RawVolumeConfig
name: linstor
provisioning:
  diskSelector:
    match: disk.transport == 'nvme'
  minSize: 40GiB
  maxSize: 100GiB
apiVersion: v1alpha1
kind: RawVolumeConfig
name: linstor-metadata
provisioning:
  diskSelector:
    match: disk.transport == 'nvme'
  minSize: 10GiB
  maxSize: 20GiB

Ziele:

  • Trennung vom Talos Systemvolume

  • Nutzung schneller NVMe Medien

  • Separater Bereich für DRBD Metadaten

Die von Talos erzeugten Partitionen werden anschließend durch LINSTOR verwendet.

LINSTOR Storage Pools

Der Cluster verwendet mehrere Storage Pools.

SATA Pool

Kapazitätsorientierter Storage auf SATA SSDs.

Storage Pool: lvm-thinpool-1
Volume Group: vg_linstor_sata
Thin Pool: thinpool_linstor
Device: /dev/sda

Eigenschaften:

  • Größere Kapazität

  • Günstiger Speicher

  • Standardpool für replizierte Volumes

NVMe Pool

Performanter Storage auf NVMe.

Storage Pool: lvm-thinpool-nvme
Volume Group: vg_linstor_nvme
Thin Pool: thinpool_linstor_nvme
Device: /dev/nvme0n1p5

Eigenschaften:

  • Niedrige Latenz

  • Hohe IOPS

  • Geeignet für Datenbanken und Performance-Workloads

DRBD Metadata Pool

Separater Pool ausschließlich für DRBD Metadaten.

Storage Pool: lvm-metadata
Volume Group: vg_linstor_nvme
Device: /dev/nvme0n1p6

Eigenschaften:

  • Speicherung der DRBD Metadaten

  • Verwendung schneller NVMe Medien

  • Entlastung der eigentlichen Datenlaufwerke

Trennung der DRBD Metadaten

DRBD Metadaten werden bewusst getrennt von den Nutzdaten gespeichert.

Gründe:

  • Geringere IO-Konkurrenz

  • Schnellere Statusupdates

  • Schnellere Resynchronisierung

  • Geringere Latenz bei Replikationsoperationen

Die Storage Classes linstor-r02 und linstor-r03 konfigurieren dafür einen dedizierten DRBD Metadata Pool.

property.linstor.csi.linbit.com/StorPoolNameDrbdMeta: "lvm-metadata"

Storage Pool Einschränkungen

Ein physisches Blockdevice kann nur einem Storage Pool zugeordnet werden.

Nicht möglich:

/dev/nvme0n1p5

├─ lvm-thinpool-nvme
└─ lvm-metadata

Ein Device darf niemals gleichzeitig mehreren LINSTOR Storage Pools zugewiesen werden.

Deshalb werden für Datenspeicher und DRBD Metadaten unterschiedliche Partitionen verwendet.

Beispiel:

/dev/nvme0n1p5 -> lvm-thinpool-nvme
/dev/nvme0n1p6 -> lvm-metadata

Storage Klassen

linstor-local

Lokaler Storage ohne DRBD.

Eigenschaften:

  • Keine Replikation

  • Maximale Performance

  • Geringste Schreiblast

Geeignet für:

  • CloudNativePG

  • Garage Data

  • Dragonfly

  • Anwendungen mit eigener Replikation

Da diese Anwendungen bereits selbst replizieren, entsteht kein zusätzlicher Mehrwert durch DRBD.

linstor-r02

Synchron replizierter Storage auf zwei Nodes.

Eigenschaften:

  • Zwei Datenkopien

  • DRBD Replikation

  • Dedizierte DRBD Metadaten

Geeignet für:

  • Stateful Anwendungen ohne eigene Replikation

  • Kritische Konfigurationsdaten

linstor-r03

Synchron replizierter Storage auf drei Nodes.

Eigenschaften:

  • Drei Datenkopien

  • Maximale Verfügbarkeit

  • Höchster Storageverbrauch

Geeignet für:

  • Besonders kritische Datenbestände

NVMe Varianten

Zusätzlich existieren folgende Klassen:

  • linstor-local-nvme

  • linstor-r02-nvme

  • linstor-r03-nvme

Diese verwenden den NVMe Storage Pool als Datenbackend.

Architekturprinzipien

  • Replikation nur wenn sie echten Mehrwert liefert

  • Anwendungen mit eigener Replikation verwenden bevorzugt linstor-local

  • DRBD Metadaten werden getrennt gespeichert

  • NVMe wird für Performance und Metadaten verwendet

  • SATA SSDs dienen primär als Kapazitätsspeicher

  • ZFS wird nicht mehr für produktive LINSTOR Volumes verwendet

Snapshots

Verwendete Snapshot Klasse:

linstor-snapshot1

Verwendung:

  • Backup

  • Wiederherstellung

  • PVC Migrationen

Eigenschaften

  • Dediziertes Storage Netzwerk

  • DRBD Replikation

  • CSI Snapshots

  • VolumeGroupSnapshots

  • Offsite Backup

Backup

Komponenten:

  • Velero

  • CloudNativePG

  • Hetzner Object Storage

Dediziertes Netzwerk für DRBD Replikation

Jeder Node hat eine 2te NIC, die für die Datenreplikation gedacht ist.

Damit Linstor diese NICs verwendet, statt dem default Podnetzwerk, müssen dem Linstor Controller die Node Interfaces und die Node Connection bekannt gemacht werden.

Node Connection

Die Node Connection kann über die Values des linstor-cluster HelmChart konfiguriert werden:

linstorNodeConnections:
  - name: replication-v6
    paths:
      - interface: cluster-v6
        name: replication-v6

Der Name des Interfaces (hier replication-v6) muss nicht mit dem tatsächlichen Namen der NIC (z.B. enp2s0) übereinstimmen. Linstor wählt das Interface anhand der später konfigurierten IP Adresse automatisch aus.

Node Interface

Das Node Interface lässt sich leider aktuell weder im HelmChart noch als CRD definieren. Daher muss das einmalig für jeden Node angelegt werden.

kubectl -n piraeus-datastore exec -it deployments/linstor-controller -- linstor node interface create k8s-home-01 cluster-v6 fde4:079d:3b73::21
kubectl -n piraeus-datastore exec -it deployments/linstor-controller -- linstor node interface create k8s-home-02 cluster-v6 fde4:079d:3b73::22
kubectl -n piraeus-datastore exec -it deployments/linstor-controller -- linstor node interface create k8s-home-03 cluster-v6 fde4:079d:3b73::23
$ kubectl -n piraeus-datastore exec deployments/linstor-controller -- linstor node interface list k8s-home-01
╭─────────────────────────────────────────────────────────────────────────╮
│ k8s-home-01 │ NetInterface │ IP                 │ Port │ EncryptionType │
╞═════════════════════════════════════════════════════════════════════════╡
│ +           │ cluster-v6   │ FDE4:079D:3B73::21 │      │                │
│ + StltCon   │ default-ipv6 │ FDC8:8E7B:9ADE::21 │ 3367 │ SSL            │