Cloud Intelligence™Cloud Intelligence™

Cloud Intelligence™

So schützen Sie Ihre StatefulSet-Daten mit Backup for GKE

By Felipe MartinezJul 20, 20237 min read

Diese Seite ist auch in English, Español, Français, Italiano, 日本語 und Português verfügbar.

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ür Backup-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 die Backup-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!