Red Hat OpenShift Cloud Services and Trilio for OpenShift
Red Hat OpenShift cloud services help you automate the deployment and management of Red Hat OpenShift clusters so that you can build, deliver and maintain applications across every major public cloud environment—in less time. Red Hat OpenShift Service on AWS (ROSA) and Microsoft Azure Red Hat OpenShift (ARO ) are two services that Red Hat co-manages with AWS and Microsoft.
Application data protection on ARO/AWS is critical for businesses. Though Open Source Tools such as Velero provides Kubernetes backup and restore functionality, Trilio provides enterprise-level features such as 24x7x365 support, scalable performance, hooks, operation visualization, and so on.
In this blog, we will demonstrate seamless disaster recovery by backing up a Minecraft server in ROSA and restoring it in ARO.
Backing Up Application on ROSA
By leveraging an Ansible playbook, we can back up the data to an AWS S3 bucket.
- Create demo-Minecraft namespace
- Create a secret that holds the S3 bucket credentials
- Create a backup target that stores the backups
- Create a backup plan, which holds the instruction on what to backup to protect the Minecraft server data and metadata (we don’t launch a backup yet, as we still have to deploy the Minecraft server and play a little):
[st@rtrek ansibledr]$ ansible-playbook backupsite.yaml PLAY [Preparing backup strategy] *************************************************************************** TASK [create the namespace "demo-minecraft"] *************************************************************************** changed: [localhost] TASK [Copy the secret yaml file] *************************************************************************** ok: [localhost] TASK [Ensure the secret is created] *************************************************************************** changed: [localhost] TASK [Copy target yaml file] *************************************************************************** ok: [localhost] TASK [Ensure target is available in "demo-minecraft"] *************************************************************************** changed: [localhost] TASK [Copy the backup plan yaml file] *************************************************************************** ok: [localhost] TASK [Ensure the backup plan is available] *************************************************************************** changed: [localhost]
In this step, we start using the demo-Minecraft namespace, go into the Minecraft directory, and execute the run.sh script. This is the script that basically creates the server, using a Helm chart. We can “oc logs” that Minecraft pod, and see when it finishes creating the world:
[st@rtrek ansibledr]$ oc project demo-minecraft Now using project "demo-minecraft" on server "https://api.trilio.cjlx.p1.openshiftapps.com:6443". [st@rtrek ansibledr]$ oc get all NAME READY STATUS RESTARTS AGE pod/aws-sa-demo4-target-validator-ep9zzt-sqrkb 1/1 Running 0 12s NAME COMPLETIONS DURATION AGE job.batch/aws-sa-demo4-target-validator-ep9zzt 0/1 13s 13s [st@rtrek ansibledr]$ cd Minecraft/ [st@rtrek Minecraft]$ ./run.sh clusterrole.rbac.authorization.k8s.io/system:openshift:scc:anyuid added: "default" Release "minecraft" does not exist. Installing it now. NAME: minecraft LAST DEPLOYED: Mon Jan 9 18:59:51 2023 NAMESPACE: demo-minecraft STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: Get the IP address of your Minecraft server by running these commands in the same shell: !! NOTE: It may take a few minutes for the LoadBalancer IP to be available. !! You can watch for EXTERNAL-IP to populate by running: kubectl get svc --namespace demo-minecraft -w minecraft-minecraft [st@rtrek Minecraft]$ oc logs minecraft-minecraft-696c6f8d94-v7t44 -f [18:01:30] [Worker-Main-3/INFO]: Preparing spawn area: 93% [18:01:31] [Worker-Main-1/INFO]: Preparing spawn area: 94% [18:01:31] [Worker-Main-1/INFO]: Preparing spawn area: 96% [18:01:32] [Worker-Main-3/INFO]: Preparing spawn area: 98% [18:01:32] [Server thread/INFO]: Time elapsed: 49400 ms [18:01:32] [Server thread/INFO]: Done (58.346s)! For help, type "help" ^C [st@rtrek Minecraft]$ oc get all NAME READY STATUS RESTARTS AGE pod/minecraft-minecraft-696c6f8d94-v7t44 1/1 Running 0 6m1s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/minecraft-minecraft LoadBalancer 172.30.11.145 af096cae3f32f4bebbfe04e63e196ff7-650369600.us-east-2.elb.amazonaws.com 25565:30331/TCP 6m1s NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/minecraft-minecraft 1/1 1 1 6m2s NAME DESIRED CURRENT READY AGE replicaset.apps/minecraft-minecraft-696c6f8d94 1 1 1 6m2s
With the next command, we see the LoadBalancer IP that we will use later on the Minecraft client to connect to the server:
[st@rtrek ansibledr]$ oc get all | grep LoadBalancer service/minecraft-minecraft LoadBalancer 172.30.11.145 af096cae3f32f4bebbfe04e63e196ff7-650369600.us-east-2.elb.amazonaws.com 25565:30331/TCP 51m
At this point, we have an address for the ELB → af096cae3f32f4bebbfe04e63e196ff7-650369600.us-east-2.elb.amazonaws.com
We use that in the Minecraft client:
Now we play a little, and then take a backup:
[st@rtrek ansibledr]$ ansible-playbook createbackup.yaml PLAY [Launch a backup] *************************************************************************** TASK [Copy the backup plan yaml file] *************************************************************************** ok: [localhost] TASK [Ensure the backup runs] *************************************************************************** changed: [localhost] [st@rtrek ansibledr]$ oc get backup NAME BACKUPPLAN BACKUP TYPE STATUS DATA SIZE CREATION TIME START TIME END TIME PERCENTAGE COMPLETED BACKUP SCOPE DURATION minecraft-backup minecraft-demo-backup-plan Full InProgress 0 2023-01-09T18:22:24Z 2023-01-09T18:22:24Z Namespace [st@rtrek ansibledr]$ oc get backup NAME BACKUPPLAN BACKUP TYPE STATUS DATA SIZE CREATION TIME START TIME END TIME PERCENTAGE COMPLETED BACKUP SCOPE DURATION minecraft-backup minecraft-demo-backup-plan Full Available 394395648 2023-01-09T18:22:24Z 2023-01-09T18:22:24Z 2023-01-09T18:27:39Z 100 Namespace 5m15.39490617s
Now that the backup is ready, we can restore the same in ARO, using the Trilio UI, or using an Ansible playbook to do it automatically.
Restore using Ansible Playbook:
We will run the playbook restoresite.yaml and this will do the whole process:
[st@rtrek ansibledr]$ ansible-playbook restorearo.yaml PLAY [Preparing restore strategy] *************************************************************************** TASK [create the namespace "demo-minecraft-restore"] *************************************************************************** changed: [localhost] TASK [Copy the secret yaml file] *************************************************************************** ok: [localhost] TASK [Ensure the secret is created] *************************************************************************** changed: [localhost] TASK [Copy target yaml file] *************************************************************************** ok: [localhost] TASK [Ensure target is available in "demo-minecraft-restore"] *************************************************************************** changed: [localhost] TASK [Copy the restore plan yaml file] *************************************************************************** changed: [localhost] TASK [Ensure the restore runs] *************************************************************************** changed: [localhost]
This playbook will create an empty namespace “demo-Minecraft-restore”, a secret for the target, a target (it holds the S3 bucket credentials), and run the restore.
After a few minutes, everything will be restored in that namespace, and ARO would have created a LoadBalancer which we will grab to use it in the Minecraft client:
[st@rtrek ansibledr]$ oc get all NAME READY STATUS RESTARTS AGE pod/aws-sa-demo4-target-browser-l7ztek-6b5575db7-g5sl6 1/1 Running 0 6m49s pod/minecfqnu-minecraft-6447d44cb5-v7qhh 0/1 Running 0 27s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/minecfqnu-minecraft LoadBalancer 172.30.184.128 20.102.37.28 25565:31879/TCP 28s service/tb-aws-sa-demo4-target-browser-l7ztek ClusterIP 172.30.154.178 <none> 80/TCP 6m50s NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/aws-sa-demo4-target-browser-l7ztek 1/1 1 1 6m50s deployment.apps/minecfqnu-minecraft 0/1 1 0 28s NAME DESIRED CURRENT READY AGE replicaset.apps/aws-sa-demo4-target-browser-l7ztek-6b5575db7 1 1 1 6m50s replicaset.apps/minecfqnu-minecraft-6447d44cb5 1 1 0 28s NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD route.route.openshift.io/tb-aws-sa-demo4-target-browser-l7ztek-f2zzf trilio-system.apps.nvsgu1at.eastus.aroapp.io /aws-sa-demo4-target.demo-minecraft-restore tb-aws-sa-demo4-target-browser-l7ztek http edge/Redirect None
In this case, is the IP 20.102.37.28:
And then we will be able to connect to the Minecraft Server running in ARO:
Restore using Trilio UI:
In this way of restoring the Minecraft server to ARO, what we do is access the Trilio UI (which is running inside ARO and exposed with a route.
Don’t be surprised if the IPs or Minecraft screenshots look different, as I recorded different videos, and different restores for this blog post.
We see in the screenshot that the Trilio UI is a multi-cluster UI, so we took the backup in the Rosa instance, and now we are going to access the backup target from the ARO instance and start restoring from there. The source cluster could be down or inaccessible, and that would not prevent us from being able to restore it anyway:
We go to targets, and select the aws-sa-demo4-target, where the backup was saved from Rosa:
We could select any backup on that backup target, but we choose the one we know the backup is:
And then the backup we want to restore, in this case we only have one backup, but we could have one full and several increments, and we could choose any of those:
Then we enter a name for the restore and the namespace where we want to restore. If the namespace where we want to restore does not exist, we can create it here:
The restoration will start at this point.
We can then go to ARO, and check that everything is being restored, like the Persistent Volume where the data is stored:
Here we can see how the Helm release was just created:
And if we go to the service, we will find the LoadBalancer created in ARO:
Then we grab the LoadBalancer IP and use it in the Minecraft client. At this point, we are in the same step as when we restored through Ansible. We only have to enter the IP, and connect to the Minecraft server:
And we can check that all our Minecraft inventory is where we left it!
YouTube video with everything, using the Trilio UR to do the migration/disaster recovery:
Thank you for getting there! I hope it was interesting for you.
The github repo where you can find the supporting files to test this demo is in the following URL:
https://github.com/trilio-demo/rosatoarodr
Useful Links:
- http://github.com/itzg/minecraft-server-charts
- http://github.com/itzg/minecraft-server-charts/tree/master/charts/minecraft
- http://github.com/gilesknap/k3s-minecraft
- http://artifacthub.io/packages/helm/minecraft-server-charts/minecraft
- Default values.yaml file http://github.com/itzg/minecraft-server-charts/blob/master/charts/minecraft/values.yaml
- https://www.plural.sh/blog/how-to-run-a-minecraft-server-on-a-kubernetes-cluster/