Velero: sauvegardez et restaurez (proprement)
vos applications Kubernetes
Rémi Verchère @ Accenture
Avant-propos
Je ne suis pas expert backup, je ne suis là par pur altruisme
C'est probablement la dernière fois que je fais cette présentation en public On
est entre nous, je risque de lancer quelques trolls
Surtout après les échanges sur Twitter ce week-end
Pas de live coding, que du REX
Au sommaire
Présentation de l'outil
Utilisation en prod, gestion des données, etc..
Exemple de migration
Des fails, parce que vous aimez ça
Qui suis-je ?
Rémi Verchère
Cloud Native Infrastructure Consultant
Ops qui aime bien les Devs
Papa x
Certified Kubernetes
{Associate,Dev,Admin,Security}
@rverchere
https://presentations.verchere.fr/
Backup & Kubernetes
Pourquoi ?
Conteneurs Stateless
Manifest YAML facilement redéployables
CI/CD
GitOps
Boucle de réconciliation
kubectl apply || crictl run et c'est réglé ^^
Plein d'autres raisons approximatives...
Backup & Kubernetes
Parce que, des fois, dans la vraie vie...
Conteneurs Statefull
Migration & Protection des données
Reprise après sinistre
Ressources en prod pas "exactement" les mêmes
L'erreur est humaine
$ kubectl delete namespace la-prod
Velero - Généralités
Un peu d'histoire
Heptio Ark, "open-sourcé" mi 2017
Société rachetée par VMware fin 2018
Intégré à l'offre Tanzu (TMC)
Actuellement en version 1.10.1 (2023-02-06)
$ git log --reverse
commit 2fe501f527a88ea292ca3dde80992ec60b388dda
Author: Andy Goldstein <andy.goldstein@gmail.com>
Date: Wed Aug 2 13:27:17 2017 -0400
Velero - Généralités
Fonctionnalités principales
Sauvegarde des ressources d'un cluster et les restaure en cas de perte.
Migration, Réplication des ressources d'un cluster à un autre.
Custom Ressources qui définissent quoi sauvegarder, comment et quand (selector,
schedule)
Composants
Serveur (Controller) qui tourne sur votre cluster
Client en ligne de commande qui s'exécute localement
https://velero.io/docs/main/index.html
Il était une fois la prod "de confiance"
Contexte
Plusieurs clusters Kubernetes managés OVHcloud
Storage object Openstack Swift & block Cinder
Applications hétérogènes
Outils de gestion d'infra majoritairement Open Source
Besoin de Backup :
Sur stockage S3, loin
Réplication des applications sur cluster de test
Possibilité de PRA sur un autre cloud provider
Exemple d'application
Nextcloud
Chart Helm
1 déploiement de l'application 1
base Mariadb
1 cache Redis (master / replicas)
Ingress, Cronjobs, etc.
https://github.com/nextcloud/helm
Exemple d'application
Nextcloud
$ kubectl get deployment,statefulset,cronjob,service,ingress
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/nextcloud 1/1 1 1 28d
NAME READY AGE
statefulset.apps/nextcloud-mariadb 1/1 28d
statefulset.apps/nextcloud-redis-master 1/1 28d
statefulset.apps/nextcloud-redis-replicas 1/1 28d
NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
cronjob.batch/nextcloud-cron */15 * * * *
F
alse
0 62s 28d
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/nextcloud ClusterIP 10.3.124.75 <none> 8080/TCP 28d
service/nextcloud-mariadb ClusterIP 10.3.145.33 <none> 3306/TCP 28d
service/nextcloud-redis-headless ClusterIP None <none> 6379/TCP 28d
service/nextcloud-redis-master ClusterIP 10.3.207.110 <none> 6379/TCP 28d
service/nextcloud-redis-replicas ClusterIP 10.3.249.214 <none> 6379/TCP 28d
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress.networking.k8s.io/nextcloud <none> nextcloud.demo.vrchr.fr ip-135-125-84-204.gra.lb.ovh.net 80, 443 28d
Velero - Sauvegarde des données
Objects Kubernetes
Les objets kubernetes sont exportés sur bucket S3
Données persistantes : 2x2 possibilités
1. Snapshots des Persistent Volumes (PV)
via API du Cloud Provider
via CSI (>= version 1.4). Compatibilité Cloud Provider (Cinder: )
3. Export des volumes montés par les pods : File System Backup FSB (Swift:
) via Restic
via Kopia (>= version 1.10)
Velero - Backup via FSB (Restic)
Activation avec chart Helm
# $ helm get values velero
deployNodeAgent: true
# Deploiement des Daemonsets sur les nodes
[...]
configuration:
[...]
uploaderType: restic # par défaut pour le moment
defaultVolumesToFsBackup:
true [...]
initContainers:
# Deja défini pour l'export des objets k8s
- name: velero-plugin-for-aws
image: velero/velero-plugin-for-
aws:v1.6.0 volumeMounts:
- mountPath: /target
name: plugins
Velero - Backup via FSB (Restic)
2 modes de backup
1. Opt-in: rien par défaut, on sélectionne ce qu'on veut sauvegarder
podAnnotations:
## Velero annotations
backup.velero.io/backup-volumes-includes: nextcloud-main
2. Opt-out: tout par défaut, on sélectionne ce qu'on veut exclure
Par défaut depuis Velero 1.5
podAnnotations:
## Velero annotations
backup.velero.io/backup-volumes-excludes: redis-data
Velero - Restore
Process de restore "presque" l'inverse du backup, mais en plus :
Validation des ressources seront compatibles
Ordre de restauration des ressources
Possibilité de changer de namespace --namespace-mappings
Possibilité de changer de storage class velero.io/change-storage-class
Mode "incrémental" --existing-resource-policy
Données (PV/PVC)
Si Snapshot : Restore du volume, puis remapping / reference
Si FSB: Création d'un nouveau volume, réhydratation des données
Velero - Snapshots ou FSB ?
Snapshot FSB
Non atomique Non atomique
Même média Média différent
Plus rapide Plus lent
Proche Distant ( coût transferts)
Non chiffré ( Storage Class) Chiffré
Même Cloud Provider ( Zone) Cloud Provider Agnostic
Velero - Snapshots ou FSB ?
Rappels de bonnes pratiques
voir même 3-2-1-1
https://www.msp360.com/resources/blog/following-3-2-1-backup-strategy/
Velero - Snapshots ou FSB ?
Les 2 ! Mais...
Bien configurer l'opt-in / opt-out côté FSB (defaultVolumesToFsBackup) Bien
configurer includes / excludes des volumes
--snapshot-volumes
Bien configurer l'utilisation de snapshots ( )
Certaines combinaisons ne fonctionnent pas ensemble
Si opt-in && includes : pas de snapshots des volumes
time="2022-10-02T00:01:04Z" level=info msg="Skipping snapshot of persistent volume
because volume is being backed up with restic."
Velero - Snapshots ou FSB ?
Mes recommendations
opt-out par défaut
1 schedule classique: backup S3, avec excludes pour certains volumes, sans
snapshots (snapshotVolumes: false)
1 schedule snapshots: defaultVolumesToFsBackup: false (opt-in)
Dans le doute : FSB
Restic vs Kopia : https://velero.io/docs/v1.10/performance-guidance/
Velero - Hooks
Pre & Post Hooks
Pod Annotation ou Backup Spec
pre.hook.backup.velero.io/container
pre.hook.backup.velero.io/command
pre.hook.backup.velero.io/on-error
pre.hook.backup.velero.io/timeout
commande doit être disponible, sinon utilisation de sidecar container
Velero - BDD & Atomicité
fsfreeze
1. Utilisation des hooks avec , sqldump
blocage de la BDD le temps du backup
2. Utilisation de BDD réplica en read-only Hook
de backup sur le réplica, à l'ancienne
2. En dehors du cluster Kubernetes
3. Utilisation de BDD managée
Blueprints de backups ? Voir Kanister
Velero - Cas d'une migration cloud
Quelques points de vigilance
Bascule DNS (CQFD)
Version de Kubernetes & API différentes : "API Group Versions Feature"
Certaines ressources non nécessaires : "--exclude-resources"
$ velero restore --exclude-resources CustomResourceDefinition,CertificateRequest,Order
Storage différent : "Changing PV/PVC Storage Class"
kind: ConfigMap
metadata:
labels:
velero.io/change-storage-class: RestoreItemAction
data:
<old-storage-class>: <new-storage-class>
Velero - Cas d'une migration cloud
Temps de restauration assez long (si plusieurs centaines de Go)
Comment optimiser ce temps de "bascule" ?
--existing-resource-policy
Flag pour restore "incrémental" ?
Velero - Cas d'une migration cloud
Temps de restauration assez long (si plusieurs centaines de Go)
Comment optimiser ce temps de "bascule" ?
Réponse: rsync !
OpenShift MTC
“ The Migration Toolkit for Containers (MTC) enables you to migrate stateful application
workloads between OpenShift Container Platform 4 clusters at the granularity of a
namespace.
“ The file system copy method uses Restic for indirect migration or Rsync for direct
volume migration.
https://docs.openshift.com/container-
platform/4.11/migration_toolkit_for_containers/about-mtc.html
“
“
Velero - Backup qui s'est mal passé
1. Storage Location
Oubli de préciser, Velero ne sait pas où sauvegarder
spec:
storageLocation: ovh-velero-storage-location
$ kubectl logs -f velero-7dcfbb4b6b-k8fl9
time="2023-01-31T03:09:07Z" level=warning msg="There is no existing backup storage location set as default.
Please see `velero backup-location-h` for options." controller=backup-storage-location
logSource="pkg/controller/backup_storage_location_controller.go:173"
2. Timeout
Sur gros volumes, Restic part en timeout
configuration:
resticTimeout: 2h
Velero - Backup qui s'est mal passé
3. Objets S3
Backup trop gros (beaucoup de namespaces)
Velero - Backup qui s'est mal passé
4. Restic OOMKilled !
Augmenter les requests & limits (grosse amélioration depuis Restic 0.14.0)
GOGC ! (https://tip.golang.org/doc/gc-guide)
Ressources Daemonset
Restic Prune !
configuration:
extraEnvVars:
GOGC: 10
resources: # Velero
limits:
cpu: null
memory: 2Gi # <---
restic:
resources:
limits:
cpu: "2"
memory: 4Gi
Velero - Backup qui s'est mal passé
5. Restic Locked backend
Gestion multi clusters : attention aux storage location RW
stderr=unable to create lock in backend: repository is already locked exclusively by PID 11108
on velero-76cfbd7858-5fr8t by nonroot (UID 65532, GID 65532)
lock was created at 2022-09-30 04:00:05 (1m5.593684965s ago)
storage ID 44a72b6f the `unlock` command can be used to remove stale locks
exit status 1" error.file="/go/src/github.com/vmware-tanzu/velero/pkg/restic/backupper.go:184"
error.function="github.com/vmware-tanzu/velero/pkg/restic.(*backupper).BackupPodVolumes"
logSource="pkg/backup/backup.go:417"
name=nextcloud-mariadb-0
$ kubectl patch backupstoragelocation <STORAGE LOCATION NAME>
--namespace velero
--type merge
--patch '{"spec":{"accessMode":"ReadOnly"}}'
Velero - Backup qui s'est mal passé
5. Restic, NFS & ReadWriteMany
1. Backup Serveur NFS
1. Backup PV Pod 1
1. Backup PV Pod 2
1. Backup PV Pod N
msg="Pod volume uses a persistent volume claim which has already been backed up
with restic from another pod, skipping."
Velero - Restore qui s'est mal passé
1. Restic Annotations
Oubli d'annoter 1 volume lors du backup
podAnnotations:
backup.velero.io/backup-volumes-includes:
2. Selector
Tout n'est pas pris en compte
$ kubectl get all -l app=mariadb-database
NAME READY STATUS RESTARTS AGE
pod/mariadb-database-0 1/1 Running 0 93d
Velero - Restore qui s'est mal passé
3. Base de données corrompue !
Pas d'atomicité : Utilisation des pre-hooks & post-hooks Sur
Backup, mais aussi sur Restore
metadata:
annotations:
backup.velero.io/backup-volumes: data
pre.hook.backup.velero.io/command: '["/bin/bash", "-
c",
"mkdir -p /bitnami/mariadb/backups
&& mysqldump -u $MARIADB_USER -p$MARIADB_PASSWORD
$MARIADB_DATABASE > /bitnami/mariadb/backups/nextcloud.dump"]'
Faut-il aussi pouvoir récupérer les dumps (tar)...
$ kubectl cp nextcloud-mariadb-0:~/nextcloud.dump ./nextcloud.dump
command terminated with exit code 126
Velero - Restore qui s'est mal passé
4. Statefulset disparu ?!
Bug avec velero.io/change-storage-class
$ velero restore create nextcloud-migration-22091501 --from-backup nextcloud-22091501
$ velero restore describe nextcloud-migration-
22091501 [...]
Phase: PartiallyFailed (run 'velero restore logs nextcloud-migration-22091501' for more
information) Total items to be restored: 105
Items restored: 105
Started: 2022-09-15 21:02:46 +0200 CEST
Completed: 2022-09-15 22:13:04 +0200 CEST
[...]
Errors:
Namespaces:
nextcloud: error preparing statefulsets.apps/nextcloud/nextcloud-mariadb: rpc error: code = Aborted desc = plugin panicked:
runtime error: invalid memory address or nil pointer dereference
error preparing statefulsets.apps/nextcloud/nextcloud-redis-master: rpc error: code = Aborted desc = plugin panicked:
runtime error: invalid memory address or nil pointer dereference
Monitoring
metrics:
serviceMonitor:
enabled: true
# HELP velero_backup_attempt_total Total number of attempted backups
# HELP velero_backup_deletion_success_total Total number of successful backup
deletions # HELP velero_backup_duration_seconds Time taken to complete backup, in
seconds
# HELP velero_backup_failure_total Total number of failed backups
# HELP velero_backup_items_errors Total number of errors encountered during backup
# HELP velero_backup_validation_failure_total Total number of validation failed
backups # HELP velero_csi_snapshot_attempt_total Total number of CSI attempted volume
snapshots
successful volume snapshots
# HELP velero_restore_attempt_total Total number of attempted
restores # HELP velero_restore_total Current number of existent
restores
# HELP velero_restore_validation_failed_total Total number of failed restores failing
Derniers conseils
Lisez la doc Velero !
Vérifiez l'état de vos backups
Validez vos restaurations régulièrement
On n'est pas obligé de tout mettre dans Kubernetes, cf services managés En
vrai, ça marche plutôt pas mal, faut-il bien configurer l'outil.
Ils utilisent Velero
Openshift "OADP" & "MTC"
VMware "TMC"
Accenture
Vous ? Parlons-en !
AU MENU
● EXPLICATION INSTALLATION ET PRÉREQUIS
● PRÉSENTATION RAPIDE DES FICHIERS DE CONFIG ET DE RESSOURCES
● DÉPLOIEMENT MULTI CLOUD
● MISE EN ÉVIDENCE DE LA RÉCONCILIATION
78
UN OUTIL À HAUT POTENTIEL !
● CLOUD NATIVE
● ENVIRONNEMENT KUBERNETES
● PAS DE LANGAGE PROPRE (MANIFEST YAML UNIQUEMENT)
● COMPATIBLE AVEC TOUT OUTIL CAPABLE D’UTILISER L’API K8S (ex: Grafana)
● AMÉLIORATION DE LA DISPONIBILITÉ DES RESSOURCES (réconciliation)
● DÉSORMAIS CAPABLE DE GÉRER UNE MYRIADE DE RESSOURCES
81