Robin Cloud Native Storage is an application-aware container storage that offers advanced data management capabilities and runs natively on any Kubernetes distribution including IBM Kubernetes Service and Red Hat OpenShift Kubernetes Service. Robin Cloud Native Storage enables you to Protect (via Snapshots, Backups), Secure (via encryption), Collaborate (via Clones and git like push/pull workflows), and make Portable (via Cloud-sync) any Stateful application that is deployed using Helm Charts or Operators.
In this code pattern we will take a snapshot of an n-tier stateful application, create a backup and restore the backup using Robin CNS. We will migrate stateful application from IBM Kubernetes Service to Red Hat OpenShift Kubernetes Service. We will deploy a simple Employee Database
application which can add/edit/delete employees data through a simple UI. Employees data will be stored in PostgreSQL database. In this code pattern we will show how to take snapshots of running application, back them up and restore the application state with just a few simple commands.
When you have completed this code pattern, you will understand how to:
- Setup Robin CNS
- Create snapshots and backup your stateful applications on to a remote Object Storage
- Package a n-tier application into a simple Robin Flexapp
- Restore any backup to any local/remote Kubernetes distribution
- Package your n-tier stateful application into a Robin FlexApp on Kubernetes
- Capture Robin Snapshot of the FlexApp and backup to Cloud Object Storage
- Decrypt the backup from Cloud Object Storage and restore the backup on OpenShift
- Create a Robin FlexApp from the restored backup to get the stateful application as it is from Kubernetes to OpenShift
Comming Soon.
- Robin Installation Tutorial: Follow the tutorial and setup robin Cloud Native Storage on Kubernetes and OpenShift.
- Helm CLI: Download and install the Helm CLI.
- Setup applications on Kubernetes to simulate existing environment
- Backup stateful application
- Restore the backed-up stateful application on OpenShift
- Verify the restored Stateful Application
- (Optional) Simulate catastrophic failure and recover from it
In this step you will deploy a stateful application on Kubernetes cluster. If you already have a stateful application deployed, then you may skip this step and proceed with step 2
- Clone the
backup-and-restore-stateful-applications-between-iks-and-roks
repo locally. In a terminal, run:
git clone https://github.com/IBM/backup-and-restore-stateful-applications-between-iks-and-roks.git
Once you have registered the repo you can go ahead and deploy a n-tier application which includes a client application and a database. In this section you will learn how to deploy postgresql database on kubernetes through helm charts.
-
In terminal, run the following command to install postgresql:
helm repo add bitnami https://charts.bitnami.com/bitnami helm install t3-db bitnami/postgresql --set persistence.storageClass=robin -n demo
NAME: t3-db LAST DEPLOYED: Thu May 6 10:54:56 2021 NAMESPACE: demo STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: ** Please be patient while the chart is being deployed ** ...
-
You will need the postgresql username, password, hostname and port to connect it to the client application. In terminal, run the following commands to get the password and ip address.
-
Run the following command to get the
IP_ADDRESS
:export IP_ADDRESS=$(kubectl get service -n demo t3-db-postgresql -o jsonpath={.spec.clusterIP}) && echo $IP_ADDRESS
-
Run the following command to get the
POSTGRES_PASSWORD
:export POSTGRES_PASSWORD=$(kubectl get secret --namespace demo t3-db-postgresql -o jsonpath="{.data.postgresql-password}" | base64 --decode) && echo $POSTGRES_PASSWORD
-
-
At this point, you will have the Postgresql credentials as follows:
username
: postgrespassword
: $POSTGRES_PASSWORDhostname
: $IP_ADDRESSport
: 5432
-
Once you have the credentials, connect to the postgres-client and create a database named
records
that will be used by the client application to store data. In terminal, run the following command:kubectl run t3-db-postgresql-client --rm --tty -i --restart='Never' --namespace demo --image docker.io/bitnami/postgresql:11.11.0-debian-10-r71 --env="PGPASSWORD=$POSTGRES_PASSWORD" --command -- psql --host t3-db-postgresql -U postgres -d postgres -p 5432
Note: The default username for Postgresql is
postgres
and the default port is5432
. -
You will enter the postgres prompt, run the
create
command to create a database.postgres=# create database records; CREATE DATABASE postgres-#
-
You can exit the postgres-client by running the
exit
command.postgres=# exit $
Similarly, deploy the client application to access the postgresql database and perform Create, Read, Update and Delete (CRUD) operations on the table.
- In the cloned directory, navigate to
client-application/helm-chart/
directory and run thehelm install
command.cd client-application/helm-chart/ helm install -n demo t3-client .
-
Once the client application is installed, access it by port forwarding. In terminal, run the following commands:
- Get the pod name:
kubectl get pods -n demo
NAME READY STATUS RESTARTS AGE t3-client-deployment-789f9f54fb-5tlhn 1/1 Running 0 8d t3-db-postgresql-0 1/1 Running 0 8d
- Port forward the pod:
kubectl port-forward t3-client-deployment-789f9f54fb-5tlhn 8080 -n demo
Forwarding from 127.0.0.1:8080 -> 8080 Forwarding from [::1]:8080 -> 8080
- Get the pod name:
-
Visit http://localhost:8080 in your browser to access the Client Application.
-
Click on Connect button and enter the database credentials that you copied in 2.1 and click on Submit. The Client Application will now be connected to the postgresql database.
Note: You can verify the connection status under Connection Status section of the client application
-
Login to IBM Cloud, and create a Cloud Object Storage. Select the Standard plan and click on Create.
-
Once the Cloud Object Storage is created, in the IBM Cloud Resources, select the Object Storage.
-
You will have to copy certain credentials in order to register Robin CNS to the Object Storage.
-
Click on the Endpoints on the left panel and select resiliency and location in which you wish to create an Object Storage Bucket. Copy the public
endpoint
from the location as shown. In our case we selected theap-geo
endpoint. -
Click on the Service credentials on the left panel and click on New credentials.
-
While creating a new credential, under the Advance options ensure that you turn on the Include HMAC Credential. Click on Add to create a credential.
-
Once the credential is created, under cos_hmac_keys copy the
access_key_id
andsecret_access_key
from the credentials as shown. -
In the parent directory of the cloned repo, add the copied
access_key_id
,secret_access_key
andendpoint
to thecredentials.json
file.{ "aws_access_key_id" : "<access_key_id>", "aws_secret_access_key" : "<secret_access_key>", "end_point": "<endpoint>" }
-
At this point you have successfully:
- Created a Cloud Object Storage and copied the credentials required for the further setup
Note: Before you proceed with the documentation, make sure you have logged into the Kubernetes cluster from your CLI. You will have already learned how to connect to your cluster through kubectl command in the Robin Installation Tutorial.
A Cloud Object Storage is required to backup the stateful application snapshot from Kubernetes cluster to Object Storage. Furthermore, the same backup will be decrypted and restored on the OpenShift cluster. Since you will have already created a Cloud Object storage in Step 2 and saved the credentials, you can now register it on Robin.
-
In terminal, access the Robin Client through the pod which you have learn't in the Robin Installation Tutorial.
kubectl exec -it robin-85pnq -n robinio -- bash
[robinds@kube-c1ima1bd0o105lencd5g-robiniooscl-default-0000029e ~]#
-
In terminal, under the robin prompt, run the
robin login
command with default username asadmin
and password asRobin123
:[robinds@kube-c1ima1bd0o105lencd5g-robiniooscl-default-0000029e ~]# robin login admin Password: User admin is logged into Administrators tenant [robinds@kube-c1ima1bd0o105lencd5g-robiniooscl-default-0000029e ~]#
-
Copy the
credentials.json
that you prepared in Step 2 into the client pod. You can do so withvi
editor on the client pod. In terminal, run the following command:[robinds@kube-c1ima1bd0o105lencd5g-robiniooscl-default-0000029e ~]# vi credentials.json
-
Copy and paste the entire json in the vi editor and hit the
ESC
key then:wq
and press enter to save the file.{ "aws_access_key_id" : "xxxx", "aws_secret_access_key" : "xxxx", "end_point": "s3.xxxx.cloud-object-storage.appdomain.cloud" }
-
Now once you have the credentials in place, run the robin repo register command. In terminal, run the following command:
[robinds@kube-c1ima1bd0o105lencd5g-robiniooscl-default-0000029e ~]# robin repo register psqlbackups s3://robin-backup-bucket/psqlbackups credentials.json readwrite --wait
NOTE: The string
s3://robin-backup-bucket/psqlbackups
indicatess3|gcs://bucket[/path/to/folder]
.psqlbackups
is the bucket that will be created in Object Storage. You can learn more about therobin repo register
command in the docs here. -
You have successfully registered the repo with robin, verify it by running the following command:
[robinds@kube-c1ima1bd0o105lencd5g-robiniooscl-default-0000029e ~]# robin repo list
+-------------+--------+----------------------+--------------+---------------------+---------------+-------------+ | Name | Type | Owner/Tenant | BackupTarget | Bucket | Path | Permissions | +-------------+--------+----------------------+--------------+---------------------+---------------+-------------+ | psqlbackups | AWS_S3 | admin/Administrators | 1 | robin-backup-bucket | psqlbackups/ | readwrite | +-------------+--------+----------------------+--------------+---------------------+---------------+-------------+
If you have followed step 1 you will have a database and a client application deployed in Kubernetes cluster. If you have not followed step 1 and you have your own application, then you will have to replace application names accordingly. In this step you will learn how to package multiple applications into a Robin FlexApp and take a snapshot. By packaging multiple deployments into once single FlexApp, it becomes easier to migrate everything together rather than migrating individual deployments.
-
In terminal, access the Robin Client through the pod which you have learn't in the Robin Installation Tutorial.
kubectl exec -it robin-85pnq -n robinio -- bash
[robinds@kube-c1ima1bd0o105lencd5g-robiniooscl-default-0000029e ~]#
-
You can see the helm apps deployed in your cluster by running the folowing command:
[robinds@kube-c1ima1bd0o105lencd5g-robiniooscl-default-0000029e ~]# robin app list
Helm/Flex Apps: +-----------+---------+--------+----------------------+-----------+-----------+---------+ | Name | Type | State | Owner/Tenant | Namespace | Snapshots | Backups | +-----------+---------+--------+----------------------+-----------+-----------+---------+ | t3-client | helm | ONLINE | admin/Administrators | demo | 0 | 0 | | t3-db | helm | ONLINE | admin/Administrators | demo | 0 | 0 | +-----------+---------+--------+----------------------+-----------+-----------+---------+
-
Run the following command to package the
t3-client
andt3-db
into a FlexApp calledemp-mgmt
.[robinds@kube-c1ima1bd0o105lencd5g-robiniooscl-default-0000029e ~]# robin app register emp-mgmt --selector app.kubernetes.io/instance=t3-client --selector app.kubernetes.io/instance=t3-db -n demo
Learn more about Robin FlexApp here.
-
You can see the
emp-mgmt
FlexApp now listed in your cluster by running the folowing command:[robinds@kube-c1ima1bd0o105lencd5g-robiniooscl-default-0000029e ~]# robin app list
Helm/Flex Apps: +-----------+---------+--------+----------------------+-----------+-----------+---------+ | Name | Type | State | Owner/Tenant | Namespace | Snapshots | Backups | +-----------+---------+--------+----------------------+-----------+-----------+---------+ | t3-client | helm | ONLINE | admin/Administrators | demo | 0 | 0 | | t3-db | helm | ONLINE | admin/Administrators | demo | 0 | 0 | | emp-mgmt | flexapp | ONLINE | admin/Administrators | demo | 0 | 0 | +-----------+---------+--------+----------------------+-----------+-----------+---------+
-
To see what are the resources tagged in
emp-mgmt
run the following command:[robinds@kube-c1ima1bd0o105lencd5g-robiniooscl-default-0000029e ~]# robin app info emp-mgmt --status
+-----------------------+---------------------------+--------+---------+ | Kind | Name | Status | Message | +-----------------------+---------------------------+--------+---------+ | ServiceAccount | t3-client | Ready | - | | Secret | t3-db-postgresql | Ready | - | | PersistentVolumeClaim | data-t3-db-postgresql-0 | Bound | - | | Pod | t3-db-postgresql-0 | Ready | - | | Service | t3-client-service | Ready | - | | Service | t3-db-postgresql | Ready | - | | Service | t3-db-postgresql-headless | Ready | - | | StatefulSet | t3-db-postgresql | Ready | - | | Deployment | t3-client-deployment | Ready | - | +-----------------------+---------------------------+--------+---------+ Key: Green: Object is running Yellow: Object is potentially down Red: Object is down
-
At this point, you will have successfully:
- Deployed Client and DB applications
- Packaged them into a Robin FlexApp
-
You can now create a snapshot, and backup to Object storage.
In order to take a backup in Object storage, you will have to attach your FlexApp to the Repo that you registered in step 2.
- Run the following command to attach
emp-mgmt
to thepsqlbackups
bucket
[robinds@kube-c1ima1bd0o105lencd5g-robiniooscl-default-0000029e ~]# robin app attach-repo emp-mgmt psqlbackups --wait
- Once the Job is finished
emp-mgmt
will be linked to thepsqlbackups
bucket in the Cloud Object Storage.
The automated script basically runs a set of Robin commands to perform the following tasks:
- Create a Snapshot of the App
- Create a Backup of the Snapshot and store it in Cloud Object Storage
- Export the sha5 token that can be used to decrypt the backup
In the parent directory of the cloned repo, goto scripts/
directory. You will be using the robinbackup.sh
script at this point.
-
Copy the
robinbackup.sh
script to the robin pod. You can do so withvi
editor on the client pod. In terminal, run the following command:[robinds@kube-c1ima1bd0o105lencd5g-robiniooscl-default-0000029e ~]# vi robinbackup.sh
-
Copy and paste the entire json in the vi editor and hit the
ESC
key then:wq
and press enter to save the file. -
The script takes 4 arguments:
-a
: Application name that you want to backup-b
: Backup name-s
: Snapshot name-r
: Object Storage Repo name
-
Since you will backup the
emp-mgmt
FlexApp you can give the-a
asemp-mgmt
. In terminal, run the following command:[robinds@kube-c1ima1bd0o105lencd5g-robiniooscl-default-0000029e ~]# ./robinbackup.sh -a emp-mgmt -s snapof2records -b emp-mgmt-backup -r psqlbackups
1/3: Creating a snapshot of emp-mgmt Job: 579 Name: K8SApplicationSnapshot State: PROCESSED Error: 0 Job: 579 Name: K8SApplicationSnapshot State: WAITING Error: 0 Job: 579 Name: K8SApplicationSnapshot State: COMPLETED Error: 0 +----------------------------------+--------+----------+----------+-------------------------+ | Snapshot ID | State | App Name | App Kind | Snapshot name | +----------------------------------+--------+----------+----------+-------------------------+ | 0ca41654af0e11ebad8c81e299357339 | ONLINE | emp-mgmt | flexapp | emp-mgmt_snapof2records | +----------------------------------+--------+----------+----------+-------------------------+ 2/3: Backing up 0ca41654af0e11ebad8c81e299357339 Creating app backup 'emp-mgmt-backup' from snapshot '0ca41654af0e11ebad8c81e299357339' Job: 583 Name: K8SApplicationBackup State: PROCESSED Error: 0 Job: 583 Name: K8SApplicationBackup State: PREPARED Error: 0 Job: 583 Name: K8SApplicationBackup State: AGENT_WAIT Error: 0 Job: 583 Name: K8SApplicationBackup State: COMPLETED Error: 0 +----------------------------------+-----------------+-------------+-------------------------+--------+ | Backup ID | Backup Name | Repo | Snapshot Name | State | +----------------------------------+-----------------+-------------+-------------------------+--------+ | 1755d024af0e11eb863f3d26fe831c20 | emp-mgmt-backup | psqlbackups | emp-mgmt_snapof2records | Pushed | +----------------------------------+-----------------+-------------+-------------------------+--------+ 3/3: Exporting Backup eyJiYWNrdXBfaWQiOiAiMTc1NWQwMjRhZjBlMTFlYjg2M2YzZDI2ZmU4MzFjMjAiLCAiYmFja3VwX3BhdGgiOiAicGdzcWxiYWNrdXBzLzE2MTgzODU1NzMvZW1wLW1nbXRfMTIvMTc1NWQwMjRhZjBlMTFlYjg2M2YzZDI2ZmU4MzFjMjAvYXBwY29uZmlnL2JhY2t1cF9tZXRhZGF0YS5qc29uIiwgInJlcG9fdHlwZSI6ICJBV1NfUzMiLCAicmVwb19wYXJhbXMiOiB7InJlcG9fdHlwZSI6ICJBV1NfUzMiLCAicGF0aCI6ICJwZ3NxbGJhY2t1cHMvIiwgImJ1Y2tldCI6ICJyb2Jpbi1iYWNrdXAtYnVja2V0IiwgInRscyI6IHRydWUsICJ2YWxpZGF0ZV9jZXJ0cyI6IHRydWUsICJlbmRfcG9pbnQiOiAiczMuZGlyZWN0LnVzLXNvdXRoLmNsb3VkLW9iamVjdC1zdG9yYWdlLmFwcGRvbWFpbi5jbG91ZCJ9fQ== Copy the above sha5 token to import backup elsewhere
-
The script may take couple of minutes to complete. Once the script execution is completed, you will get a long sha5 token displayed. This token is important as it will be used in the target cluster to restore the
emp-mgmt
FlexApp. -
You can also learn more about the Robin commands used in the script:
-
You can exit the robin client by running the following command:
[robinds@kube-c1ima1bd0o105lencd5g-robiniooscl-default-0000029e ~]# exit $
Before you begin with the restoration, you will have to create an OpenShift project. In terminal, run the following command:
oc new-project demo
oc project demo
Note: You need to be connected to the OpenShift cluster through your terminal for the
oc
commands to work. You will have learn't how to connect in the Robin Installation Tutorial.
You will be restoring the stateful application from the Cloud Object Storage. Since you will have already created a Cloud Object storage in Step 2 and backed up the stateful application in Step 3, you can now register the same repo in OpenShift cluster and restore the Robin FlexApp.
-
In terminal, access the Robin Client through the pod which you have learn't in the Robin Installation Tutorial.
kubectl exec -it robin-9aPnq -n robinio -- bash
[robinds@kube-c1ima1bd0o105lencd5g-robinioopenshiftcl-default-0000029e ~]#
-
In terminal, under the robin prompt, run the
robin login
command with default username asadmin
and password asRobin123
:[robinds@kube-c1ima1bd0o105lencd5g-robinioopenshiftcl-default-0000029e ~]# robin login admin Password: User admin is logged into Administrators tenant [robinds@kube-c1ima1bd0o105lencd5g-robinioopenshiftcl-default-0000029e ~]#
-
Copy the
credentials.json
that you prepared in Step 2 into the client pod. You can do so withvi
editor on the client pod. In terminal, run the following command:[robinds@kube-c1ima1bd0o105lencd5g-robinioopenshiftcl-default-0000029e ~]# vi credentials.json
-
Copy and paste the entire json in the vi editor and hit the
ESC
key then:wq
and press enter to save the file.{ "aws_access_key_id" : "xxxx", "aws_secret_access_key" : "xxxx", "end_point": "s3.xxxx.cloud-object-storage.appdomain.cloud" }
-
Now once you have the credentials in place, run the robin repo register command. In terminal, run the following command:
[robinds@kube-c1ima1bd0o105lencd5g-robinioopenshiftcl-default-0000029e ~]# robin repo register psqlbackups s3://robin-backup-bucket/psqlbackups credentials.json readwrite --wait
NOTE: The string
s3://robin-backup-bucket/psqlbackups
indicatess3|gcs://bucket[/path/to/folder]
.psqlbackups
is the bucket that will be created in Object Storage. You can learn more about therobin repo register
command in the docs here. -
You have successfully registered the repo with robin, verify it by running the following command:
[robinds@kube-c1ima1bd0o105lencd5g-robinioopenshiftcl-default-0000029e ~]# robin repo list
+-------------+--------+----------------------+--------------+---------------------+---------------+-------------+ | Name | Type | Owner/Tenant | BackupTarget | Bucket | Path | Permissions | +-------------+--------+----------------------+--------------+---------------------+---------------+-------------+ | psqlbackups | AWS_S3 | admin/Administrators | 1 | robin-backup-bucket | psqlbackups/ | readwrite | +-------------+--------+----------------------+--------------+---------------------+---------------+-------------+
The automated script basically runs a set of Robin commands to perform the following tasks:
- Decrypt the backup from the Object Storage and import it in OpenShift
- Create a Robin FlexApp from the backup
In the parent directory of the cloned repo, goto scripts/
directory. You will be using the robinrestore.sh
script at this point.
-
Copy the
robinrestore.sh
script to the robin pod. You can do so withvi
editor on the client pod. In terminal, run the following command:[robinds@kube-c1ima1bd0o105lencd5g-robinioopenshiftcl-default-0000029e ~]# vi robinrestore.sh
-
Copy and paste the entire json in the vi editor and hit the
ESC
key then:wq
and press enter to save the file. -
The script takes 2 arguments:
-a
: Application name that you want to create-t
: sha5 Token to decrypt the backup
-
Since you will be restoing the
emp-mgmt
FlexApp you can give the-a
asemp-mgmt
. Enter the token copied from 6. Run the script to create a Snapshot, Backup and Export it as-t
argument. In terminal, run the following command:[robinds@kube-c1ima1bd0o105lencd5g-robinioopenshiftcl-default-0000029e ~]# ./robinrestore.sh -a emp-mgmt -t eyJiYWNrdXBfaWQiOiAiMTc1NWQwMjRhZjBlMTFlYjg2M2YzZDI2ZmU4MzFjMjAiLCAiYmFja3VwX3BhdGgiOiAicGdzcWxiYWNrdXBzLzE2MTgzODU1NzMvZW1wLW1nbXRfMTIvMTc1NWQwMjRhZjBlMTFlYjg2M2YzZDI2ZmU4MzFjMjAvYXBwY29uZmlnL2JhY2t1cF9tZXRhZGF0YS5qc29uIiwgInJlcG9fdHlwZSI6ICJBV1NfUzMiLCAicmVwb19wYXJhbXMiOiB7InJlcG9fdHlwZSI6ICJBV1NfUzMiLCAicGF0aCI6ICJwZ3NxbGJhY2t1cHMvIiwgImJ1Y2tldCI6ICJyb2Jpbi1iYWNrdXAtYnVja2V0IiwgInRscyI6IHRydWUsICJ2YWxpZGF0ZV9jZXJ0cyI6IHRydWUsICJlbmRfcG9pbnQiOiAiczMuZGlyZWN0LnVzLXNvdXRoLmNsb3VkLW9iamVjdC1zdG9yYWdlLmFwcGRvbWFpbi5jbG91ZCJ9fQ==
1/2: Importing using the token: eyJiYWNrdXBfaWQiOiAiNGRiYTBiYzhhODJkMTFlYjkwMGY4ZmU4OTNkY2QwNjciLCAiYmFja3VwX3BhdGgiOiAicGdzcWxiYWNrdXBzLzE2MTgzODU1NzMvZW1wLW1nbXRfMTIvNGRiYTBiYzhhODJkMTFlYjkwMGY4ZmU4OTNkY2QwNjcvYXBwY29uZmlnL2JhY2t1cF9tZXRhZGF0YS5qc29uIiwgInJlcG9fdHlwZSI6ICJBV1NfUzMiLCAicmVwb19wYXJhbXMiOiB7InJlcG9fdHlwZSI6ICJBV1NfUzMiLCAicGF0aCI6ICJwZ3NxbGJhY2t1cHMvIiwgImJ1Y2tldCI6ICJyb2Jpbi1iYWNrdXAtYnVja2V0IiwgInRscyI6IHRydWUsICJ2YWxpZGF0ZV9jZXJ0cyI6IHRydWUsICJlbmRfcG9pbnQiOiAiczMuZGlyZWN0LnVzLXNvdXRoLmNsb3VkLW9iamVjdC1zdG9yYWdlLmFwcGRvbWFpbi5jbG91ZCJ9fQ== Job: 1089 Name: K8sBackupImport State: PROCESSED Error: 0 Job: 1089 Name: K8sBackupImport State: COMPLETED Error: 0 +----------------------------------+-------------+-------------+---------------------+----------+ | Backup ID | Backup Name | Repo | Snapshot Name | State | +----------------------------------+-------------+-------------+---------------------+----------+ | 1755d024af0e11eb863f3d26fe831c20 | emp-mgmt-backup | psqlbackups | emp-mgmt_snapof2records | Imported | +----------------------------------+-------------+-------------+---------------------+----------+ 2/2: Restoring app using Backup: 1755d024af0e11eb863f3d26fe831c20 Job: 1090 Name: K8SApplicationCreate State: PROCESSED Error: 0 Job: 1090 Name: K8SApplicationCreate State: PREPARED Error: 0 Job: 1090 Name: K8SApplicationCreate State: AGENT_WAIT Error: 0 Job: 1090 Name: K8SApplicationCreate State: COMPLETED Error: 0 Helm/Flex Apps: +----------+---------+--------+----------------------+-----------+-----------+---------+ | Name | Type | State | Owner/Tenant | Namespace | Snapshots | Backups | +----------+---------+--------+----------------------+-----------+-----------+---------+ | emp-mgmt | flexapp | ONLINE | admin/Administrators | demo | 0 | 0 | +----------+---------+--------+----------------------+-----------+-----------+---------+ +-----------------------+------------------------------------------------+--------+---------+ | Kind | Name | Status | Message | +-----------------------+------------------------------------------------+--------+---------+ | ServiceAccount | emp-mgmt-t3-client | Ready | - | | Secret | emp-mgmt-t3-db-postgresql | Ready | - | | Secret | default-dockercfg-f4j59 | Ready | - | | Secret | emp-mgmt-t3-client-dockercfg-9hjgw | Ready | - | | PersistentVolumeClaim | data-emp-mgmt-t3-db-postgresql-0 | Bound | - | | Pod | emp-mgmt-t3-client-deployment-7bf7d6f9b8-qrx84 | Ready | - | | Pod | emp-mgmt-t3-db-postgresql-0 | Ready | - | | Service | emp-mgmt-t3-client-service | Ready | - | | Service | emp-mgmt-t3-db-postgresql | Ready | - | | Service | emp-mgmt-t3-db-postgresql-headless | Ready | - | | ReplicaSet | emp-mgmt-t3-client-deployment-7bf7d6f9b8 | Ready | - | | StatefulSet | emp-mgmt-t3-db-postgresql | Ready | - | | Deployment | emp-mgmt-t3-client-deployment | Ready | - | +-----------------------+------------------------------------------------+--------+---------+ Key: Green: Object is running Yellow: Object is potentially down Red: Object is down Postgresql Connection Details: Username: postgres Password: z8HBKm2asy Hostname: 172.21.106.4 Port: 5432
-
The script may take couple of minutes to complete. Once the script execution is completed, you will see the FlexApp
emp-mgmt
restored in your OpenShift cluster. You will also see the new Postgresql connection details which will be used to connect the Client Application. -
You can also learn more about the Robin commands used in the script:
-
You can exit the robin client by running the following command:
[robinds@kube-c1ima1bd0o105lencd5g-robinioopenshiftcl-default-0000029e ~]# exit $
Now that the n-tier Application is migrated to OpenShift, you can verify the application and the data by accessing the client application. In OpenShift you can simply create a route and then access the client application in your web browser.
-
To create a route in OpenShift, run the following commands:
- Get the service name:
oc project demo oc get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE emp-mgmt-t3-client-service NodePort 172.21.59.91 <none> 8080:30304/TCP 21m emp-mgmt-t3-db-postgresql ClusterIP 172.21.106.4 <none> 5432/TCP 21m emp-mgmt-t3-db-postgresql-headless ClusterIP None <none> 5432/TCP 21m
- Run the expose command:
oc expose svc/emp-mgmt-t3-client-service
route.route.openshift.io/emp-mgmt-t3-client-service exposed
- Get the route:
oc get route
NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD emp-mgmt-t3-client-service emp-mgmt-t3-client-service-demo.robinio-os-cluster-f2c6cdc6801be85fd188b09d006f13e3-0000.us-south.containers.appdomain.cloud emp-mgmt-t3-client-service 8080 None
NOTE: append
http://
to the obtained route. Example: http://emp-mgmt-t3-client-service-demo.robinio-os-cluster-f2c6cdc6801be85fd188b09d006f13e3-0000.us-south.containers.appdomain.cloud
- Get the service name:
-
Visit the route that you obtained to access the client application.
-
Click on Connect button and enter the database credentials that you obtained in 3. Run the script to decrypt the Backup, and create a FlexApp from it and click on Submit. The Client Application will now be connected to the postgresql database.
-
You will see the exact same records in the postgresql database confirming the successful migration of the n-tier application from Kubernetes to OpenShift.
This section shows how you can recover your stateful application if there is any catastrophic failure with the database or the client application.
-
Take a snapshot of the n-tier application before you begin. In terminal, run the following command:
[robinds@kube-c1ima1bd0o105lencd5g-robinioopenshiftcl-default-0000029e ~]# robin snapshot create emp-mgmt --wait
Job: 690 Name: K8SApplicationSnapshot State: WAITING Error: 0 Job: 690 Name: K8SApplicationSnapshot State: COMPLETED Error: 0
-
Now that you have the backup of n-tier application, you can simulate a catastrophic failure. Go ahead and delete all the rows from the Employee Table.
-
You can restore all the data by simply running the following commands:
- Get the Snapshot ID:
[robinds@kube-c1ima1bd0o105lencd5g-robinioopenshiftcl-default-0000029e ~]# robin snapshot list --app emp-mgmt
+----------------------------------+--------+----------+----------+------------------------------+ | Snapshot ID | State | App Name | App Kind | Snapshot name | +----------------------------------+--------+----------+----------+------------------------------+ | b6fb9114b86911eb8b68f9cbb5113b62 | ONLINE | emp-mgmt | flexapp | emp-mgmt_snapshot-1621404969 | +----------------------------------+--------+----------+----------+------------------------------+
- Run the
robin restore
command:[robinds@kube-c1ima1bd0o105lencd5g-robinioopenshiftcl-default-0000029e ~]# robin app restore emp-mgmt --snapshotid b6fb9114b86911eb8b68f9cbb5113b62 --wait
Job: 694 Name: K8SApplicationRollback State: VALIDATED Error: 0 Job: 694 Name: K8SApplicationRollback State: PREPARED Error: 0 Job: 694 Name: K8SApplicationRollback State: AGENT_WAIT Error: 0 Job: 694 Name: K8SApplicationRollback State: COMPLETED Error: 0
- Get the Snapshot ID:
-
Now visit the client application, do note that you will have to reconnect the client application to the database with the credentials obtained in 3. Run the script to decrypt the Backup, and create a FlexApp from it. Once reconnected you will see the data restored.
In this code pattern we used Robin CNS to take snapshot/backup of an n-tier stateful application running on Kubernetes. We restored the backed up application on to OpenShift. We verified that the stateful application is moved with all the right data. As a next step, you can explore other features provided by Robin
This code pattern is licensed under the Apache License, Version 2. Separate third-party code objects invoked within this code pattern are licensed by their respective providers pursuant to their own separate licenses. Contributions are subject to the Developer Certificate of Origin, Version 1.1 and the Apache License, Version 2.