This example shows how you can backup and restore the application that is deployed using DeploymentConfig, OpenShift's resource on an OpenShift cluster. Like Deployment, Statefulset in Kubernetes, OpenShift has another controller named DeploymentConfig, it is almost like Deployment but has some significant differences.
DeploymentConfig is not standard Kubernetes resource but OpenShift resource and creates a new ReplicationController and let's it start up Pods.
This example can be followed if your application is deployed on OpenShift cluster's DeploymentConfig resources.
- Setup OpenShift, you can follow steps mentioned below
- PV provisioner support in the underlying infrastructure
- Kanister controller version 0.112.0 installed in your cluster in namespace
kanister
- Kanctl CLI installed (https://docs.kanister.io/tooling.html#kanctl)
Note
All the helm commands in the document are for the Helm version 3, if you have version 2 setup you will have to change the Helm commands a bit.
To test the applications that are deployed on OpenShift using DeploymentConfig, we will first have to setup OpenShift cluster. To setup the OpenShift cluster in our local environment we are going to use minishift. To install and setup minishift please follow this guide.
Once we have minishift setup we will go ahead and deploy MongoDB application on the minishift cluster using DeploymentConfig and try to backup and restore the data from the application.
Note
Once you have setup minishift by following the steps mentioned above, you can interact with the cluster using oc
command line tool. By default
you are logged in as developer user, that will prevent us from creating some of the resources so please make sure you login as admin by
the following command
oc login -u system:admin
and you are all set to go through rest of this example.
We will use the JSON templates, as described here, provided by OpenShift to deploy the MongoDB database on the minishift cluster that we have just setup.
To install the MongoDB on your cluster please run below command
# Create the namespaces
~ oc create ns mongodb-test
namespace/mongodb-test created
# Install the database
~ oc new-app https://raw.githubusercontent.com/openshift/origin/master/examples/db-templates/mongodb-persistent-template.json \
-p MONGODB_ADMIN_PASSWORD=secretpassword -n mongodb-test
we can use the parameter MONGODB_ADMIN_PASSWORD
to setup the admin password for the MongoDB that we are installing. Once the database is installed get all the pods from mongodb-test
namespace to make sure the pods are in Running
status.
~ oc get pods -n mongodb-test
NAME READY STATUS RESTARTS AGE
mongodb-1-7vw4g 1/1 Running 0 1m
When we say integrating with Kanister, we actually mean creating some Kanister resources to support backup
and restore
actions.
Create Profile Kanister resource using below command
~ kanctl create profile s3compliant --access-key <ACCESS-KEY> \
--secret-key <SECRET-KEY> \
--bucket <BUKET-NAME> --region <AWS-REGION> \
--namespace mongodb-test
secret 's3-secret-gkvgi4' created
profile 's3-profile-vzpfb' created
NOTE:
The command will configure a location where artifacts resulting from Kanister
data operations such as backup should go. This is stored as a profiles.cr.kanister.io
CustomResource (CR) which is then referenced in Kanister ActionSets. Every ActionSet
requires a Profile reference to complete the action. This CR (profiles.cr.kanister.io
)
can be shared between Kanister-enabled application instances.
NOTE:
If MongoDB chart is installed specifying existing secret by setting parameter --set auth.existingSecret=<mongo-secret-name>
you will need to modify the secret name in
the blueprint mongo-blueprint.yaml
at following places:
actions.backup.phases[0].objects.mongosecret.name: <mongo-secret-name>
actions.restore.phases[0].objects.mongosecret.name: <mongo-secret-name>
NOTE: v2 Blueprints are experimental and are not supported with standalone Kanister.
Create Blueprint in the same namespace as the controller (kanister
)
~ oc create -f mongo-dep-config-blueprint.yaml -n kanister
blueprint.cr.kanister.io/mongodb-blueprint created
Now that we have created the Profile and Blueprint Kanister resources we will insert some data into
MongoDB database that we will take backup of.
To insert the data into the MongoDB database we will exec
into the MongoDB pod, please follow below commands
to do so
# Get the MongoDB pod name
~ oc get pods -n mongodb-test
NAME READY STATUS RESTARTS AGE
mongodb-1-7vw4g 1/1 Running 0 4m
# Exec into the pod and insert some records
~ oc exec -it -n mongodb-test mongodb-1-7vw4g bash
bash-4.2$ mongo admin --authenticationDatabase admin -u admin -p $MONGODB_ADMIN_PASSWORD --quiet --eval "db.restaurants.insert({'name' : 'Roys', 'cuisine' : 'Hawaiian', 'id' : '8675309'})"
WriteResult({ "nInserted" : 1 })
bash-4.2$ mongo admin --authenticationDatabase admin -u admin -p $MONGODB_ADMIN_PASSWORD --quiet --eval "db.restaurants.insert({'name' : 'Willies', 'cuisine' : 'Hawaiian', 'id' : '8675310'})"
WriteResult({ "nInserted" : 1 })
# view the record that you have just inserted
bash-4.2$ mongo admin --authenticationDatabase admin -u admin -p $MONGODB_ADMIN_PASSWORD --quiet --eval "db.restaurants.find()"
{ "_id" : ObjectId("5e5ce013d026502dd164d659"), "name" : "Roys", "cuisine" : "Hawaiian", "id" : "8675309" }
{ "_id" : ObjectId("5e5ce01966f876c088fb6697"), "name" : "Willies", "cuisine" : "Hawaiian", "id" : "8675310" }
As you can see we have inserted two documents in the restaurants
collection.
You can now take a backup of the MongoDB data using an ActionSet defining backup for this application. Create an ActionSet in the same namespace as the controller.
# Get the profile
~ oc get profile -n mongodb-test
NAME AGE
s3-profile-vzpfb 1m
# Create the backup Actionset
~ kanctl create actionset --action backup --namespace kanister --blueprint mongodb-blueprint --deploymentconfig mongodb-test/mongodb \
--profile mongodb-test/s3-profile-vzpfb
actionset backup-hdrxr created
# You can describe the Actionset to make sure it is completed
~ oc describe actionset -n kanister backup-hdrxr
# and you will be able to see the status in events at the very end, somewhat like below
# Normal Update Complete 1m Kanister Controller Updated ActionSet 'backup-hdrxr' Status->complete
Let's say someone accidentally deleted the restaurants
collection using the following command in mongodb pod:
# login to the MongoDB pod and delete the records manually
bash-4.2$ mongo admin --authenticationDatabase admin -u admin -p $MONGODB_ADMIN_PASSWORD --quiet --eval "db.restaurants.drop()"
true
If you try to access this data in the database, you should see that it is no longer there:
bash-4.2$ mongo admin --authenticationDatabase admin -u admin -p $MONGODB_ADMIN_PASSWORD --quiet --eval "db.restaurants.find()"
# No entries should be found in the database
To restore the missing data, you should use the backup that you created before. An easy way to do this is to leverage kanctl
, a command-line tool that helps create ActionSets that depend on other ActionSets:
# Get the backup Actionset name
~ oc get actionset -n kanister
NAME AGE
backup-hdrxr 9m
# create the restore Actionset
~ kanctl --namespace kanister create actionset --action restore --from "backup-hdrxr"
actionset restore-backup-hdrxr-tdw9f created
# Describe the Actionset to check if it has been completed
~ oc describe actionset -n kanister restore-backup-hdrxr-tdw9f
# And you should see the last line of the describe, like below
# Normal Update Complete 35s Kanister Controller Updated ActionSet 'restore-backup-hdrxr-tdw9f' Status->complete
Once you have verified that the status of Actionset is Complete
, let's login to the MongoDB pod once again to make sure the data has been restored.
# Exec into the MongoDB pod
bash-4.2$ mongo admin --authenticationDatabase admin -u admin -p $MONGODB_ADMIN_PASSWORD --quiet --eval "db.restaurants.find()"
{ "_id" : ObjectId("5e5ce013d026502dd164d659"), "name" : "Roys", "cuisine" : "Hawaiian", "id" : "8675309" }
{ "_id" : ObjectId("5e5ce01966f876c088fb6697"), "name" : "Willies", "cuisine" : "Hawaiian", "id" : "8675310" }
As you can see the data that we deleted in previous step, to imitate disaster, has been restored successfully.
The artifacts created by the backup action can be cleaned up using the following command:
~ kanctl --namespace kanister create actionset --action delete --from "backup-hdrxr"
actionset delete-backup-hdrxr-fbllx created
If you run into any issues with the above commands, you can check the logs of the controller using:
$ kubectl --namespace kanister logs -l app=kanister-operator
you can also check events of the actionset
$ kubectl describe actionset <actionset-name> -n kanister
When we install a application using oc new-app
a label of format app=<name>
, gets added to all the resources that get created. To get that label execute below command
~ oc get pods -n mongodb-test --show-labels
NAME READY STATUS RESTARTS AGE LABELS
mongodb-1-7vw4g 1/1 Running 0 27m app=mongodb-persistent,deployment=mongodb-1,deploymentconfig=mongodb,name=mongodb
As you can see the label that was added is app=mongodb-persistent
to delete all the resources with this label, use below command
~ oc delete all -n mongodb-test -l app=mongodb-persistent
Remove Blueprint and Profile CR
~ oc delete blueprints.cr.kanister.io <blueprint-name> -n kanister
~ oc delete profiles.cr.kanister.io <profile-name> -n mongodb-test