Skip to content

Datenbanken ​

Datenbanken legst du als Custom Resource in deinem Namespace an. Die Operatoren laufen bereits im Cluster, du musst nichts installieren.

PostgreSQL (CloudNativePG) ​

Gruppe und Version: postgresql.cnpg.io/v1, Kind Cluster.

yaml
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: app-db
spec:
  instances: 3
  storage:
    size: 10Gi
    storageClass: hcloud-volumes

Eine Instanz ohne Backup ist kein Produktionsbetrieb

Ein Cluster mit instances: 1 und ohne konfiguriertes Backup ist ein Ausgangspunkt zum Ausprobieren. Für den Produktivbetrieb nimm instances: 3 und richte ein Backup-Ziel ein. Das Volume auf hcloud-volumes ist über das Netz angebunden und übersteht den Ausfall eines Knotens, aber mit einer Instanz ist die Datenbank nicht erreichbar, bis das Volume an einem anderen Knoten hängt und der Pod dort gestartet ist. Ohne Backup-Ziel gibt es keine Wiederherstellung auf einen bestimmten Zeitpunkt und nichts Konsistentes, aus dem du zurückholen kannst, wenn Daten gelöscht oder beschädigt werden oder das Volume selbst verloren geht.

Wird sein Knoten ersetzt, startet ein Cluster mit instances: 1 samt Volume auf einem anderen Knoten neu und ist bis dahin nicht erreichbar. Behält der Cluster sein PodDisruptionBudget (die Voreinstellung), setzt die Plattform für diese Zeit spec.nodeMaintenanceWindow am Cluster und entfernt das Feld danach wieder. Mit zwei oder mehr Instanzen wechselt der Primary vorher auf eine andere Instanz.

In einen PostgreSQL-Pod kommst du nicht per Shell ​

kubectl exec in einen CloudNativePG-Pod wird abgelehnt:

text
Error from server: admission webhook denied the request:
Exec/attach is only allowed into gVisor-sandboxed pods.

Deine eigenen Workloads laufen sandboxed und akzeptieren exec ganz normal. PostgreSQL-Pods sind die Ausnahme, das betrifft also nur PostgreSQL. In MariaDB- und Dragonfly-Pods kommst du wie überall sonst hinein.

kubectl port-forward ist davon nicht betroffen. Der übliche Weg, SQL gegen deine eigene Datenbank auszuführen, ist deshalb: Port weiterleiten und mit einem lokalen Client verbinden, mit den Zugangsdaten, die der Operator erzeugt hat. Ein kurzlebiger psql-Pod im Namespace funktioniert genauso.

MariaDB (mariadb-operator) ​

Gruppe: k8s.mariadb.com, Kind MariaDB.

yaml
apiVersion: k8s.mariadb.com/v1alpha1
kind: MariaDB
metadata:
  name: app-db
spec:
  rootPasswordSecretKeyRef:
    name: app-db-root
    key: password
  storage:
    size: 10Gi
    storageClassName: hcloud-volumes

Dragonfly ​

Gruppe und Version: dragonflydb.io/v1alpha1, Kind Dragonfly.

yaml
apiVersion: dragonflydb.io/v1alpha1
kind: Dragonfly
metadata:
  name: cache
spec:
  replicas: 2

Erreichbar ist die Instanz unter redis://<name>:6379, im Beispiel oben also redis://cache:6379.

Dragonfly spricht das Redis-Wire-Protokoll, die meisten Clients funktionieren deshalb ohne Anpassung. Es gibt allerdings dokumentierte Unterschiede im Verhalten einzelner Befehle. Teste deine Anwendung, bevor du eine bestehende Redis-Instanz ablöst.

Backups ​

PostgreSQL und MariaDB können sich beide planmäßig sichern, in einen Bucket, der dir gehört. Ein Bucket wird nicht gestellt, das hier ist also etwas, das du einrichtest, und nichts, was du geerbt bekommst.

Wohin Backups gehen ​

Überallhin, wo S3 gesprochen wird. ITSH Object Storage funktioniert und ist der einfachste Weg: Leg einen Bucket und einen Zugangsschlüssel an und pack den Schlüssel in ein Secret in deinem Namespace.

Gib dem Schlüssel Lesen und Schreiben auf diesen Bucket. CloudNativePG listet den Bucket für seinen Backup-Katalog und löscht alte Backups, um die retentionPolicy durchzusetzen, und beides darf Nur Schreiben nicht.

bash
kubectl create secret generic backup-creds \
  --from-literal=ACCESS_KEY_ID='<access-key>' \
  --from-literal=ACCESS_SECRET_KEY='<secret-key>'

PostgreSQL ​

Trag ein Backup-Ziel am Cluster ein und plane es dann:

yaml
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: app-db
spec:
  instances: 3
  storage:
    size: 10Gi
    storageClass: hcloud-volumes
  backup:
    barmanObjectStore:
      destinationPath: "s3://my-backups/app-db"
      endpointURL: "https://storage.itsh.dev"
      s3Credentials:
        accessKeyId:
          name: backup-creds
          key: ACCESS_KEY_ID
        secretAccessKey:
          name: backup-creds
          key: ACCESS_SECRET_KEY
    retentionPolicy: "30d"
---
apiVersion: postgresql.cnpg.io/v1
kind: ScheduledBackup
metadata:
  name: app-db-daily
spec:
  schedule: "0 0 3 * * *"
  cluster:
    name: app-db

Der Zeitplan ist ein sechsstelliger Cron-Ausdruck, Sekunden zuerst. Das Beispiel läuft also täglich um 03:00 Uhr.

barmanObjectStore gibt eine Deprecation-Warnung aus

Beim Anwenden erfährst du, dass das Feld veraltet ist. CloudNativePG hat es in 1.26 so markiert, entfernt werden soll es in 1.31. Das ist erwartet: Es ist der Weg, auf dieser Plattform Backups zu konfigurieren, und das Barman Cloud Plugin, das es upstream ablöst, ist hier nicht installiert. Nutz es. Sobald das Plugin verfügbar ist, ist die Migration eine Änderung am laufenden Cluster, und deine bestehenden Backups bleiben lesbar.

MariaDB ​

Backup- und Restore-Ressourcen funktionieren genauso und nehmen entweder ein S3-Ziel oder ein PVC. Der Feldaufbau steht in der Dokumentation des mariadb-operator.

Zwei Grenzen, die du kennen solltest ​

Object Versioning, Lifecycle-Regeln und Object-Lock gibt es bei ITSH Object Storage nicht. Backups lassen sich hier also nicht unveränderlich machen: Wer in den Bucket schreiben darf, kann sie auch löschen.

Gib Backups einen eigenen Bucket und einen darauf beschränkten Zugangsschlüssel, und halt diesen Schlüssel aus Workloads heraus, die ihn nicht brauchen. Sind unveränderliche Backups für dich zwingend, sprich vorher mit dem Support, bevor du dich auf dieses Setup verlässt.

Volume-Snapshots und Point-in-Time-Wiederherstellung von Volumes gibt es nicht. Backups laufen auf Datenbankebene und werden vom Operator erstellt. Für ein PVC, das keine verwaltete Datenbank ist, gibt es kein Äquivalent. Was dir in einem einfachen Volume wichtig ist, braucht also eine eigene Kopie woanders.

Teste die Wiederherstellung ​

Ein Backup, das nie jemand zurückgespielt hat, ist eine Vermutung. Spiel es einmal in einen Wegwerf-Cluster zurück, bevor du es brauchst, und prüf, ob die Daten wirklich da sind.

Wie es weitergeht ​