Previous slide Next slide Toggle fullscreen Open presenter view
Velero: sauvegardez et restaurez (proprement) vos applications Kubernetes
Rémi Verchère @ Accenture
Qui suis-je ?
Rémi Verchère
Cloud Native Infrastructure Consultant
DevOps, Cloud, Kubernetes, Backup ?
La hype du backup
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, 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
Racheté par VMware fin 2018
Intégré à l'offre Tanzu (TMC)
Actuellement en version 1.9
$ 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 des ressources d'un cluster à un autre.
Réplication d'un cluster de production vers des clusters de dev et test.
Custom Ressources qui définissent quoi sauvegarder, comment et quand (selector, schedule)
Composants
Serveur qui tourne sur votre cluster
Client en ligne de commande qui s'exécute localement
Velero - Installation
Cluster: Chart Helm
$ helm repo add vmware-tanzu https://vmware-tanzu.github.io/helm-charts && helm repo update
$ helm install velero vmware-tanzu/velero --create-namespace -n velero
Release "velero" has been installed. Happy Helming!
Poste client: CLI
$ asdf plugin add velero && asdf install velero 1.9.1 && asdf global velero 1.9.1
$ velero version
Client:
Version: v1.9.1
Git commit: e4c84b7b3d603ba646364d5571c69a6443719bf2
Server:
Version: v1.9.1
Aurélie Vache - Understanding Kubernetes in a visual way
Aurélie Vache - Understanding Kubernetes in a visual way
Mise en situation : la prod
Il était une fois la prod "de confiance"
Contexte
Plusieurs clusters Kubernetes managés OVHcloud & Scaleway
OVHcloud: Storage object Openstack Swift & block Cinder
Scaleway: Storage object S3 & block
Outils majoritairement Open Source
Applications hétérogènes
Backup sur stockage S3 , OVHcloud ou Scaleway selon les cas, régions
Besoin de répliquer les 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 * * * * False 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
Backup & Restore, l'aventure...
Velero - Première fois
1er backup
$ velero backup create nextcloud-backup-1 --include-namespaces nextcloud
$ velero backup describe nextcloud-backup-1
Name: nextcloud-backup-1
Namespace: velero
[...]
Phase: Completed
Errors: 0
Warnings: 0
[...]
Total items to be backed up: 200
Items backed up: 200
[...]
Velero - Première fois
1er restore
$ velero restore create nextcloud-restore-1 --from-backup nextcloud-backup-1
$ velero restore nextcloud-restore-1
Name: nextcloud-restore-1
Namespace: velero
Labels: <none>
Annotations: <none>
Phase: Completed
Total items to be restored: 200
Items restored: 200
Velero - Première fois
1er fail
Objets kubernetes sauvés, données sacrifiées !
Velero Snapshots, Backups, Restore
Volumes Persistants
Velero - Sauvegarde des données
Objects Kubernetes
Les objets kubernetes sont exportés sur bucket S3
3 types de storage pour les données persistantes
Snapshots des Persistent Volumes (PV) via API du Cloud Provider
Snapshots des Persistent Volumes (PV) via CSI (>= version 1.4 )
Export volumes montés des pods sur Bucket S3 via Restic
Velero - Snapshots PV via API
Velero - Snapshots PV via CSI
Velero - Snapshot PV via CSI
Activation avec chart Helm
Sous réserve que votre CSI le supporte : --features=EnableCSI
snapshotsEnabled: true
[... ]
configuration:
[... ]
features: EnableCSI
[... ]
initContainers:
- name: velero-plugin-for-csi
image: velero/velero-plugin-for-csi:v0.3.1
volumeMounts:
- mountPath: /target
name: plugins
Velero - Snapshot PV via CSI
J'ai testé pour vous
$ velero backup get
NAME STATUS ERRORS WARNINGS CREATED EXPIRES STORAGE LOCATION SELECTOR
daily-s3-20220920000000 Failed 0 0 2022-09-20 02:00:00 +0200 CEST 1d velero-gra9 <none>
daily-s3-20220916000004 Completed 0 0 2022-09-16 02:00:04 +0200 CEST 1d velero-gra9 <none>
daily-s3-20220915000003 Completed 0 0 2022-09-15 02:00:03 +0200 CEST 5h velero-gra9 <none>
daily-snapshot-20220920010027 Failed 0 0 2022-09-20 03:00:27 +0200 CEST 1d velero-gra9 <none>
daily-snapshot-20220915010003 Completed 0 0 2022-09-15 03:00:03 +0200 CEST 6h velero-gra9 <none>
$ kubectl logs -f velero-5b86bc8db-5p8md
time="2022-10-03T19:32:22Z" level=info msg="Waiting for volumesnapshotcontents
snapcontent-bc5660db-b0a4-4cc5-98cb-a071d5473dcb to have snapshot handle. Retrying in 5s" [...]
time="2022-10-03T19:32:27Z" level=info msg="Waiting for volumesnapshotcontents
snapcontent-bc5660db-b0a4-4cc5-98cb-a071d5473dcb to have snapshot handle. Retrying in 5s" [...]
Velero - Snapshot PV via CSI
J'ai insisté, avec les équipes du CSP
$ velero backup get
NAME STATUS ERRORS WARNINGS CREATED EXPIRES STORAGE LOCATION SELECTOR
daily-s3-20221004182135 Completed 0 0 2022-10-04 20:21:35 +0200 CEST 1d velero-gra9 <none>
daily-s3-20221004181435 Completed 0 0 2022-10-04 20:14:35 +0200 CEST 1d velero-gra9 <none>
[...]
daily-snapshot-20221004190535 Completed 0 0 2022-10-04 21:05:35 +0200 CEST 1d velero-gra9 <none>
daily-snapshot-20221004190035 Completed 0 0 2022-10-04 21:00:35 +0200 CEST 1d velero-gra9 <none>
daily-snapshot-20221004185535 Completed 0 0 2022-10-04 20:55:35 +0200 CEST 1d velero-gra9 <none>
daily-snapshot-20221004185035 Completed 0 0 2022-10-04 20:50:35 +0200 CEST 1d velero-gra9 <none>
[...]
Aux limites configurées côté storage provider
N'est pas considéré comme stockage pérenne
Velero - Backup via Restic
Velero - Backup via Restic
Activation avec chart Helm
deployRestic: true
[... ]
configuration:
[... ]
defaultVolumesToRestic: true
[... ]
initContainers:
- name: velero-plugin-for-aws
image: velero/velero-plugin-for-aws:v1.5.1
volumeMounts:
- mountPath: /target
name: plugins
Velero - Backup via Restic
2 modes de backup
Opt-in : rien par défaut, on sélectionne ce qu'on veut sauvegarder
podAnnotations:
backup.velero.io/backup-volumes-includes: nextcloud-main
Opt-out : tout par défaut, on sélectionne ce qu'on veut exclure
Par défaut depuis Velero 1.5
podAnnotations:
backup.velero.io/backup-volumes-excludes: redis-data
Velero - Restore
Données (PV/PVC)
Si Snapshot API ou CSI: Restore du volume, puis remapping / reference
Si Restic: Création d'un nouveau volume, réhydratation des données
Velero - Restore avec Restic
Velero - Snapshots ou Restic ?
Snapshot
Restic
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 Restic ?
Rappels de bonnes pratiques
voir même 3-2-1-1
Velero - Snapshots ou Restic ?
Les 2 ! Mais...
Bien configurer l'opt-in / opt-out côté Restic (defaultVolumesToRestic )
Bien configurer includes / excludes des volumes
Bien configurer l'utilisation de snapshots (--snapshot-volumes
)
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 Restic ?
Mes recommendations
opt-out par défaut
1 schedule classique: backup S3, avec excludes pour certains volumes, sans snapshots (snapshotVolumes: false )
1 schedule snapshots: defaultVolumesToRestic: false (opt-in )
Dans le doute : Restic
Restic - Généralités
Simple
Multi backend (Local, SFTP, S3, ...)
Rapide (Backup Incrémental & Déduplication)
Secure
Intégré à Velero
Restic is a backup program that is fast, efficient and secure. It supports the three major operating systems (Linux, macOS, Windows) and a few smaller ones (FreeBSD, OpenBSD).
Restic - Incrémental
Backup
Restore
Velero won’t restore a resource if a that resource is scaled to 0 and already exists in the cluster.
Restic - Restauration partielle
Exemple de besoin : récupérer juste 1 fichier effacé par un humain
Comment le récupérer depuis le repository restic ?
$ export AWS_SECRET_KEY_ID="Si vous lisez ce message, RDV sur le stand Accenture"
$ export AWS_SECRET_ACCESS_KEY="Place offerte pour le DevOps D-Day aux 2 premiers"
$ export ACN_SECRET_CODE="velero"
$ restic snapshots -r s3:https://s3.fr-par-.scw.cloud/backup-velero-nextcloud/restic/nextcloud
enter password for repository:
Restic - Securité
Secure : Restic uses cryptography to guarantee confidentiality and integrity of your data. The location the backup data is stored is assumed not to be a trusted environment (e.g. a shared space where others like system administrators are able to access your backups). Restic is built to secure your data against such attackers.
Those of you familiar with restic may know that it encrypts all of its data. Velero uses a static, common encryption key for all Restic repositories it creates
$ kubectl get secret velero-restic-credentials -o jsonpath="{.data.repository-password}" \
| base64 -d
https://github.com/vmware-tanzu/velero/pull/4961
Restic - Atomicité
Note that cluster backups are not strictly atomic. If Kubernetes objects are being created or edited at the time of backup, they might not be included in the backup. The odds of capturing inconsistent information are low, but it is possible
Idée (à la ***)
Scale à 0 juste avant le backup, au moins pas d'écritures !
Velero’s Restic integration backs up data from volumes by accessing the node’s filesystem, on which the pod is running. For this reason, Velero’s Restic integration can only backup volumes that are mounted by a pod and not directly from the PVC
Velero - Hooks
commande doit être disponible, sinon utilisation de sidecar container
Et 1 autre sur les Bases de Données !
Velero - BDD & Atomicité
Utilisation des hooks avec fsfreeze
, sqldump
blocage de la BDD le temps du backup
Utilisation de BDD réplica en read-only
Hook de backup sur le réplica , à l'ancienne
En dehors du cluster Kubernetes
Utilisation de BDD managée
Blueprints de backups ? Voir Kanister
Cas de migration cloud
Velero - Cas d'une migration cloud
Velero - Cas d'une migration cloud
Quelques points de vigilance
$ 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 " ?
Flag --existing-resource-policy
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 " ?
OpenShift MTC
Quelques fails
Velero - Backup qui s'est mal passé
Storage Location
Oubli de préciser, Velero ne sait pas où sauvegarder
spec:
storageLocation: ovh-velero-storage-location
Timeout
Sur gros volumes, Restic part en timeout
configuration:
resticTimeout: 2h
Velero - Backup qui s'est mal passé
Objets S3
Backup trop gros (beaucoup de namespaces)
Velero - Backup qui s'est mal passé
Restic OOMKilled !
Augmenter les requests & limits
GOGC ! (https://tip.golang.org/doc/gc-guide )
configuration:
extraEnvVars:
GOGC: 10
resources:
limits:
cpu: null
memory: 2Gi
restic:
resources:
limits:
cpu: "2"
memory: 4Gi
Velero - Backup qui s'est mal passé
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é
Restic, NFS & ReadWriteMany
5.1. Backup Serveur NFS
5.2. Backup PV Pod 1
5.3. Backup PV Pod 2
5.4. 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é
Restic Annotations
Oubli d'annoter 1 volume lors du backup
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é
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é
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 validations
# HELP velero_volume_snapshot_attempt_total Total number of attempted volume snapshots
Monitoring
Alerting !
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
Ils utilisent Velero
Openshift "OADP" & "MTC"
VMware "TMC"
Accenture
Vous ? Parlons-en !
Merci !
2022.devops-dday.com
Rémi Verchère @ Accenture
Notes: Je hais les backups, mais je hais encore plus perdre des données.
Depuis quelques temps j'administre des cluster k8s & applications qui tournent dessus.
On m'a présenté Velero comme l'outil magique, mais j'y crois pas trop ;)
J'ai pas trouvé bcp de ressources FR sur le sujet, d'où ce talk pour partager avec vous mes galères !
Pas de sauvegarde d'ETCD / Control planes, on reste sur l'applicatif
1. The Velero client makes a call to the Kubernetes API server to create a Backup object.
2. The BackupController notices the new Backup object and performs validation.
3. The BackupController begins the backup process. It collects the data to back up by querying the API server for resources.
4. The BackupController makes a call to the object storage service – for example, AWS S3 – to upload the backup file.
CSI: Container Storage Interface
⚠️ `fsfreeze` & montages NFS
# Velero - Cas d'une migration cloud
- Installation de Velero sur les 2 clusters.
- Configuration des mêmes Storage Location (Read Only)
- Backup Velero Cluster A, sur Bucket S3 avec Restic
- Restore sur Cluster B, depuis même Bucket S3 avec Restic
- Facile ! Ou pas...
Utilisation de nfs-ganesha-server-and-external-provisioner
---
# Une config de chart helm
# qui marche *à peu près*
---
# Velero - Config qui marche *à peu près*
```yaml
# *** helm get values velero
initContainers:
- name: velero-plugin-for-aws
image: velero/velero-plugin-for-aws:v1.5.1
volumeMounts:
- mountPath: /target
name: plugins
- name: velero-plugin-for-csi
image: velero/velero-plugin-for-csi:v0.3.1
volumeMounts:
- mountPath: /target
name: plugins
```
---
# Velero - Config qui marche *à peu près*
```yaml
configuration:
provider: aws
backupStorageLocation:
name: ovh-velero-storage-location
bucket: ovh-velero-storage-location
default: true
config:
region: sbg
s3ForcePathStyle: true
s3Url: https://s3.sbg.cloud.ovh.net
volumeSnapshotLocation:
config:
enableSharedConfig: true
region: gra
```
---
# Velero - Config qui marche *à peu près*
```yaml
configuration:
extraEnvVars:
GOGC: 10
features: EnableCSI
defaultVolumesToRestic: true
resticTimeout: 2h
```
---
# Velero - Config qui marche *à peu près*
```yaml
resources:
limits:
cpu:
memory: "2Gi"
snapshotsEnabled: true
deployRestic: true
restic:
resources:
limits:
cpu: "2"
memory: "4Gi"
```
---
# Velero - Config qui marche *à peu près*
```yaml
credentials:
secretContents:
cloud: |
[default]
aws_access_key_id="Utilisez plutôt des secrets, bon sang !"
aws_secret_access_key="Si votre RSSI voit ça vous êtes mal..."
metrics:
serviceMonitor:
enabled: true
additionalLabels:
release: prom
```
---
# Velero - Sauvegarde Nexcloud
## Schedule S3
Rendez-vous sur mon compte GitLab ;)
## Schedule Snapshot
Rendez-vous sur mon compte GitLab ;)
## Annotations chart Helm
Rendez-vous sur mon compte GitLab ;)