Storage, Backup und Restore in meinem Kubernetes-Cluster

Hallo zusammen! Nachdem wir uns im letzten Beitrag mit Ingress und Load Balancer beschäftigt haben, möchte ich heute über Storage, Backup und Restore schreiben. In meinem Kubernetes-Cluster verwende ich Longhorn für das Storage-Management und k8up zusammen mit rclone und Restic für Backup und Restore. Hier zeige ich euch, wie ich diese Komponenten in meinem Setup integriert habe.

Storage mit Longhorn

Warum Longhorn?

Für das Storage-Management habe ich mich für Longhorn entschieden, weil es eine einfache und robuste Lösung bietet. Im Gegensatz zu komplexeren Systemen wie Ceph ist Longhorn leichter zu konfigurieren und zu verwalten. Das von k3s mitgelieferte local-path-storage funktioniert nicht gut, wenn man Pods über mehrere Nodes betreiben möchte. Longhorn ermöglicht es mir, eine zusätzliche SSD in meinen k3s-Nodes zu nutzen und bietet eine bessere Verteilung und Verwaltung der Daten.

Installation und Konfiguration von Longhorn

Die Installation von Longhorn erfolgt über FluxCD. Hier ist ein Beispiel, wie die Konfiguration aussehen könnte:

<code>apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
  name: longhorn
  namespace: longhorn-system
spec:
  chart:
    spec:
      chart: longhorn
      version: "1.2.3"
      sourceRef:
        kind: HelmRepository
        name: longhorn
        namespace: flux-system
  values: {}
</code>
Code-Sprache: HTML, XML (xml)

Verwaltung von Longhorn

Es hat mich überrascht, dass Longhorn allein schon ca. 30 Pods in meinem System laufen lässt. Diese Pods sind notwendig, um die Verteilung und Redundanz der Daten sicherzustellen und die Integrität des Storage-Systems zu gewährleisten.

Festplatten müssen auf dem System formartiert und gemounted werden. Danach kann man sie in das System von Longhorn bequem über das Webinterface einbinden.

Das Webinterface habe ich mit dem oauth2-Proxy (kommt später) verbunden und im Cluster veröffentlicht. Für meine Zwecke reicht die default storage class, die ich ebenfalls im HelmRelease definiert habe:

    persistence:
      # -- Setting that allows you to specify the default Longhorn StorageClass.
      defaultClass: true
      # -- Filesystem type of the default Longhorn StorageClass.
      defaultFsType: ext4
      # -- mkfs parameters of the default Longhorn StorageClass.
      defaultMkfsParams: ""
      # -- Replica count of the default Longhorn StorageClass.
      defaultClassReplicaCount: 2
      # -- Data locality of the default Longhorn StorageClass. (Options: "disabled", "best-effort")
      defaultDataLocality: disabled
      # -- Reclaim policy that provides instructions for handling of a volume after its claim is released. (Options: "Retain", "Delete")
      reclaimPolicy: Delete
      # -- Setting that allows you to enable live migration of a Longhorn volume from one node to another.
      migratable: false
      # -- Set NFS mount options for Longhorn StorageClass for RWX volumes
      nfsOptions: ""
      recurringJobSelector:
        # -- Setting that allows you to enable the recurring job selector for a Longhorn StorageClass.
        enable: false
        # -- Recurring job selector for a Longhorn StorageClass. Ensure that quotes are used correctly when specifying job parameters. (Example: `[{"name":"backup", "isGroup":true}]`)
        jobList: []

Code-Sprache: PHP (php)

Backup und Restore mit k8up und Restic

Warum k8up und Restic?

Für die Datensicherung setze ich auf k8up in Kombination mit rclone und Restic. Diese Tools ermöglichen eine flexible und zuverlässige Backup-Lösung. Die Backups speichere ich auf einer Storagebox von Hetzner, und rclone konfiguriere ich mit SFTP, um die Daten dorthin zu übertragen.

Installation und Konfiguration von k8up

Hier ist ein Beispiel, wie die Konfiguration für k8up in meinem Git-Repository aussieht:

<code>apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
  name: k8up
  namespace: k8up
spec:
  chart:
    spec:
      chart: k8up
      version: "1.0.0"
      sourceRef:
        kind: HelmRepository
        name: k8up
        namespace: flux-system
  values: {}
</code>
Code-Sprache: HTML, XML (xml)

Konfiguration von rclone mit SFTP

Die Konfiguration von rclone für den Zugriff auf die Hetzner Storagebox erfolgt über ein Secret in Kubernetes:

kind: Secret
metadata:
  name: rclone-config
  namespace: k8up
stringData:
  rclone.conf: |
[hetzner]
type = sftp host = &lt;hetzner-storagebox-host&gt; user = &lt;username&gt; pass = &lt;password&gt; key_file = /root/.ssh/id_rsaCode-Sprache: HTML, XML (xml)

Backup von PVCs mit k8up und Restic

Um ein PVC ins Backup aufzunehmen, kann man eine Annotation hinzufügen:

<code>apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: example-pvc
  namespace: default
  annotations:
    k8up.io/backup: "true"
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
</code>Code-Sprache: HTML, XML (xml)

Zusätzlich muss ein Backup-Schedule definiert werden:

apiVersion: k8up.io/v1
kind: Schedule
metadata:
  name: example-backup-schedule
  namespace: example
spec:
  backend:
    rest:
      url: http://rclone.backup.svc.cluster.local:50001/backup
    repoPasswordSecretRef:
      name: restic-credentials
      key: repo-key
  backup:
    schedule: '@daily-random' # damit nicht alle Backups zur gleichen Zeit starten
    failedJobsHistoryLimit: 2
    successfulJobsHistoryLimit: 2
  check:
    schedule: '0 1 * * 1' # 01:00 on Monday
    failedJobsHistoryLimit: 2
    successfulJobsHistoryLimit: 2
  prune:
    schedule: '0 1 * * 0' # 00:00 on Monday
    failedJobsHistoryLimit: 2
    successfulJobsHistoryLimit: 2
    retention:
      keepLast: 3
      keepDaily: 7
      keepWeekly: 5
      keepMonthly: 12

Mit diesem Schedule läuft einmal am Tag ein Backup. Einmal pro Woche werden die Backups überprüft und aufgeräumt.

Backup von Datenbanken

Einfachere Datenbank-Backups können per PodAnnotation festgelegt werden. Hier ist ein Beispiel für ein MongoDB-Backup:

<code>  annotations:
    k8up.io/backupcommand: sh -c 'mongodump --username=$MONGODB_ROOT_USER --password=$MONGODB_ROOT_PASSWORD --archive'
    k8up.io/file-extension: .archiv</code>Code-Sprache: HTML, XML (xml)

Das konfiguriere ich natürlich in den values für die MongoDB. Der Start wird durch den Backupschedule gesteuert und erzeugt ein Dump der Datenbank. Dieser Dump wird nun ins Backupsystem hochgeladen.

Fazit

Mit Longhorn habe ich eine zuverlässige und einfach zu verwaltende Storage-Lösung für meinen Kubernetes-Cluster gefunden. Die Kombination aus k8up, rclone und Restic ermöglicht es mir, flexible und zuverlässige Backups meiner Daten zu erstellen und im Notfall wiederherzustellen. Diese Lösungen bieten eine solide Grundlage für die Speicherung und Sicherung meiner Daten in einem Heim-Kubernetes-Cluster.

Bleibt dran, um mehr über die fortgeschrittene Nutzung von Kubernetes und die Verwaltung von Heimnetzwerken zu erfahren!

Weitere Blogposts aus der k3s-Reihe

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert