Blog

Velero sur OpenShift : backup et restauration de cluster Kubernetes

OpenShift
Velero
Backup
Disaster Recovery
Kubernetes

Mise en place de Velero sur OpenShift pour sauvegarder et restaurer namespaces, volumes persistants et ressources Kubernetes. Installation via Helm, configuration S3, schedules automatiques, disaster recovery et migration inter-clusters.

15 mars 2025

Velero : la référence du backup Kubernetes

Velero (anciennement Heptio Ark) est l’outil open-source de référence pour la sauvegarde et la restauration de clusters Kubernetes. Il sauvegarde à la fois les ressources Kubernetes (YAML des objets) et les volumes persistants (snapshots CSI ou via Restic/Kopia).

Cas d’usage principaux :

  • Disaster Recovery — restaurer un cluster après une panne
  • Migration inter-clusters — déplacer des workloads d’un cluster à l’autre
  • Sauvegarde applicative — snapshot cohérent d’un namespace entier
  • Clone d’environnement — dupliquer production → staging

Architecture Velero

OpenShift Cluster

├── Velero Deployment (namespace velero)
│   ├── Velero Server
│   └── Node Agent (DaemonSet) ← pour les volumes via Kopia/Restic

├── CSI Snapshot Controller (intégré OpenShift)

└── Namespaces applicatifs
    ├── Resources (Deployments, Services, ConfigMaps...)
    └── PersistentVolumes


                    ▼ backup/restore
            S3 Bucket (AWS, Minio, ODF NooBaa...)
            ├── backups/
            │   ├── daily-backup-2025-03-15/
            │   │   ├── velero-backup.json
            │   │   ├── resources/
            │   │   └── volume-snapshots/
            │   └── ...
            └── restic/  (données volumes Kopia)

Prérequis : stockage S3

Velero requiert un backend S3 pour stocker les backups. Plusieurs options :

# Option 1 : AWS S3
# Option 2 : MinIO (self-hosted)
# Option 3 : ODF NooBaa (déjà sur OpenShift)

# Récupérer les credentials NooBaa pour Velero
oc get secret noobaa-admin -n openshift-storage \
  -o jsonpath='{.data.AWS_ACCESS_KEY_ID}' | base64 -d

oc get secret noobaa-admin -n openshift-storage \
  -o jsonpath='{.data.AWS_SECRET_ACCESS_KEY}' | base64 -d

# Créer un bucket dédié Velero dans NooBaa
cat <<EOF | oc apply -f -
apiVersion: objectbucket.io/v1alpha1
kind: ObjectBucketClaim
metadata:
  name: velero-bucket
  namespace: openshift-storage
spec:
  generateBucketName: velero-backups
  storageClassName: openshift-storage.noobaa.io
EOF

Installation via Helm

helm repo add vmware-tanzu https://vmware-tanzu.github.io/helm-charts
helm repo update

oc create namespace velero

# Créer le fichier credentials S3
cat > /tmp/credentials-velero <<EOF
[default]
aws_access_key_id=<ACCESS_KEY>
aws_secret_access_key=<SECRET_KEY>
EOF

oc create secret generic cloud-credentials \
  -n velero \
  --from-file=cloud=/tmp/credentials-velero

# Installer Velero avec plugin AWS/S3 et support CSI
helm install velero vmware-tanzu/velero \
  --namespace velero \
  --set-file credentials.secretContents.cloud=/tmp/credentials-velero \
  --set configuration.backupStorageLocation[0].name=default \
  --set configuration.backupStorageLocation[0].provider=aws \
  --set configuration.backupStorageLocation[0].bucket=velero-backups-xxxx \
  --set configuration.backupStorageLocation[0].config.region=us-east-1 \
  --set configuration.backupStorageLocation[0].config.s3Url=https://s3.openshift-storage.svc.cluster.local \
  --set configuration.backupStorageLocation[0].config.s3ForcePathStyle=true \
  --set configuration.backupStorageLocation[0].config.insecureSkipTLSVerify=true \
  --set configuration.volumeSnapshotLocation[0].name=default \
  --set configuration.volumeSnapshotLocation[0].provider=aws \
  --set configuration.volumeSnapshotLocation[0].config.region=us-east-1 \
  --set initContainers[0].name=velero-plugin-for-aws \
  --set initContainers[0].image=velero/velero-plugin-for-aws:v1.10.0 \
  --set initContainers[0].volumeMounts[0].mountPath=/target \
  --set initContainers[0].volumeMounts[0].name=plugins \
  --set initContainers[1].name=velero-plugin-for-csi \
  --set initContainers[1].image=velero/velero-plugin-for-csi:v0.7.0 \
  --set initContainers[1].volumeMounts[0].mountPath=/target \
  --set initContainers[1].volumeMounts[0].name=plugins \
  --set features=EnableCSI \
  --set nodeAgent.enabled=true \
  --set nodeAgent.podVolumePath=/var/lib/kubelet/pods \
  --version 7.2.1

Permissions OpenShift (SCC)

# Le NodeAgent (DaemonSet) nécessite des privilèges pour accéder aux volumes
oc adm policy add-scc-to-user privileged \
  -z velero-server \
  -n velero

oc adm policy add-scc-to-user privileged \
  -z node-agent \
  -n velero

Prendre un backup manuel

# Installer la CLI velero
curl -L https://github.com/vmware-tanzu/velero/releases/download/v1.14.0/velero-v1.14.0-linux-amd64.tar.gz | tar xz
sudo mv velero-v1.14.0-linux-amd64/velero /usr/local/bin/

# Backup d'un namespace complet (ressources + volumes)
velero backup create backup-production \
  --include-namespaces production \
  --default-volumes-to-fs-backup \
  --wait

# Backup avec snapshot CSI (plus rapide pour les gros volumes)
velero backup create backup-production-csi \
  --include-namespaces production \
  --snapshot-volumes \
  --volume-snapshot-locations default \
  --wait

# Backup multi-namespaces en excluant certaines ressources
velero backup create backup-all-apps \
  --include-namespaces production,staging,monitoring \
  --exclude-resources events,events.events.k8s.io \
  --ttl 720h \          # Rétention 30 jours
  --wait

Vérifier le backup :

velero backup get
velero backup describe backup-production --details
velero backup logs backup-production

Schedules automatiques

# Backup quotidien à 2h du matin, rétention 30 jours
velero schedule create daily-backup \
  --schedule="0 2 * * *" \
  --include-namespaces production,staging \
  --default-volumes-to-fs-backup \
  --ttl 720h

# Backup hebdomadaire complet du cluster
velero schedule create weekly-full-backup \
  --schedule="0 1 * * 0" \
  --include-cluster-resources=true \
  --ttl 2160h    # 90 jours

# Lister les schedules
velero schedule get

Ou en YAML pour le GitOps :

apiVersion: velero.io/v1
kind: Schedule
metadata:
  name: daily-production
  namespace: velero
spec:
  schedule: "0 2 * * *"
  template:
    includedNamespaces:
      - production
    excludedResources:
      - events
      - events.events.k8s.io
    defaultVolumesToFsBackup: true
    ttl: 720h0m0s
    storageLocation: default
  useOwnerReferencesInBackup: false

Restauration

Restaurer un namespace complet

# Restauration dans le même namespace
velero restore create restore-production \
  --from-backup backup-production \
  --wait

# Restauration avec mapping de namespace (migration)
velero restore create migrate-to-staging \
  --from-backup backup-production \
  --namespace-mappings production:staging \
  --wait

# Restaurer uniquement certaines ressources
velero restore create restore-configmaps \
  --from-backup backup-production \
  --include-resources configmaps,secrets \
  --wait

Vérifier la restauration

velero restore describe restore-production
velero restore logs restore-production

# Vérifier que les pods sont Running
oc get pods -n production
oc get pvc -n production

Migration inter-clusters

Scénario : migrer l’application de cluster-source vers cluster-cible.

# 1. Sur le cluster source — backup
velero backup create migration-backup \
  --include-namespaces mon-app \
  --default-volumes-to-fs-backup \
  --wait

# 2. Sur le cluster cible — configurer le même BackupStorageLocation
# (pointant sur le même bucket S3)
velero backup-location create source-cluster \
  --provider aws \
  --bucket velero-backups-xxxx \
  --config region=us-east-1,s3Url=https://... \
  --access-mode ReadOnly    # Lecture seule sur le bucket source

# 3. Synchroniser les backups disponibles
velero backup-location get

# 4. Restaurer sur le cluster cible
velero restore create migrate-mon-app \
  --from-backup migration-backup \
  --wait

Hooks pre/post backup pour la cohérence applicative

Pour les bases de données, utiliser des hooks pour flusher les données avant le snapshot :

apiVersion: apps/v1
kind: Deployment
metadata:
  name: postgresql
  namespace: production
  annotations:
    # Quiescer la DB avant le backup
    pre.hook.backup.velero.io/command: >
      ["/bin/bash", "-c", "psql -U postgres -c 'CHECKPOINT;'"]
    pre.hook.backup.velero.io/container: postgresql
    pre.hook.backup.velero.io/on-error: Fail
    pre.hook.backup.velero.io/timeout: 60s
    # Reprendre après le backup
    post.hook.backup.velero.io/command: >
      ["/bin/bash", "-c", "echo 'backup complete'"]
    post.hook.backup.velero.io/container: postgresql

Conclusion

Velero est l’outil incontournable pour la protection des données et la résilience des clusters Kubernetes/OpenShift. Sa flexibilité (backup ressources, snapshots CSI, Kopia pour les volumes) et son intégration avec les stockages S3 en font une solution adaptée aussi bien aux PME (avec MinIO ou ODF NooBaa) qu’aux grandes entreprises (AWS S3, Azure Blob). Combiné à des schedules automatiques et des hooks applicatifs, Velero garantit des RTO/RPO maîtrisés pour vos workloads critiques.