Restore to Mayastor

Before you begin, make sure you have the following:

  • Access to a Kubernetes cluster with Velero installed.

  • A backup of your Mongo database created using Velero.

  • Mayastor configured in your Kubernetes environment.

Step 1: Install Velero with GCP Provider on Destination (Mayastor Cluster)

Install Velero with the GCP provider, ensuring you use the same values for the BUCKET-NAME and SECRET-FILENAME placeholders that you used originally. These placeholders should be replaced with your specific values:

velero install --use-node-agent --provider gcp --plugins velero/velero-plugin-for-gcp:v1.6.0 --bucket BUCKET-NAME --secret-file SECRET-FILENAME --uploader-type restic

Step 2: Verify Backup Availability

Check the availability of your previously-saved backups. If the credentials or bucket information doesn't match, you won't be able to see the backups:

velero get backup | grep 13-09-23
kubectl get backupstoragelocation -n velero

Step 3: Restore Using Velero CLI

Initiate the restore process using Velero CLI with the following command:

velero restore create mongo-restore-13-09-23 --from-backup mongo-backup-13-09-23

Step 4: Check Restore Status

You can check the status of the restore process by using the velero get restore command.

velero get restore

When Velero performs a restore, it deploys an init container within the application pod, responsible for restoring the volume. Initially, the restore status will be InProgress.

Your storage class was originally set to cstor-csi-disk because you imported this PVC from a cStor volume, the status might temporarily stay as In Progress and your PVC will be in Pending status.

Step 5: Backup PVC and Change Storage Class

  • Retrieve the current configuration of the PVC which is in Pending status using the following command:

kubectl get pvc mongodb-persistent-storage-claim-mongod-0 -o yaml > pvc-mongo.yaml
  • Confirm that the PVC configuration has been saved by checking its existence with this command:

ls -lrt | grep pvc-mongo.yaml
  • Edit the pvc-mongo.yaml file to update its storage class. Below is the modified PVC configuration with mayastor-single-replica set as the new storage class:

The statefulset for Mongo will still have the cstor-csi-disk storage class at this point. This will be addressed in the further steps.

apiVersion: v1
kind: PersistentVolumeClaim
    role: mongo mongo-backup-13-09-23 mongo-restore-13-09-23
  name: mongodb-persistent-storage-claim-mongod-0
  namespace: default
  - ReadWriteOnce
      storage: 3Gi
  storageClassName: mayastor-single-replica
  volumeMode: Filesystem

Step 6: Resolve issue where PVC is in a Pending

  • Begin by deleting the problematic PVC with the following command:

kubectl delete pvc mongodb-persistent-storage-claim-mongod-0
  • Once the PVC has been successfully deleted, you can recreate it using the updated configuration from the pvc-mongo.yaml file. Apply the new configuration with the following command:

kubectl apply -f pvc-mongo.yaml

Step 7: Check Velero init container

After recreating the PVC with Mayastor storageClass, you will observe the presence of a Velero initialization container within the application pod. This container is responsible for restoring the required volumes.

You can check the status of the restore operation by running the following command:

kubectl describe pod <enter_your_pod_name>

The output will display the pods' status, including the Velero initialization container. Initially, the status might show as "Init:0/1," indicating that the restore process is in progress.

You can track the progress of the restore by running:

velero get restore

You can then verify the data restoration by accessing your MongoDB instance. In the provided example, we used the "mongosh" shell to connect to the MongoDB instance and check the databases and their content. The data should reflect what was previously backed up from the cStor storage.

mongosh mongodb://admin:admin@mongod-0.mongodb-service.default.svc.cluster.local:27017

Step 8: Monitor Pod Progress

Due to the statefulset's configuration with three replicas, you will notice that the mongo-1 pod is created but remains in a Pending status. This behavior is expected as we have the storage class set to cStor in statefulset configuration.

Step 9: Capture the StatefulSet Configuration and Modify Storage Class

Capture the current configuration of the StatefulSet for MongoDB by running the following command:

kubectl get sts mongod -o yaml > sts-mongo-original.yaml

This command will save the existing StatefulSet configuration to a file named sts-mongo-original.yaml. Next, edit this YAML file to change the storage class to mayastor-single-replica.

apiVersion: apps/v1
kind: StatefulSet
  annotations: mongodb-persistent-storage-claim mongo default
  generation: 1
  labels: Helm mongo-backup-13-09-23 mongo-restore-13-09-23
  name: mongod
  namespace: default
  podManagementPolicy: OrderedReady
  replicas: 3
  revisionHistoryLimit: 10
      role: mongo
  serviceName: mongodb-service
      creationTimestamp: null
        environment: test
        replicaset: rs0
        role: mongo
      - command:
        - mongod
        - --bind_ip
        - --replSet
        - rs0
              key: username
              name: secrets
              key: password
              name: secrets
        image: mongo:latest
        imagePullPolicy: Always
              - /bin/sh
              - -c
              - sleep 90 ; ./tmp/scripts/  > /tmp/script-log
        name: mongod-container
        - containerPort: 27017
          protocol: TCP
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
        - mountPath: /data/db
          name: mongodb-persistent-storage-claim
        - mountPath: /tmp/scripts
          name: mongo-scripts
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 10
      - configMap:
          defaultMode: 511
          name: mongo-replica
        name: mongo-scripts
    type: RollingUpdate
  - apiVersion: v1
    kind: PersistentVolumeClaim
      annotations: mayastor-single-replica #Make the change here
      creationTimestamp: null
      name: mongodb-persistent-storage-claim
      - ReadWriteOnce
          storage: 3Gi
      volumeMode: Filesystem

Step 10: Delete StatefulSet (Cascade=False)

Delete the StatefulSet while preserving the pods with the following command:

kubectl delete sts mongod --cascade=false

You can run the following commands to verify the status:

kubectl get sts
kubectl get pods
kubectl get pvc

Step 11: Deleting Pending Secondary Pods and PVCs

Delete the MongoDB Pod mongod-1.

kubectl delete pod mongod-1

Delete the Persistent Volume Claim (PVC) for mongod-1.

kubectl delete pvc mongodb-persistent-storage-claim-mongod-1

Step 12: Recreate StatefulSet

Recreate the StatefulSet with the Yaml file.

kubectl apply -f sts-mongo-mayastor.yaml
kubectl get pods
kubectl mayastor get volumes

Step 13: Verify Data Replication on Secondary DB

Verify data replication on the secondary database to ensure synchronization.

root@mongod-1:/# mongosh mongodb://admin:admin@mongod-1.mongodb-service.default.svc.cluster.local:27017 
Current Mongosh Log ID: 6501c744eb148521b3716af5
Connecting to:          mongodb://<credentials>@mongod-1.mongodb-service.default.svc.cluster.local:27017/?directConnection=true&appName=mongosh+1.10.6
Using MongoDB:          7.0.1
Using Mongosh:          1.10.6

For mongosh info see:

   The server generated these startup warnings when booting
   2023-09-13T14:19:37.984+00:00: Using the XFS filesystem is strongly recommended with the WiredTiger storage engine. See
   2023-09-13T14:19:38.679+00:00: Access control is not enabled for the database. Read and write access to data and configuration is unrestricted
   2023-09-13T14:19:38.679+00:00: You are running this process as the root user, which is not recommended
   2023-09-13T14:19:38.679+00:00: vm.max_map_count is too low

rs0 [direct: secondary] test> use mydb 
switched to db mydb
rs0 [direct: secondary] mydb> db.getMongo().setReadPref('secondary')

rs0 [direct: secondary] mydb> db.accounts.find()
    _id: ObjectId("65019e2f183959fbdbd23f00"),
    name: 'john',
    total: '1058'
    _id: ObjectId("65019e2f183959fbdbd23f01"),
    name: 'jane',
    total: '6283'
    _id: ObjectId("65019e31183959fbdbd23f02"),
    name: 'james',
    total: '472'
rs0 [direct: secondary] mydb> 

Last updated