Einleitung
StatefulSets sind eine leistungsstarke Kubernetes-Ressource für den Betrieb zustandsbehafteter Anwendungen. Sie sind allerdings auch komplex und nur schwer zu sichern – und ein Ausfall kann schnell zu Datenverlust führen.
2022 hat Google ein neues Add-on für GKE vorgestellt: Backup for GKE. Damit lassen sich containerisierte Anwendungen und Daten auf einfache, cloud-native Weise schützen, verwalten und wiederherstellen.
In diesem Artikel schauen wir uns die Komponenten von Backup for GKE an und zeigen, wie Sie Volumes eines MySQL-StatefulSets sichern, das in einem GKE-Cluster läuft.
Architektur
Backup for GKE besteht aus zwei Hauptkomponenten:
- Einem Service, der in Google Cloud läuft und eine ressourcenbasierte REST-API bereitstellt. Dieser Service ist die Control Plane für Backup for GKE und umfasst UI-Elemente in der Google Cloud Console, die mit der API interagieren.
- Einem Agent, der in jedem Cluster läuft, in dem Backups oder Restores ausgeführt werden. Der Agent wickelt Backup- und Restore-Vorgänge in diesen Clustern über die Backup-for-GKE-API ab.
Backup for GKE ist in die GKE-UI, die Google Cloud CLI und die REST-APIs integriert und sorgt damit für konsistente Workflows in Entwicklung und Betrieb. Ein Backup erfasst zwei Arten von Daten:
- Config Backup: eine Sammlung von Kubernetes-Ressourcen-Manifesten, die aus dem API-Server des zu sichernden Clusters extrahiert werden und dessen Zustand abbilden.
- Volume Backups: Volume-Sicherungen, die zu den im Config Backup enthaltenen
PersistentVolumeClaim-Ressourcen gehören.
Sie entscheiden, welche Workloads gesichert oder wiederhergestellt werden sollen – einzeln oder alle auf einmal. Workloads lassen sich aus einem Cluster sichern und in einem anderen wiederherstellen. Per Zeitplan laufen Backups automatisch, sodass Sie im Ernstfall schnell reagieren und Ihre Workloads wiederherstellen können.
Schritt für Schritt
In den nächsten Schritten legen wir einen zonalen GKE-Cluster an, deployen ein MySQL-StatefulSet hinein und testen sowohl die Erstellung des Backups als auch die Wiederherstellung unserer Datenbank.
Variablen definieren
Der Einfachheit halber legen wir zunächst ein paar Umgebungsvariablen an:
export PROJECT_ID=felipe-playground-378415
export REGION=us-east1
export LOCATION=us-east1-c
export CLUSTER=backup-for-gke
export BK_PLAN_ALL_NAMESPACES=mysql-bk-plan-all-ns
export RESTORE_PLAN_ALL_NAMESPACES=mysql-bk-plan-all-ns
export BK_ALL_NAMESPACES=mysql-bk-all-namespaces
export RESTORE_ALL_NAMESPACES=mysql-restore-all-namespaces
GKE-Cluster erstellen
Setzen wir ein paar Variablen, um die Befehle übersichtlich zu halten. Tragen Sie hier Ihre eigene PROJECT_ID ein. Für diese Übung erstellen wir einen zonalen GKE-Cluster in der Zone us-east1-c. Ein zonaler Cluster hat eine einzige Control Plane in einer einzelnen Zone. Für produktive Workloads empfehle ich allerdings regionale Cluster, da sie mehrere Control-Plane-Replikate über mehrere Zonen einer Region verteilen und so eine höhere Verfügbarkeit bieten. Außerdem nutzen wir hier alle Standardwerte – Standard-VPC und -Subnetze, Anzahl der Nodes, Default-Service-Account usw. Für Produktions-Cluster ist davon abzuraten.
Ergänzen Sie unbedingt das Flag --addons=BackupRestore, damit auch die Backup-Controller und sämtliche CRDs deployed werden.
gcloud container clusters create ${CLUSTER} \
--release-channel stable \
--zone ${LOCATION} \
--node-locations ${LOCATION} \
--project ${PROJECT_ID} \
--addons=BackupRestore
Nun verbinden wir uns mit dem Cluster:
gcloud container clusters get-credentials ${CLUSTER} \
--zone ${LOCATION} \
--project ${PROJECT_ID}
StatefulSet installieren
Jetzt legen wir unser StatefulSet an. Für diese Übung habe ich den MySQL Operator gewählt, der sich per Helm unkompliziert installieren lässt.
helm repo add mysql-operator https://mysql.github.io/mysql-operator/
helm repo update
helm install my-mysql-operator mysql-operator/mysql-operator \
--namespace mysql-operator --create-namespace
MySQL installieren
Installieren Sie MySQL via Helm – und denken Sie daran, das Passwort zu ändern!
helm install mycluster mysql-operator/mysql-innodbcluster \
--set tls.useSelfSigned=true \
--set credentials.root.user=safeuser \
--set credentials.root.password=notsupersafepassword \
--set credentials.root.host="%"
Mit dem Befehl kubectl get pods,pvc sollten Sie in etwa folgende Ausgabe sehen:
NAME READY STATUS RESTARTS AGE
pod/mycluster-0 2/2 Running 0 23m
pod/mycluster-1 2/2 Running 0 23m
pod/mycluster-2 2/2 Running 0 23m
pod/mycluster-router-67585969f6-m9nd7 1/1 Running 0 22m
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
persistentvolumeclaim/datadir-mycluster-0 Bound pvc-d5214172-9b81-4d29-9bf0-9e0dcdc8f691 2Gi RWO standard-rwo 23m
persistentvolumeclaim/datadir-mycluster-1 Bound pvc-df8e188a-51aa-4c4f-acb1-73daa72bc721 2Gi RWO standard-rwo 23m
persistentvolumeclaim/datadir-mycluster-2 Bound pvc-defb5e6e-5946-4183-99d2-c168b05a3d6c 2Gi RWO standard-rwo 23m
Perfekt! Im nächsten Schritt richten wir die Backup-for-GKE-Ressourcen für unseren Cluster ein.
Backup for GKE kennt zwei Konfigurations- und Steuerungsressourcen:
BackupPlan: eine übergeordnete Ressource fürBackup-Ressourcen, die eine Kette von Backups bündelt. Sie enthält die Backup-Konfiguration – also Quellcluster, Auswahl der zu sichernden Workloads sowie die Region, in der dieBackup-Artefakte aus diesem Plan abgelegt werden.RestorePlan: liefert eine wiederverwendbare Restore-Vorlage. Sie enthält die Restore-Konfiguration mit Zielcluster, zugrundeliegendem Backup-Plan, Restore-Umfang, Konfliktbehandlung und Substitutionsregeln.
Backup-Plan für alle Namespaces erstellen
gcloud beta container backup-restore backup-plans create ${BK_PLAN_ALL_NAMESPACES} \
--project=${PROJECT_ID} \
--location=${REGION} \
--cluster=projects/${PROJECT_ID}/locations/${LOCATION}/clusters/${CLUSTER} \
--all-namespaces \
--include-secrets \
--include-volume-data
Restore-Plan für alle Namespaces erstellen
gcloud beta container backup-restore restore-plans create ${RESTORE_PLAN_ALL_NAMESPACES}\
--all-namespaces \
--project=${PROJECT_ID} \
--location=${REGION} \
--backup-plan=projects/${PROJECT_ID}/locations/${REGION}/backupPlans/${BK_PLAN_ALL_NAMESPACES} \
--cluster=projects/${PROJECT_ID}/locations/${LOCATION}/clusters/${CLUSTER} \
--cluster-resource-conflict-policy=use-existing-version \
--namespaced-resource-restore-mode=delete-and-restore \
--volume-data-restore-policy=restore-volume-data-from-backup \
--cluster-resource-restore-scope="storage.k8s.io/StorageClass","scheduling.k8s.io/PriorityClass"
Wenn die Befehle oben erfolgreich durchgelaufen sind, stehen alle Pläne bereit.
Backup für alle Namespaces erstellen
gcloud beta container backup-restore backups create ${BK_ALL_NAMESPACES} \
--project=${PROJECT_ID} \
--location=${REGION} \
--backup-plan=${BK_PLAN_ALL_NAMESPACES} \
--wait-for-completion
Je nach Größe Ihrer Volumes kann das eine Weile dauern. Sobald der Vorgang abgeschlossen ist, erscheint folgende Meldung:
Backup completed. Backup state: SUCCEEDED
Wiederherstellung testen
gcloud beta container backup-restore restores create ${RESTORE_ALL_NAMESPACES} \
--project=${PROJECT_ID} \
--location=${REGION} \
--restore-plan=${RESTORE_PLAN_ALL_NAMESPACES} \
--backup=projects/$PROJECT_ID/locations/${REGION}/backupPlans/${BK_PLAN_ALL_NAMESPACES}/backups/${BK_ALL_NAMESPACES} \
--wait-for-completion
Restore Completed. Restore stat: SUCCEEDED
Läuft!
Mit Backup for GKE können Sie auch ein einzelnes Anwendungs-Bundle sichern, das über die CRD ProtectedApplication erstellt wurde – das ist aber Stoff für einen weiteren Beitrag.
IaC
Aktuell (Juni 2023) gibt es nur eine Terraform-Ressource zum Anlegen eines GKE-Backup-Plans: google_gke_backup_backup_plan, eingeführt mit Version 4.5.0 des Google Providers, nachzulesen hier. Weitere Ressourcen werden hoffentlich bald folgen.
Preise
Backup for GKE verursacht Kosten in zwei Dimensionen: zum einen eine Management-Gebühr, die sich an der Anzahl der geschützten GKE-Pods bemisst, zum anderen eine Speichergebühr, die auf der gesicherten Datenmenge (in GB) basiert. Beide Gebühren werden monatlich abgerechnet, wie bei anderen GKE-Features auch.
Ein Beispiel: Ein Kunde mit einem einzelnen Backup-Plan in Iowa (us-central1), der pro Monat im Schnitt 20 Pods sichert und dabei 200 GB an Backup-Daten in Iowa speichert, zahlt 25,60 $. Davon entfallen 20 $ auf das GKE-Backup-Management (20 × 1,00 $ pro Pod und Monat) und 5,60 $ auf den Backup-Speicher (200 × 0,028 $ pro GB und Monat).
Ab dem 26. Juni 2023 kommen zusätzlich Network-Egress-Gebühren für Backups hinzu, die in einer anderen Region als der GKE-Quellcluster gespeichert werden. Diese Gebühren richten sich nach Quell- und Zielregion sowie der Datenmenge, die bei jedem solchen "regionsübergreifenden" Backup-Vorgang übertragen wird.
Aufräumen
Cluster löschen:
gcloud container clusters delete ${CLUSTER} --project $PROJECT_ID --zone ${LOCATION}
Vergessen Sie nicht, auch die Backups und Pläne zu entfernen.
# Backup löschen
gcloud beta container backup-restore backups delete ${BK_ALL_NAMESPACES} \
--location=${REGION} \
--backup-plan=${BK_PLAN_ALL_NAMESPACES}
# Backup-Plan löschen
gcloud beta container backup-restore backup-plans delete ${BK_PLAN_ALL_NAMESPACES} \
--location=${REGION}
# Restore-Plan löschen
gcloud beta container backup-restore restore-plans delete ${RESTORE_PLAN_ALL_NAMESPACES} \
--location=${REGION}
Viel Spaß beim Ausprobieren – melden Sie sich gern, falls Sie Fragen haben!
Unterm Strich ist Backup for GKE ein leistungsstarkes Werkzeug, um Ihre StatefulSet-Daten zuverlässig abzusichern. Wenn Sie StatefulSets in Kubernetes betreiben, sollten Sie Backup for GKE in Betracht ziehen.
Ressourcen:
Pricing | Google Kubernetes Engine (GKE) | Google Cloud \ Review pricing for GKE\ cloud.google.com