-
Notifications
You must be signed in to change notification settings - Fork 152
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add example blueprint for CSI snapshot functions (#1184)
* style: Add CSI Snapshot funcs MySQL example blueprint * style: Updates in the example README * style: Update title * style: typo in Prerequisites * style: Fix multiple typos * style: Update helm command * style: Fix title, blueprint note and 'Backup application data' descripion * style: Remove unnecessary quotation marks * style: Update blueprint note * fix: Update create blueprint command * style: fix grammatical typos and readme header syntax * style: Fix create blueprint note with correct blueprint file name * style: Update README as per reviewer comments * style: Explain --pvc argument * style: Update introduction as per reviewer comment * Update example README as per reviewer comments * Update KubeOps function to allow create & delete for core group resources * Add test case for KubeOps Delete core group resource * Remove core group permissions from clusterrole * Update KubeOps Delete operation to wait for resource to be deleted * Update testcase for kubeops delete on core group resource * Update KubeOps test to use existing svc spec * Update poll.Wait logic for waiting on delete operation to complete * Fix gofmt issues * Update wait.Poll to poll.Wait method & pass context from parent * Update as per reviewer comments * Update example with Time Log application * Replace namespace mysql with time-log * Handle error from Delete() and add comment for using poll.Wait() * Add waitForResourceDeletion function * Remove redundant check for error * Revert createPhase method in kubeops_test.go * Update KubeOps test * Update README as per reviewer comments * Add comment to explain the waitForResourceDeletion function * Update comment for waitForResourceDeletion Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> Co-authored-by: Pavan Navarathna <pavan@kasten.io>
- Loading branch information
1 parent
abfbcbd
commit 54f7705
Showing
2 changed files
with
218 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
# Backup and restore using CSI VolumeSnapshot | ||
|
||
## Introduction | ||
VolumeSnapshots provide Kubernetes users with a standardized way to copy a volume's contents at a particular point in time without creating an entirely new volume. This functionality enables, for example, database administrators to backup databases before performing edit or delete modifications. | ||
This example demonstrates Kanister's ability to protect an application called Time-Logger using CSI VolumeSnapshots. Time-Logger application is contrived but useful for demonstrating Kanister's features. The application appends the current time to a log file every second. | ||
|
||
## Prerequisites | ||
|
||
- Helm 3 installed | ||
- Kubernetes 1.16+ with Beta APIs enabled | ||
- Kanister controller version 0.72.0 installed in the cluster, let's assume in namespace `kanister` | ||
- Kanctl CLI installed (https://docs.kanister.io/tooling.html#install-the-tools) | ||
- VolumeSnapshot CRDs, Snapshot Controller & a CSI Driver | ||
|
||
## Install application | ||
|
||
Install Time-Logger application. | ||
|
||
```bash | ||
# Create namespace | ||
$ kubectl create namespace time-log | ||
|
||
# Create the Deployment and PersistentVolumeClaim in time-log namespace | ||
$ kubectl -n time-log create -f ./examples/time-log/time-logger-deployment.yaml | ||
|
||
# Run a shell inside time-logger deployment's pod | ||
$ kubectl exec -it $(kubectl get pods -n time-log -l app=time-logger -o=jsonpath='{.items[0].metadata.name}') -n time-log -- /bin/bash | ||
|
||
# Make note of the first entry recorded in the /var/log/time.log | ||
$ head --lines=1 /var/log/time.log | ||
Sun Jan 23 08:54:39 UTC 2022 | ||
``` | ||
|
||
## Protect the Application | ||
|
||
### Create Blueprint | ||
|
||
Create the Blueprint in `kanister` namespace | ||
|
||
> **Note**: This example uses a Kubernetes cluster on DigitalOcean. Therefore the `snapshotClass` and `storageClass` in the following `./examples/stable/csi-snapshot/csi-snapshot-blueprint.yaml` file are set to `do-block-storage`. Change the arguments appropriately before creating the blueprint. | ||
```bash | ||
$ kubectl create -f ./examples/stable/csi-snapshot/csi-snapshot-blueprint.yaml -n kanister | ||
``` | ||
|
||
### Backup the application data | ||
|
||
Create a snapshot of application data using `backup` action defined in blueprint. One of the easiest ways to do so is by using `kanctl` utility. | ||
|
||
```bash | ||
# Create Actionset | ||
# Make sure the value of blueprint matches the name of blueprint created earlier | ||
|
||
$ kanctl create actionset --action backup --namespace kanister --blueprint csi-snapshot-bp --deployment time-log/time-logger | ||
actionset backup-mlvcv created | ||
|
||
$ kubectl --namespace kanister get actionset | ||
NAME AGE | ||
backup-mlvcv 112s | ||
|
||
# View the status of the actionset | ||
# Make sure the name of the actionset here matches the name of the actionset created above | ||
$ kubectl --namespace kanister describe actionset backup-mlvcv | ||
|
||
# Check the CSI VolumeSnapshot created | ||
$ kubectl -n time-log get volumesnapshot | ||
NAME READYTOUSE SOURCEPVC SOURCESNAPSHOTCONTENT RESTORESIZE SNAPSHOTCLASS SNAPSHOTCONTENT CREATIONTIME AGE | ||
time-log-pvc-snapshot-nxj4g true time-log-pvc 1Gi do-block-storage snapcontent-13bc2d1c-6717-47a2-a0b7-4a2f76bd2cb4 58s 58s | ||
``` | ||
|
||
## Disaster strikes! | ||
|
||
Let's say someone accidentally deleted the log file at path `/var/log` | ||
|
||
```bash | ||
# Run a shell inside time-logger deployment's pod | ||
$ kubectl exec -it $(kubectl get pods -n time-log -l app=time-logger -o=jsonpath='{.items[0].metadata.name}') -n time-log -- /bin/bash | ||
|
||
# Remove the log file | ||
$ rm /var/log/time.log | ||
|
||
# Check the first entry recorded in the /var/log/time.log again. It is now replaced with a new entry. | ||
# This is because Time-Logger app recreates the log file once it's deleted and starts adding newer entries to it. | ||
$ head --lines=1 /var/log/time.log | ||
Sun Jan 23 09:15:43 UTC 2022 | ||
``` | ||
|
||
## Restore application | ||
|
||
Use the backup created earlier to restore the application data. This can be achieved using `kanctl` again by creating the restore action. | ||
|
||
```bash | ||
# Make sure to use correct backup actionset name here | ||
$ kanctl --namespace kanister create actionset --action restore --from backup-mlvcv | ||
actionset restore-backup-mlvcv-6z9xn created | ||
|
||
# Use the following command to check events in the actionset | ||
$ kubectl --namespace kanister describe actionset restore-backup-mlvcv-6z9xn | ||
``` | ||
|
||
## Verify the restored application data | ||
|
||
To verify restore action, check the first entry of the file `/var/log/time.log` and confirm that it's been restored with the original value. | ||
|
||
```bash | ||
# Run a shell inside time-logger deployment's pod | ||
$ kubectl exec -it $(kubectl get pods -n time-log -l app=time-logger -o=jsonpath='{.items[0].metadata.name}') -n time-log -- /bin/bash | ||
|
||
$ head --lines=1 /var/log/time.log | ||
Sun Jan 23 08:54:39 UTC 2022 | ||
``` | ||
|
||
## Delete the Artifacts | ||
|
||
The CSI VolumeSnapshot created by the backup action can be cleaned up using the following command. | ||
|
||
```bash | ||
# Make sure to use correct backup actionset name here | ||
$ kanctl --namespace kanister create actionset --action delete --from backup-mlvcv | ||
actionset delete-backup-mlvcv-cq6bw created | ||
|
||
# View the status of the ActionSet | ||
$ kubectl --namespace kanister describe actionset delete-backup-glptq-cq6bw | ||
``` | ||
|
||
## Cleanup | ||
|
||
### Uninstalling the application | ||
|
||
To uninstall the application delete `time-log` namespace. | ||
|
||
```bash | ||
# Remove time-log namespace | ||
$ kubectl delete namespace time-log | ||
``` | ||
|
||
### Delete CRs | ||
|
||
Remove the blueprint. | ||
|
||
```bash | ||
$ kubectl delete blueprints.cr.kanister.io csi-snapshot-bp -n kanister | ||
``` | ||
|
||
Remove the actionsets. | ||
|
||
```bash | ||
$ kubectl delete actionsets -n kanister --all | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
apiVersion: cr.kanister.io/v1alpha1 | ||
kind: Blueprint | ||
metadata: | ||
name: csi-snapshot-bp | ||
actions: | ||
backup: | ||
outputArtifacts: | ||
snapshotInfo: | ||
keyValue: | ||
name: "{{ .Phases.createCSISnapshot.Output.name }}" | ||
pvc: "{{ .Phases.createCSISnapshot.Output.pvc }}" | ||
namespace: "{{ .Phases.createCSISnapshot.Output.namespace }}" | ||
restoreSize: "{{ .Phases.createCSISnapshot.Output.restoreSize }}" | ||
snapshotContent: "{{ .Phases.createCSISnapshot.Output.snapshotContent }}" | ||
phases: | ||
- func: CreateCSISnapshot | ||
name: createCSISnapshot | ||
args: | ||
pvc: "{{ (index .Object.spec.template.spec.volumes 0).persistentVolumeClaim.claimName }}" | ||
namespace: "{{ .Object.metadata.namespace }}" | ||
snapshotClass: do-block-storage | ||
restore: | ||
inputArtifactNames: | ||
- snapshotInfo | ||
phases: | ||
- func: ScaleWorkload | ||
name: scaleDownSS | ||
args: | ||
name: "{{ .Deployment.Name }}" | ||
namespace: "{{ .Deployment.Namespace }}" | ||
kind: deployment | ||
replicas: 0 | ||
- func: KubeOps | ||
name: deleteOriginalPVC | ||
args: | ||
operation: delete | ||
namespace: "{{ .ArtifactsIn.snapshotInfo.KeyValue.namespace }}" | ||
objectReference: | ||
apiVersion: v1 | ||
group: "" | ||
resource: persistentvolumeclaims | ||
name: "{{ .ArtifactsIn.snapshotInfo.KeyValue.pvc }}" | ||
namespace: "{{ .ArtifactsIn.snapshotInfo.KeyValue.namespace }}" | ||
- func: RestoreCSISnapshot | ||
name: restorePVCFromSnapshot | ||
args: | ||
name: "{{ .ArtifactsIn.snapshotInfo.KeyValue.name }}" | ||
pvc: "{{ .ArtifactsIn.snapshotInfo.KeyValue.pvc }}" | ||
namespace: "{{ .ArtifactsIn.snapshotInfo.KeyValue.namespace }}" | ||
storageClass: do-block-storage | ||
restoreSize: "{{ .ArtifactsIn.snapshotInfo.KeyValue.restoreSize }}" | ||
accessModes: ["ReadWriteOnce"] | ||
volumeMode: "Filesystem" | ||
- func: ScaleWorkload | ||
name: scaleUpSS | ||
args: | ||
name: "{{ .Deployment.Name }}" | ||
namespace: "{{ .Deployment.Namespace }}" | ||
kind: deployment | ||
replicas: 1 | ||
delete: | ||
inputArtifactNames: | ||
- snapshotInfo | ||
phases: | ||
- func: DeleteCSISnapshot | ||
name: deleteCSISnapshot | ||
args: | ||
name: "{{ .ArtifactsIn.snapshotInfo.KeyValue.name }}" | ||
namespace: "{{ .ArtifactsIn.snapshotInfo.KeyValue.namespace }}" |