Generic Backup and Restore¶
Applications can often be deployed using non-shared storage (e.g., local SSDs) or on systems where K10 does not currently support the underlying storage provider. To protect data in these scenarios, K10 with Kanister gives you the ability, with extremely minor application modifications to add functionality to backup, restore, and migrate this application data in an efficient and transparent manner.
While a complete example is provided below, the only change needed is the addition of a sidecar to your application deployment that can mount the application data volume. An example, where /data is used as an sample mount path, can be seen in the below specification. Note that the sidecar must be named kanister-sidecar and you should pin the version of the image to the latest Kanister release.
- name: kanister-sidecar image: kanisterio/kanister-tools:0.28.0 command: ["bash", "-c"] args: - "tail -f /dev/null" volumeMounts: - name: data mountPath: /data
Once the above change is made, K10 will be able to automatically extract data and, via tools such as Restic, able to efficiently deduplicate data and transfer it into an object store.
If you have multiple volumes used by your pod, you simply need to mount them all within this sidecar container. There is no naming requirement on the mount path as long as they are unique.
The below section provides a complete end-to-end example of how to extend your application to support file-system level backup and restore. A dummy application is used as an example below but it should be straightforward to extend this example.
Deploy the application¶
The following specification contains a complete example of how to exercise generic backup and restore functionality. It consists of a an application Deployment that use a Persistent Volume Claim (mounted internally at /data) for storing data. Two containers are used in this example: the regular application container and a sidecar. The sidecar container includes Kanister-provided tools and, as specified above, also has access to the same volume for data extraction and insertion.
Saving the below specification as a file,
recommended for reuse later.
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: demo-pvc labels: app: demo pvc: demo spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi --- apiVersion: extensions/v1beta1 kind: Deployment metadata: name: demo-app labels: app: demo spec: template: metadata: labels: app: demo spec: containers: - name: demo-container image: alpine:3.7 resources: requests: memory: 256Mi cpu: 100m command: ["tail"] args: ["-f", "/dev/null"] volumeMounts: - name: data mountPath: /data - name: kanister-sidecar image: kanisterio/kanister-tools:0.28.0 command: ["tail"] args: ["-f", "/dev/null"] volumeMounts: - name: data mountPath: /data volumes: - name: data persistentVolumeClaim: claimName: demo-pvc
Deploy the above application as follows:
# Deploying in a specific namespace $ kubectl create namespace <namespace> $ kubectl apply --namespace=<namespace> -f deployment.yaml
Create a Kanister Profile¶
If you haven't done so already, create a Kanister profile with the appropriate Location and Credentials information from the K10 settings page.
The easiest way to insert data into the demo application is to simply copy it in:
# Get pods for the demo application from its namespace $ kubectl get pods --namespace=<namespace> | grep demo-app # Copy required data manually into the pod $ kubectl cp <file-name> <namespace>/<pod>:/data/ # Verify if the data was copied successfully $ kubectl exec --namespace=<namespace> <pod> -- ls -l /data
Backup the application data either by creating a Policy or running a Manual Backup from K10. This assumes that the application is running on a system where K10 does not support the provisioned disks (e.g., local storage).
To destroy the data manually, run the following command:
# Using kubectl $ kubectl exec --namespace=<namespace> <pod> -- rm -rf /data/*
Alternatively, the application and the PVC can be deleted and recreated.
Restore the data using K10 by selecting the appropriate restore point.
After restore, you should verify that the data is intact. One way to verify this is to use MD5 checksum tool.
# MD5 on the original file copied $ md5 <file-name> # Copy the restored data back to local env $ kubectl get pods --namespace=<namespace> | grep demo-app $ kubectl cp <namespace>/<pod>:/data/<filename> <new-filename> # MD5 on the new file $ md5 <new-filename>
The MD5 checksums should match.
Force Generic Snapshot¶
Even when snapshot support from the storage provider is available, generic
backups can be enforced by adding the
annotation to the workload as shown in the example below.
Note that the Kanister sidecar and Kanister profile must both be present for generic snapshot to work.
apiVersion: extensions/v1beta1 kind: Deployment metadata: name: demo-app labels: app: demo annotations: k10.kasten.io/forcegenericbackup: "true"
The following is a
kubectl example to add the annotation to a running
# Add annotation to force generic backups $ kubectl annotate deployment <deployment-name> k10.kasten.io/forcegenericbackup="true" --namespace=<namespace-name>