For AI agents: the complete documentation index is available at https://docs.ovhcloud.com/fr/llms.txt, the full documentation bundle is available at https://docs.ovhcloud.com/fr/llms-full.txt, and this page is available as Markdown at https://docs.ovhcloud.com/fr/guides/public-cloud/containers-orchestration/managed-kubernetes/backup-restore-pv-volume-snapshot.md.

Sauvegarder et restaurer votre Persistent Volume avec les Volume Snapshots sur OVHcloud Managed Kubernetes

Voir en Markdown

Découvrez comment sauvegarder et restaurer votre Persistent Volume avec les Volume Snapshots sur OVHcloud Managed Kubernetes

Dans ce tutoriel, nous utilisons les Volume Snapshots Kubernetes pour sauvegarder et restaurer des volumes persistants sur un cluster OVHcloud Managed Kubernetes.

Les Volume Snapshots sont une fonctionnalité Kubernetes passée en disponibilité générale (GA) avec Kubernetes 1.20.

Ils permettent de créer un « instantané » (snapshot) d'un volume persistant. Un snapshot représente une copie d'un volume à un instant donné. Un snapshot peut être utilisé soit pour réhydrater un nouveau volume (pré-rempli avec les données du snapshot), soit pour restaurer un volume existant à un état antérieur (représenté par le snapshot).

Avant de commencer

Ce tutoriel suppose que vous disposez déjà d'un cluster OVHcloud Managed Kubernetes opérationnel, ainsi que de connaissances de base sur son fonctionnement. Pour en savoir plus sur ces sujets, veuillez consulter le guide de démarrage rapide OVHcloud Managed Kubernetes Service.

Ce tutoriel suppose également que vous êtes familiarisé avec les Persistent Volumes Kubernetes. Vous devez également savoir comment les PV sont gérés sur le service OVHcloud Managed Kubernetes. Veuillez consulter le guide Persistent Volumes sur OVHcloud Managed Kubernetes.

En pratique

Mise en place

Dans ce guide, nous allons utiliser un exemple simple : un petit serveur web Nginx avec un PersistentVolume.

Créez un fichier nommé nginx-example-with-pv.yml avec le contenu suivant :

---
apiVersion: v1
kind: Namespace
metadata:
  name: nginx-example
  labels:
    app: nginx
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: nginx-logs
  namespace: nginx-example
  labels:
    app: nginx
spec:
  storageClassName: csi-cinder-high-speed
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  namespace: nginx-example
spec:
  strategy:
    type: Recreate
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      volumes:
        - name: nginx-logs
          persistentVolumeClaim:
            claimName: nginx-logs
      containers:
        - image: nginx:1.7.9
          name: nginx
          ports:
            - containerPort: 80
          volumeMounts:
            - mountPath: "/var/log/nginx"
              name: nginx-logs
              readOnly: false
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: nginx
  name: nginx-service
  namespace: nginx-example
spec:
  ports:
    - port: 80
      targetPort: 80
  selector:
    app: nginx
  type: LoadBalancer

Puis appliquez-le au cluster :

kubectl apply -f nginx-example-with-pv.yml
Info

Si vous regardez attentivement la partie deployment de ce manifeste, vous remarquerez que nous avons défini un .spec.strategy.type. Il spécifie la stratégie utilisée pour remplacer les anciens pods par de nouveaux, et nous l'avons défini sur Recreate, afin que tous les pods existants soient supprimés avant que de nouveaux ne soient créés.

Nous procédons ainsi car la Storage Class que nous utilisons, csi-cinder-high-speed, ne prend en charge que le mode ReadWriteOnce : nous ne pouvons donc avoir qu'un seul pod en écriture sur le Persistent Volume à un instant donné.

Attendez d'obtenir une IP externe :

kubectl -n nginx-example get svc nginx-service -w

Lorsque vous disposez d'une IP externe de Load Balancer, enregistrez-la :

export LB_IP=$(kubectl -n nginx-example get svc nginx-service -o jsonpath='{.status.loadBalancer.ingress[0].ip}')

Puis effectuez quelques appels vers l'URL pour générer des logs d'accès :

curl -I $LB_IP

Nous devons maintenant nous connecter au pod pour lire le fichier de logs et vérifier que nos logs sont bien écrits.

Récupérez d'abord le nom du pod Nginx en cours d'exécution :

export POD_NAME=$(kubectl get po -n nginx-example -o name)

Puis connectez-vous à celui-ci et consultez vos logs d'accès :

kubectl -n nginx-example exec $POD_NAME -c nginx -- cat /var/log/nginx/access.log
Info

Les Volume Snapshots fonctionnent avec toutes les Storage Classes, y compris les volumes chiffrés LUKS (csi-cinder-high-speed-luks, csi-cinder-classic-luks, csi-cinder-high-speed-gen2-luks). Le chiffrement est maintenu de façon transparente pendant les opérations de snapshot et de restauration.

Vous devriez obtenir un résultat semblable à celui-ci :

$ kubectl apply -f nginx-example-with-pv.yml
namespace/nginx-example created
persistentvolumeclaim/nginx-logs created
deployment.apps/nginx-deployment created
service/nginx-service created

$ kubectl -n nginx-example get svc nginx-service -w

NAME            TYPE           CLUSTER-IP   EXTERNAL-IP   PORT(S)        AGE
nginx-service   LoadBalancer   10.3.28.41   <pending>     80:32675/TCP   4s
nginx-service   LoadBalancer   10.3.28.41   <pending>     80:32675/TCP   91s
nginx-service   LoadBalancer   10.3.28.41   135.125.XX.XXX   80:32675/TCP   91s
nginx-service   LoadBalancer   10.3.28.41   135.125.XX.XXX   80:32675/TCP   95s

$ export LB_IP=$(kubectl -n nginx-example get svc nginx-service -o jsonpath='{.status.loadBalancer.ingress[0].ip}')

$ echo $LB_IP
135.125.XX.XXX

$ curl -I $LB_IP
HTTP/1.1 200 OK
Server: nginx/1.7.9
Date: Mon, 26 Sep 2022 06:56:32 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 23 Dec 2014 16:25:09 GMT
Connection: keep-alive
ETag: "54999765-264"
Accept-Ranges: bytes

$ curl -I $LB_IP
HTTP/1.1 200 OK
Server: nginx/1.7.9
Date: Mon, 26 Sep 2022 06:56:33 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 23 Dec 2014 16:25:09 GMT
Connection: keep-alive
ETag: "54999765-264"
Accept-Ranges: bytes

$ export POD_NAME=$(kubectl get po -n nginx-example -o name)

$ echo $POD_NAME
pod/nginx-deployment-5bfc8c9f6f-zplsl

$ kubectl -n nginx-example exec $POD_NAME -c nginx -- cat /var/log/nginx/access.log

10.2.0.0 - - [26/Sep/2022:06:56:32 +0000] "HEAD / HTTP/1.1" 200 0 "-" "curl/7.64.1" "-"
141.94.164.46 - - [26/Sep/2022:06:56:33 +0000] "HEAD / HTTP/1.1" 200 0 "-" "curl/7.64.1" "-"

Créer un snapshot

Créez un VolumeSnapshot dans un fichier nginx-example-snapshot.yml avec le contenu suivant :

apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
  name: nginx-snapshot
  namespace: nginx-example
spec:
  volumeSnapshotClassName: csi-cinder-snapclass-in-use-v1
  source:
    persistentVolumeClaimName: nginx-logs 

Puis appliquez-le :

kubectl apply -f nginx-example-snapshot.yml

Vous devriez obtenir un résultat semblable à celui-ci :

$ kubectl apply -f nginx-example-snapshot.yml

volumesnapshot.snapshot.storage.k8s.io/nginx-snapshot created

$ kubectl -n nginx-example get VolumeSnapshot
NAME             READYTOUSE   SOURCEPVC    SOURCESNAPSHOTCONTENT   RESTORESIZE   SNAPSHOTCLASS                    SNAPSHOTCONTENT                                    CREATIONTIME   AGE
nginx-snapshot   true         nginx-logs                           1Gi           csi-cinder-snapclass-in-use-v1   snapcontent-131c751e-5cdb-4575-b0c0-538273c67d36   5m20s          5m20s

Simuler un sinistre

Simulons un scénario de sinistre, en supprimant les fichiers de logs de la PVC :

kubectl -n nginx-example exec $POD_NAME -c nginx -- rm /var/log/nginx/access.log
kubectl -n nginx-example exec $POD_NAME -c nginx -- ls -al /var/log/nginx/

Vous devriez obtenir un résultat semblable à celui-ci :

$ kubectl -n nginx-example exec $POD_NAME -c nginx -- rm /var/log/nginx/access.log
kubectl -n nginx-example exec $POD_NAME -c nginx -- ls -al /var/log/nginx/

total 24
drwxr-xr-x 3 root root  4096 Sep 26 07:10 .
drwxr-xr-x 1 root root  4096 Jan 27  2015 ..
-rw-r--r-- 1 root root     0 Sep 26 06:54 error.log
drwx------ 2 root root 16384 Sep 26 06:54 lost+found

Restaurer le volume

Pour restaurer un snapshot donné, vous devez supprimer la PVC d'origine puis la recréer à partir du snapshot.

Réduisez le déploiement à 0 réplique et supprimez la PVC d'origine :

kubectl -n nginx-example scale deployment/nginx-deployment --replicas=0 
kubectl -n nginx-example delete pvc nginx-logs

Créez ensuite un fichier nginx-example-restore.yml avec le contenu suivant :

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nginx-logs
  namespace: nginx-example
  labels:
    app: nginx
spec:
  dataSource:
    name: nginx-snapshot
    kind: VolumeSnapshot
    apiGroup: snapshot.storage.k8s.io
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi

Puis appliquez-le :

kubectl apply -f nginx-example-restore.yml

Vérifiez que la PVC est restaurée :

kubectl -n nginx-example get pvc

Le volume doit avoir un statut égal à Bound. Vous pouvez maintenant restaurer le déploiement à sa valeur de réplique de 1, et attendre que le pod repasse à l'état Running :

kubectl -n nginx-example scale deployment/nginx-deployment --replicas=1 
kubectl -n nginx-example get pods -w

Vous pouvez maintenant vérifier que le fichier access.log est de nouveau présent et que son contenu est toujours là :

export POD_NAME=$(kubectl get po -n nginx-example -o name)
echo $POD_NAME

kubectl -n nginx-example exec $POD_NAME -c nginx -- ls -al /var/log/nginx/
kubectl -n nginx-example exec $POD_NAME -c nginx -- cat /var/log/nginx/access.log

Vous devriez obtenir un résultat semblable à celui-ci :

$ kubectl -n nginx-example scale deployment/nginx-deployment --replicas=0
kubectl -n nginx-example delete pvc nginx-logs
deployment.apps/nginx-deployment scaled
persistentvolumeclaim "nginx-logs" deleted

$ vi nginx-example-restore.yml

$ kubectl apply -f nginx-example-restore.yml

persistentvolumeclaim/nginx-logs created

$ kubectl -n nginx-example get pvc

NAME         STATUS   VOLUME                                                                   CAPACITY   ACCESS MODES   STORAGECLASS            AGE
nginx-logs   Bound    ovh-managed-kubernetes-dmhe43-pvc-d5c65ae2-e9fd-48a9-8c29-d69cdd464f59   1Gi        RWO            csi-cinder-high-speed   7s

$ kubectl -n nginx-example scale deployment/nginx-deployment --replicas=1
kubectl -n nginx-example get pods -w
deployment.apps/nginx-deployment scaled
NAME                                READY   STATUS              RESTARTS   AGE
nginx-deployment-5bfc8c9f6f-m627t   0/1     ContainerCreating   0          0s
nginx-deployment-5bfc8c9f6f-m627t   0/1     ContainerCreating   0          7s
nginx-deployment-5bfc8c9f6f-m627t   1/1     Running             0          10s

$ export POD_NAME=$(kubectl get po -n nginx-example -o name)
$ echo $POD_NAME
pod/nginx-deployment-5bfc8c9f6f-m627t

$ kubectl -n nginx-example exec $POD_NAME -c nginx -- ls -al /var/log/nginx/

total 28
drwxr-xr-x 3 root root  4096 Sep 26 06:54 .
drwxr-xr-x 1 root root  4096 Jan 27  2015 ..
-rw-r--r-- 1 root root   181 Sep 26 06:56 access.log
-rw-r--r-- 1 root root     0 Sep 26 06:54 error.log
drwx------ 2 root root 16384 Sep 26 06:54 lost+found

$ kubectl -n nginx-example exec $POD_NAME -c nginx -- cat /var/log/nginx/access.log

10.2.0.0 - - [26/Sep/2022:06:56:32 +0000] "HEAD / HTTP/1.1" 200 0 "-" "curl/7.64.1" "-"
141.94.164.46 - - [26/Sep/2022:06:56:33 +0000] "HEAD / HTTP/1.1" 200 0 "-" "curl/7.64.1" "-"

Suppression (nettoyage)

À la fin, vous pouvez procéder au nettoyage en supprimant l'ensemble des éléments. Supprimez le namespace nginx-example :

kubectl delete namespace nginx-example

Aller plus loin

  • Pour une formation ou une assistance technique sur la mise en œuvre de nos solutions, contactez votre commercial ou consultez la page Professional Services pour obtenir un devis et faire analyser votre projet par nos experts.

  • Échangez avec notre communauté d'utilisateurs.

Cette page vous a-t-elle aidé ?