This tutorial will show you how to use Stash to backup and restore a Kubernetes volume in Rook storage service. Here, we are going to backup the /source/data
folder of a busybox pod into AWS S3 compatible Rook Object Storage. Then, we will show how to recover this data into a PersistentVolumeClaim
of Rook Block Storage. We will also re-deploy deployment using this recovered volume.
At first, you need to have a Kubernetes cluster, and the kubectl command-line tool must be configured to communicate with your cluster. If you do not already have a cluster, you can create one by using Minikube. Now, install Stash
in your cluster following the steps here.
You should have understanding the following Stash concepts:
Then, you will need to have a Rook Storage Service with Object Storage and Block Storage configured. If you do not already have a Rook Storage Service configured, you can create one by following this quickstart guide.
First, deploy the following busybox
Deployment in your cluster. Here we are using a git repository as a source volume for demonstration purpose.
$ kubectl apply -f ./docs/examples/tutorial/busybox.yaml
deployment "stash-demo" created
Definition of busybox
deployment:
apiVersion: apps/v1beta1
kind: Deployment
metadata:
labels:
app: stash-demo
name: stash-demo
namespace: default
spec:
replicas: 1
template:
metadata:
labels:
app: stash-demo
name: busybox
spec:
containers:
- args:
- sleep
- "3600"
image: busybox
imagePullPolicy: IfNotPresent
name: busybox
volumeMounts:
- mountPath: /source/data
name: source-data
restartPolicy: Always
volumes:
- gitRepo:
repository: https://github.com/appscode/stash-data.git
name: source-data
Run the following command to confirm that busybox
pods are running.
$ kubectl get pods -l app=stash-demo
NAME READY STATUS RESTARTS AGE
stash-demo-b66b9cdfd-j7rb5 1/1 Running 0 49s
You can check that the /source/data/
directory of pod is populated with data from the volume source using this command,
$ kubectl exec stash-demo-b66b9cdfd-j7rb5 -- ls -R /source/data/
/source/data/:
stash-data
/source/data/stash-data:
Eureka-by-EdgarAllanPoe.txt
LICENSE
README.md
Now, let’s backup the directory into a AWS S3 compatible Rook Object Storage.
At first, we need to create a secret for Restic
crd. Create secret for Restic
using following command,
$ echo -n 'changeit' > RESTIC_PASSWORD
$ echo -n '<your-rook-access-key-id-here>' > AWS_ACCESS_KEY_ID
$ echo -n '<your-rook-secret-access-key-here>' > AWS_SECRET_ACCESS_KEY
$ kubectl create secret generic rook-restic-secret \
--from-file=./RESTIC_PASSWORD \
--from-file=./AWS_ACCESS_KEY_ID \
--from-file=./AWS_SECRET_ACCESS_KEY
secret "rook-restic-secret" created
Verify that the secret has been created successfully,
$ kubectl get secret rook-restic-secret -o yaml
apiVersion: v1
data:
AWS_ACCESS_KEY_ID: <base64 encoded rook access key>
AWS_SECRET_ACCESS_KEY: <base64 encoded rook secret key>
RESTIC_PASSWORD: Y2hhbmdlaXQ=
kind: Secret
metadata:
creationTimestamp: 2018-04-12T10:32:14Z
name: rook-restic-secret
namespace: default
resourceVersion: "2414"
selfLink: /api/v1/namespaces/default/secrets/rook-restic-secret
uid: c454391b-3e3c-11e8-a7b6-080027672508
type: Opaque
Now, we can create Restic
crd. This will create a repository stash-backup-repo
in Rook Object Storage bucket and start taking periodic backup of /source/data/
folder.
$ kubectl apply -f ./docs/examples/backends/rook/rook-restic.yaml
restic "rook-restic" created
Definition of Restic
crd for Rook Object Storage backend,
apiVersion: stash.appscode.com/v1alpha1
kind: Restic
metadata:
name: rook-restic
namespace: default
spec:
selector:
matchLabels:
app: stash-demo # Must match with the label of busybox pod we have created before.
fileGroups:
- path: /source/data
retentionPolicyName: 'keep-last-5'
backend:
s3:
endpoint: 'http://rook-ceph-rgw-my-store.rook' # Use your own rook object storage end point.
bucket: stash-backup # Give a name of the bucket where you want to backup.
prefix: demo # . Path prefix into bucket where repository will be created.(optional).
storageSecretName: rook-restic-secret
schedule: '@every 1m'
volumeMounts:
- mountPath: /source/data
name: source-data
retentionPolicies:
- name: 'keep-last-5'
keepLast: 5
prune: true
If everything goes well, A Repository
crd with name deployment.stash-demo
will be created for the respective repository in Rook Object Storage backend. Verify that, Repository
is created successfully using this command,
$ kubectl get repository deployment.stash-demo
NAME AGE
deployment.stash-demo 1m
Restic
will take backup of the volume periodically with a 1-minute interval. You can verify that backup is taking successfully by,
$ kubectl get snapshots -l repository=deployment.stash-demo
NAME AGE
deployment.stash-demo-c1014ca6 10s
Here, deployment.stash-demo-c1014ca6
represents the name of the successful backup Snapshot taken by Stash in deployment.stash-demo
repository.
PersistentVolumeClaim
Rook Block Storage allow the users to mount persistent volume into pod using PersistentVolumeClaim
. Here, we will recover our backed up data into a PVC.
At first, delete Restic
crd so that it does not lock the restic repository while we are trying to recover from it.
$ kubectl delete restic rook-restic
restic "rook-restic" deleted
Now, create a PersistentVolumeClaim
for Rook Block Storage,
$ kubectl apply -f ./docs/examples/backends/rook/rook-pvc.yaml
persistentvolumeclaim "stash-recovered" created
Definition of PersistentVolumeClaim
:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: stash-recovered
labels:
app: stash-demo
spec:
storageClassName: rook-block
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 2Gi
Check cluster has provisioned the requested claim,
$ kubectl get pvc -l app=stash-demo
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
stash-recovered Bound pvc-a7aa73fa-3e3f-11e8-a7b6-080027672508 2Gi RWO rook-block 36s
Look at the STATUS
filed. stash-recovered
PVC is bounded to volume pvc-a7aa73fa-3e3f-11e8-a7b6-080027672508
.
Now, create a Recovery
to recover backed up data in this PVC.
$ kubectl apply -f ./docs/examples/backends/rook/rook-recovery.yaml
recovery "rook-recovery" created
Definition of Recovery
should look like below:
apiVersion: stash.appscode.com/v1alpha1
kind: Recovery
metadata:
name: rook-recovery
namespace: default
spec:
repository:
name: deployment.stash-demo
namespace: default
paths:
- /source/data
recoveredVolumes:
- mountPath: /source/data
persistentVolumeClaim:
claimName: stash-recovered
Wait until Recovery
job completed its task. To verify that recovery completed successfully run,
$ kubectl get recovery rook-recovery -o yaml
apiVersion: stash.appscode.com/v1alpha1
kind: Recovery
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"stash.appscode.com/v1alpha1","kind":"Recovery","metadata":{"name":"rook-recovery","namespace":"default"},"spec":{"repository":"deployment.stash-demo","paths":["/source/data"],"recoveredVolumes":[{"mountPath":"/source/data","persistentVolumeClaim":{"claimName":"stash-recovered"}}]}}
clusterName: ""
creationTimestamp: 2018-04-12T12:57:54Z
generation: 0
name: rook-recovery
namespace: default
resourceVersion: "2315"
selfLink: /apis/stash.appscode.com/v1alpha1/namespaces/default/recoveries/rook-recovery
uid: 1dbad356-3e51-11e8-b2bd-080027dbef96
spec:
repository:
name: deployment.stash-demo
namespace: default
paths:
- /source/data
recoveredVolumes:
- mountPath: /source/data
persistentVolumeClaim:
claimName: stash-recovered
status:
phase: Succeeded
Now, let’s re-deploy the busybox
deployment using this recovered PVC. First, delete old deployment and recovery job.
$ kubectl delete deployment stash-demo
deployment "stash-demo" deleted
$ kubectl delete recovery rook-recovery
recovery "rook-recovery" deleted
Now, mount the recovered PersistentVolumeClaim
in busybox
deployment instead of gitRepo
we had mounted before then re-deploy it,
$ kubectl apply -f ./docs/examples/backends/rook/restored-deployment.yaml
deployment "stash-demo" created
apiVersion: apps/v1beta1
kind: Deployment
metadata:
labels:
app: stash-demo
name: stash-demo
namespace: default
spec:
replicas: 1
template:
metadata:
labels:
app: stash-demo
name: busybox
spec:
containers:
- args:
- sleep
- "3600"
image: busybox
imagePullPolicy: IfNotPresent
name: busybox
volumeMounts:
- mountPath: /source/data
name: source-data
restartPolicy: Always
volumes:
- name: source-data
persistentVolumeClaim:
claimName: stash-recovered
Get the pod of new deployment,
$ kubectl get pod -l app=stash-demo
NAME READY STATUS RESTARTS AGE
stash-demo-5bc57fbcfb-b45k8 1/1 Running 0 1m
Check the backed up data is restored in /source/data/
directory of busybox
pod.
$ kubectl exec stash-demo-5bc57fbcfb-b45k8 -- ls -R /source/data/
/source/data/:
lost+found
stash-data
/source/data/lost+found:
/source/data/stash-data:
Eureka-by-EdgarAllanPoe.txt
LICENSE
README.md
$ kubectl delete pvc stash-recovered
$ kubectl delete deployment stash-demo
$ kubectl delete repository deployment.stash-demo
Uninstall Stash following the instructions here.