Einst von VMware entwickelt und nunmehr Open Source in den Händen der Cloud Native Computing Foundation, leistet Velero Backup, Disaster Recovery und Datenmigration im Kubernetes-Umfeld. Wir zeigen, wie Sie das Tool aufsetzen und die drei erwähnten Aufgaben in Ihrem Cluster erledigen. So stellen
Sie sicher, dass Ihre Apps immer Rückenwind haben.
Backups innerhalb eines Kubernetes-Clusters umfassen üblicherweise verschiedene Elemente wie die Master-Knoten, die Worker-Knoten und die etcd-Datenbank. Administratoren sind bei Datensicherungen aber zumeist an Kubernetes-Objekten interessiert, also zum Beispiel Namespaces, Persistent Disks
oder Deployments.
Genau in diese Bresche springt Velero [1]. Die Software läuft sowohl in Cloudumgebungen als auch im eigenen Rechenzentrum und kommt mit diesen zentralen Funktionalitäten daher:
- Erstellen von Backups und deren Einspielen im Falle eines Datenverlustes.
Backups innerhalb eines Kubernetes-Clusters umfassen üblicherweise verschiedene Elemente wie die Master-Knoten, die Worker-Knoten und die etcd-Datenbank. Administratoren sind bei Datensicherungen aber zumeist an Kubernetes-Objekten interessiert, also zum Beispiel Namespaces, Persistent Disks
oder Deployments.
Genau in diese Bresche springt Velero [1]. Die Software läuft sowohl in Cloudumgebungen als auch im eigenen Rechenzentrum und kommt mit diesen zentralen Funktionalitäten daher:
- Erstellen von Backups und deren Einspielen im Falle eines Datenverlustes.
- Migration von Cluster-Ressourcen auf andere Cluster.
- Replizieren von Inhalten eines Clusters auf andere Umgebungen.
Infrastrukur für Velero
Die Velero-Serverkomponenten müssen auf dem Kubernetes-Cluster installiert werden. Dies erfolgt entweder über ein Helm Chart oder über die Velero CLI. Diese CLI bildet die Basis für Arbeiten mit dem Tool, kommt also bei Sicherungen und Recovery zum Einsatz. Schließlich sind die Storage-Provider-Plug-ins im
Quellspeicher der Datensicherung einzuspielen.
Darüber hinaus benötigen Sie noch Platz zum Ablegen der Backups. Velero nutzt dafür S3-kompatiblen Objektspeicher, den Sie beispielsweise in der Cloud in Form von AWS S3, Azure Storage oder Google Cloud Storage bereitstellen. Falls Sie lokal unterwegs sind, gibt es dafür Produkte wie Swarm Object Storage von
Datacore, NtApp Storage Grid oder auch das Open-Source-Projekt MinIO [2].
Velero via CLI in Betrieb nehmen
Am einfachsten installieren Sie Velero über dessen CLI. Voraussetzung dafür ist, dass Sie Zugriff auf einen Kubernetes-Cluster haben. Dafür müssen Sie im ersten Schritt die CLI installieren, was wir beispielhaft für ein Linux-System zeigen. Zunächst laden Sie also die CLI herunter:
Das enthaltene Binary verschieben Sie in den Ordner "/usr/bin":
sudo mv velero-v1.11.1-linuxamd64/velero /usr/bin
Die Installation überprüfen Sie, indemSie die Version abfragen:
velero version
Nun geht es an die Installation der Serverkomponenten. Zuvor sind jedoch einige Voraussetzungen zu erfüllen, angefangen mit der notwendigen Kubernetes-Minimal-Version. Dies ist allerdings einfach – Version 1.12 ist schon seit einigen Jahren erhältlich. Beim Einrichten des Objektspeichers gibt es mehr
Arbeit. Dieser muss nicht nur vorhanden sein, Sie brauchen auch entsprechende Berechtigungen. Die Konfiguration ist je nach verwendetem Objektspeicher beziehungsweise Clouddienst unterschiedlich. Wir zeigen im Folgenden die Konfiguration in der Google-Cloud.
Dafür wechseln Sie in der Google Cloud Console in das Projekt, in dem der Objektspeicher sein Zuhause haben soll und geben oben mittig "Cloud Storage" im Suchfeld ein. Auf der Seite "Cloud Storage" angekommen, klicken Sie oben links auf "Buckets auswählen" und dann auf "Create". Jetzt hinterlegen Sie den Namen
des Cloud Storage Buckets – dieser muss weltweit eindeutig sein. Anschließend wählen Sie eine Region aus – für Deutschland empfiehlt sich "europe-west3", also Frankfurt. Den Rest der Einstellungen können Sie übernehmen und klicken auf "Create".
Notwendige Berechtigungen zuteilen
Die anschließende Vergabe der notwendigen Berechtigungen ist etwas kniffliger. Diese müssen sowohl den Zugriff auf den Bucket als auch die Rechte für die Installation im Kubernetes-Cluster umfassen. Für den Cluster sind Admin-Rechte für denjenigen notwendig, der die Installation durchführt.
Die Velero-Installation legt innerhalb des Kubernetes-Clusters RBAC-Objekte (Role Based Access Control) an. Daher benötigen Sie die entsprechende Cluster-Admin-Rolle. Beim Zugriff auf den Bucket können Sie es sich leicht machen und einfach die "Object-Admin"-Rolle im Projekt vergeben. Für das
Erzeugen von Snap-shots und diversen anderen Objekten sind weitere Rechte notwendig, dafür legen wir im Folgenden eine Custom-Rolle an.
Zuerst müssen wir aber einen Google-Service-Account erzeugen, der diese Rechte erhalten soll. Dies ist über die Cloudkonsole oder über die Bash möglich. Haben Sie die Google gcloud-CLI noch nicht aktiviert, erledigen Sie dies in der Konsole, indem Sie die Cloud Shell über den Knopf oben rechts starten. Dort
gehen Sie auch die weiteren Arbeiten an, zuerst schauen Sie Ihre aktuellen Projekteinstellungen nach:
gcloud config list
Anschließend setzen Sie "PROJECT_ID" auf den gewünschten Wert:
PROJECT_ID=$(gcloud config get-value project)
Nun erzeugen Sie den Service-Account:
GSA_NAME=velero
gcloud iam service-accounts create $GSA_NAME \ --display-name "Velero service account"
Um mit den Service-Account arbeiten zu können, ist noch dessen E-Mail-Adresse erforderlich. Diese bekommen wir wie folgt heraus:
SERVICE_ACCOUNT_EMAIL=$(gcloud iam service-accounts list \ --filter="displayName:Velero service account" \ --format 'value(email)')
Nun legen Sie die Custom-Role für Velero an. Die notwendigen Befehle zeigt Listing 1. Dabei definieren Sie zuerst ein Array mit den entsprechend benötigten Einzelrechten und legen anschließend eine Rolle damit an. Im dritten Schritt verknüpfen Sie die Rolle mit dem zuvor angelegten Service-Account. Als Letztes
geben Sie dem Service-Account noch die Rechte, mit dem Bucket zu arbeiten.
gsutil iam ch serviceAccount:$SERVICE_ACCOUNT_EMAIL:objectAdmin gs://${BUCKET}
Nun müssen wir dafür sorgen, dass Velero im Betrieb die ihm zugeteilten Berechtigungen auch nutzen kann. Dafür gibt es in der Google-Cloud verschiedene Ansätze:
- Sie erzeugen einen Service-Account-Key und geben diesen bei der Installation an.
- Sie konfigurieren "Workforce Identity Federation". Dies hat jedoch den Nachteil, dass Sie die velero-Befehle "velero backup logs", "velero backup download", "velero backup describe" und "velero re-store describe" nicht nutzen können.
- Sie richten "GKE Workload Identity" ein und können innerhalb des Kubernetes-Clusters mittels Annotationen ein Mapping zwischen Kubernetes- und Google-Service-Accounts definieren.
Wir entscheiden uns für die erste Variante und erzeugen einen Service-Account-Key:
gcloud iam service-accounts keys create credentials-velero \ --iam-account $SERVICE_ACCOUNT_ EMAIL
Nun kann die Installation beginnen. Dies gelingt uns wie folgt:
velero install \
--provider gcp \
--plugins velero/velero-plugin-for-gcp:v1.6.0 \
--bucket $BUCKET \
--secret-file ./credentials-velero
Nach der Installation checken Sie im Kubernetes-Cluster, ob Velero läuft:
$ kubectl get pods -n velero
Das Innenleben von Velero verstehen
Für die Arbeit mit Velero ist ein grundsätzliches Verständnis der Architektur der Software notwendig. Dessen Installation erzeugt im Kubernetes-Cluster einen Backup-Controller. Dieser kommuniziert sowohl mit dem Kubernetes-API- Server, der etcd-Datenbank als auch mit den konfigurierten Storage-Locations.
Die Arbeitsweise des Tools am Beispiel eines Backup-Workflows ist in Bild 2 ersichtlich. Diesen initiieren Sie durch den Befehl velero backup create test-backup:
1. Der Velero-Befehl setzt einen API-Aufruf an den Kubernetes-API-Server ab, um innerhalb von Kubernetes ein Backupobjekt zu erzeugen.
2. Der Backup-Controller bemerkt das neu erstellte Objekt und überprüft dessen Werte.
3. Der Backup-Controller beginnt mit der Sicherung. Dafür sammelt er vom API-Server die notwendigen Daten.
4. Anschließend ruft er die API des Objektspeichers auf – in unserem Beispiel Google Cloud Storage – und lädt die Backupdatei hoch.
Velero unterstützt sowohl das einmalige Anlegen eines Backups (One-Time) als auch wiederkehrende Sicherungen (recurring). Dabei ist es möglich, einzelne Objekte als auch den ganzen Cluster zu sichern.
Ausführen einer One-Time-Sicherung
Beim Erzeugen eines initialen Backups ist es oft sinnvoll, den ganzen Cluster samt aller Namespaces zu sichern. Starten Sie das Backup ohne dedizierte Flags, sichert Velero den gesamten Cluster mit allen Namespaces und Objekten. Ein einmaliges Backup starten Sie über
velero backup create initial-backup
Sie haben dabei die Option, mittels velero backup describe initial-backup zu überprüfen, ob die Sicherung geklappt hat. Die Antwort auf diese Anfrage ist relativ lang und sieht wie Listing 2 aus. Dabei liefert Ihnen die describe-Option alle Einstellungen des Backupjobs. Wichtig dabei ist, ob der Job
abgeschlossen wurde, aber auch die Anzahl der gesicherten Objekte. Auch die Start- und die Endzeit des Backup-Jobs sind von Relevanz.
Listing 2: Velero antwortet auf Frage nach erfolgreichem Backup
Für den Produktiveinsatz ist es entsprechend eine Option, beispielsweise über Prometheus Warnmeldungen zu generieren, falls ein Backup nicht funktioniert. Wenn Sie überprüfen wollen, ob die Backupdateien tatsächlich existieren, können Sie sich zudem in der Cloud Console
den Inhalt des entsprechenden Storage-Buckets ansehen. Wie im Bild ersichtlich, erzeugt Velero für jede Sicherung einen Ordner und legt dort die Dateien ab.
Backups nach Zeitplan
In der zweiten Option fahren wir ein Backup zeitgesteuert. Die Velero-CLI stellt dazu die Option "Schedule" bereit, mit deren Hilfe Sie die Sicherung entsprechend steuern und CRON-Expressions übergeben können. Um jede Nacht um 1 Uhr ein Backup durchzuführen, nutzen Sie diesen Befehl:
Die CRON-Expressions lassen sich mit Kurzbefehlen vereinfachen. Dabei sichert "@yearly" einmal pro Jahr um Mitternacht des 1. Januars, "@monthly" einmal pro Monat am ersten Tag im Monat um Mitternacht, "@weekly" einmal pro Woche (Sonntags um Mitternacht), "@daily" jeden Tag um 0:00 Uhr und schließlich
"@hourly" zu jeder vollen Stunde. Der Befehl für eine solche Sicherung schaut dann wie folgt aus:
In vielen Fällen gilt es, nur ausgewählte Elemente in einem Cluster oder verschiedene Einstellungen zu sichern. Velero bietet dafür eine Reihe von Flags (denen Sie jeweils ein doppeltes Minuszeichen voranstellen müssen):
- exclude-namespaces: Komma-separierte Liste von Namespaces, die nicht Teil des Backups sein sollen.
- exclude-resources: Komma-separierte Liste von Ressourcen, die nicht gesichert werden.
- include-namespaces: Komma-separierte Liste von Namespaces, die enthalten sein sollen.
- selector: Backup nur für Objekte, die ein entsprechendes Label aufweisen.
- ttl: Definiert, wie lange eine Sicherung aufgehoben werden soll.
Um also beispielsweise ein tägliches Backup auf einen Namespace durchzuführen, erledigen Sie dies mit diesem Befehl:
Bislang bietet Velero keine grafische Benutzeroberfläche, sodass Sie alle Aufgaben mithilfe von Kubernetes-Manifesten oder der CLI erledigen müssen. Die CLI ist jedoch sehr intuitiv, sodass die Einarbeitung schnell gelingen sollte. So können Sie beispielweise relativ einfach Objekte auflisten lassen, wie zum
Beispiel: Backup-Locations, Backups, Plug-ins, Restores, Schedules und Snapshot-Locations. Alle vorhandenen Sicherung zeigt Ihnen also velero get backups.
Über die CLI sind Sie auch in der Lage, Backups manuell zu löschen: velero delete backup tag2. Aber auch anspruchsvollere Aufgaben wie das Zurückspielen von Sicherungen gehen leicht von der Hand. Hier am Beispiel "initial-backup":
Das beim Disaster Recovery notwendige Zurückspielen eines Deployments wollen wir an einem Beispiel demonstrieren. Dafür legen wir zunächst ein Namespace und ein NGINX-Deployment an:
Nun simulieren wir den Fehlerfall, im Beispiel durch das Löschen des Namespaces:
kubectl delete ns velero-test
An dieser Stelle wurden mit dem Namespace alle Objekte gelöscht, das heißt, auch das NGINX-Deployment ist nicht mehr existent. Die Rücksicherung muss nun so aussehen:
velero create restore --from-backup velero-test
Eine anschließende Überprüfung ergibt Gewissheit, dass das Deployment wieder da ist:
kubectl get deployments -n velero-test
NAME READY UP-TO-DATE AVAILABLE AGE
nginx 1/1 1 1 64s
Daten migrieren
Bei einer Datenmigration kann Velero auf einfache Art und Weise Objekte von einem Cluster auf einen anderen übertragen. Technisch basiert dies auf Veleros Backup- und Restore-Funktionalitäten und der Tatsache, dass der Zustand von Kubernetes-Objekten mit dem angebundenen Objektspeicher synchron gehalten wird.
Dementsprechend ist es notwendig, sowohl den Cluster, von dem Objekte kopiert werden sollen, als auch den Ziel-Cluster auf den gleichen Bucket zeigen zu lassen. Allerdings gibt hier es einige Einschränkungen:
- Eine Datenmigration funktioniert nicht zwischen verschiedenen Public-Cloud-Anbietern. So können Sie beispielsweise einen AWS-EKS-Cluster nicht mit einem Azure-Kubernetes-Service-Cluster synchron halten.
- Die Kubernetes-Version darf auf dem Ziel-Cluster nicht kleiner sein als auf dem Quell-Cluster. Eine hundertprozentige Kompatibilität liegt nur vor, wenn auf beiden Clustern die gleiche Version eingespielt ist.
- Bei AWS und Azure gibt es keine Unterstützung für eine regionsübergreifende Datenmigration. In einem solchen Fall muss ein dateibasiertes Systembackup zum Einsatz kommen.
Damit die Synchronisierung funktionieren kann, müssen Sie auf den Ziel-Cluster Velero installieren. Wie bereits oben beschrieben, können Sie dies wie folgt bewerkstelligen:
velero install \ --provider gcp \
--plugins velero/velero-plugin-for-gcp:v1.6.0 \
--bucket $BUCKET \
--secret-file ./credentials-velero
Sobald die Installation erfolgreich war, können Sie sich via velero get backups auf dem zweiten Cluster überzeugen, dass alle Backupobjekte aus dem Objektspeicher gelesen wurden. Anschließend lässt sich auf dem zweiten Cluster die Sicherung einspielen.
Fazit
Velero ist schnell zu installieren und einfach zu bedienen. Das Projekt existiert seit rund sechs Jahren und hat im Kubernetes-Ökosystem mittlerweile weite Verbreitung erlangt. An dem Projekt wird aktiv weitergearbeitet und neue Versionen erfreuen durch immer mehr Features.