***************************************** Example Workflow utilizing ROBIN Storage ***************************************** In the guide below, we will showcase how to deploy a MariaDB application via Helm using ROBIN Storage and introduce some basic application life cycle management features provided by ROBIN. --------------- App Deployment --------------- Deploy the necessary Tiller Objects ----------------------------------- .. code-block:: console $ robin k8s deploy-tiller-objects Tiller objects were successfully deployed for namespace 'default' Configure helm for your ROBIN cluster ------------------------------------- .. note:: Helm should already be pre-installed on the machine you wish to run ROBIN commands from. The below steps only configure Helm for optimal use. To install Helm, read the instructions available `here `_. .. code-block:: console $ robin k8s helm-setup HELM_HOME has been configured at /root/.helm. Tiller (the Helm server-side component) has been installed into your Kubernetes Cluster. Please note: by default, Tiller is deployed with an insecure 'allow unauthenticated users' policy. For more information on securing your installation see: https://docs.helm.sh/using_helm/#securing-your-helm-installation Happy Helming! You should see pod named tiller-deploy running now: .. code-block:: console $ kubectl get pods -n default NAME READY STATUS RESTARTS AGE tiller-deploy-5bfb586db7-4xmk2 1/1 Running 0 77s Add the `stable` Helm repositry -------------------------------- .. code-block:: console $ helm repo add stable https://kubernetes-charts.storage.googleapis.com/ "stable" has been added to your repositories Deploy the MariaDB helm chart using the ROBIN storage class --------------------------------------------------------------------- First get the name of the ROBIN storage class available on your machine, by running the following command: .. code-block:: console $ kubectl get sc NAME PROVISIONER AGE robin (default) robin 15m To create the MariaDB app run the following command with the ROBIN storage class discoved above in place of : .. code-block:: console $ helm install stable/mariadb --name users --set master.persistence.storageClass= \ --set master.persistence.size=20Gi --set slave.persistence.storageClass= \ --set slave.persistence.size=20Gi --set db.name=testdb --tls --tiller-namespace default The output should look something similar to this: .. code-block:: console $ helm install stable/mariadb --name users --set master.persistence.storageClass=robin \ --set master.persistence.size=20Gi --set slave.persistence.storageClass=robin \ --set slave.persistence.size=20Gi --set db.name=testdb --tls --tiller-namespace default NAME: users LAST DEPLOYED: Fri May 24 16:09:44 2019 NAMESPACE: default STATUS: DEPLOYED RESOURCES: ==> v1/ConfigMap NAME DATA AGE users-mariadb-master 1 0s users-mariadb-slave 1 0s users-mariadb-tests 1 0s ==> v1/Service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE users-mariadb ClusterIP 172.19.151.176 3306/TCP 0s users-mariadb-slave ClusterIP 172.19.199.152 3306/TCP 0s ==> v1beta1/StatefulSet NAME DESIRED CURRENT AGE users-mariadb-master 1 1 0s users-mariadb-slave 1 1 0s ==> v1/Pod(related) NAME READY STATUS RESTARTS AGE users-mariadb-master-0 0/1 Pending 0 0s users-mariadb-slave-0 0/1 Pending 0 0s ==> v1/Secret NAME TYPE DATA AGE users-mariadb Opaque 2 0s The above command will deploy a MariaDB application named users containing a MySQL database named testdb. Note the size values given are arbitrary, change them as per your cluster restrictions. .. note:: Before running the install command ensure that the ROBIN storage class name specified is correct as for Kubernetes versions newer than 1.13 it appears as `robin` but for older versions it is displayed as `robin-0-3` We can see that the application is created using the `robin` storage class by looking at the details of the pvcs created: .. code-block:: console $ kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE data-users-mariadb-master-0 Bound pvc-0509988e-7e79-11e9-bf41-00155d61160c 20Gi RWO robin 7h30m data-users-mariadb-slave-0 Bound pvc-0511def7-7e79-11e9-bf41-00155d61160c 20Gi RWO robin 7h30m Register the application with ROBIN ------------------------------------ .. code-block:: console $ robin app register demo --app helm/users Job: 11 Name: K8SAppRegister State: WAITING Error: 0 Job: 11 Name: K8SAppRegister State: COMPLETED Error: 0 The above command will allow ROBIN to capture all of the Kubernetes objects related to the specified Helm application. To verify all of the neccessary objects are being tracked you can run the following command: .. code-block:: console $ robin app status --app demo +-----------------------+-----------------------------+--------+ | Kind | Name | Status | +-----------------------+-----------------------------+--------+ | ConfigMap | users-mariadb-slave | Ready | | ConfigMap | users-mariadb-master | Ready | | Secret | users-mariadb | Ready | | PersistentVolumeClaim | data-users-mariadb-master-0 | Bound | | PersistentVolumeClaim | data-users-mariadb-slave-0 | Bound | | Pod | users-mariadb-slave-0 | Ready | | Pod | users-mariadb-master-0 | Ready | | Service | users-mariadb-slave | Ready | | Service | users-mariadb | Ready | | StatefulSet | users-mariadb-slave | Ready | | StatefulSet | users-mariadb-master | Ready | +-----------------------+-----------------------------+--------+ .. note:: It is highly recommended to wait for all the necessary objects to be in a good state before running additional ROBIN commands. ------------------------------------------ Application Lifecycle Management Features ------------------------------------------ Detailed below are quick start commands of some of the advanced application lifecycle management tools that ROBIN provides. Snapshots --------- A **snapshot** is a reference marker for an application at a particular point in time. Snapshots are useful for example to instantaneously recover an application to a known healthy state in the event of corruption. For more details on snapshots please visit this `section `_. To create a snapshot named `snap1` of the registered `demo` application, run the following command: .. code-block:: console $ robin snapshot create snap1 demo --wait Job: 14 Name: K8SApplicationSnapshot State: VALIDATED Error: 0 Job: 14 Name: K8SApplicationSnapshot State: WAITING Error: 0 Job: 14 Name: K8SApplicationSnapshot State: COMPLETED Error: 0 To verify that has been created, run the following command: .. code-block:: console $ robin snapshot list +----------------------------------+--------+----------+----------+---------------+ | Snapshot ID | State | App Name | App type | Snapshot name | +----------------------------------+--------+----------+----------+---------------+ | 0283d21e7ebc11e9ba4e39b23cfec954 | ONLINE | demo | helm | demo_snap1 | +----------------------------------+--------+----------+----------+---------------+ For further information on additional snapshot commands click `here `_. Clones ------ A clone is a copy of an existing application. Cloning is useful when you want to run reports on a database without affecting the source database application, or for performing UAT tests or for validating patches before applying them to the production database. For more details on clones please visit this `section `_. To create a clone named `clone1` from the snapshot we created previously, run the following command: .. code-block:: console $ robin clone create clone1 0283d21e7ebc11e9ba4e39b23cfec954 --wait Job: 18 Name: K8SApplicationClone State: WAITING Error: 0 Job: 18 Name: K8SApplicationClone State: AGENT_WAIT Error: 0 Job: 18 Name: K8SApplicationClone State: COMPLETED Error: 0 .. note:: Snapshot IDs are randomly generated with every snapshot creation and hence the command run here will have to be changed to reflect the Snapshot ID generated by your ROBIN cluster. To verify the clone has been created and registered with ROBIN, run the following command: .. code-block:: console $ robin app list +--------+---------+-----------+-----------+---------+ | Name | Type | Namespace | Snapshots | Backups | +--------+---------+-----------+-----------+---------+ | demo | helm | default | 1 | 0 | | clone1 | flexapp | default | 0 | 0 | +--------+---------+-----------+-----------+---------+ In addition since a cloned application is considered a standalone, independent application we can check the status of its objects by running the following command: .. code-block:: console $ robin app status --app clone1 +-----------------------+------------------------------------+----------+ | Kind | Name | Status | +-----------------------+------------------------------------+----------+ | ConfigMap | clone1-users-mariadb-master | Ready | | ConfigMap | clone1-users-mariadb-slave | Ready | | Secret | clone1-users-mariadb | Ready | | PersistentVolumeClaim | data-clone1-users-mariadb-slave-0 | Bound | | PersistentVolumeClaim | data-clone1-users-mariadb-master-0 | Bound | | Pod | clone1-users-mariadb-master-0 | Ready | | Pod | clone1-users-mariadb-slave-0 | Ready | | Service | clone1-users-mariadb-slave | Ready | | Service | clone1-users-mariadb | Ready | | StatefulSet | clone1-users-mariadb-master | Ready | | StatefulSet | clone1-users-mariadb-slave | Ready | +-----------------------+------------------------------------+----------+ Backups ------- ROBIN allows users to backup their applications (along with the data attached) by creating copies of the metadata and volume data referenced by a snapshot in an external repository such as S3 Object Store, Google Cloud Storage, etc. This in turn makes their stateful applications portable across Kubernetes clusters spanning on-prem, publc and hybrid cloud environments. Registering a Repository ~~~~~~~~~~~~~~~~~~~~~~~~ To create a backup, one must register the repository to which the data will be pushed with ROBIN. To do so run the following command: .. code-block:: console $ robin repo register demo-backup gcs://demos-backup-tutorial /root/gcs.json readwrite --wait Job: 20 Name: StorageRepoAdd State: WAITING Error: 0 Job: 20 Name: StorageRepoAdd State: COMPLETED Error: 0 An example of the JSON file needed to register a GCS bucket is detailed below: .. code-block:: json { "type": "service_account", "project_id": "rock-range-805623", "privbte_key_id": "c9fde8c819735439248147457629895ebbcc1f21", "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgpqkkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDXlyNg3997PJlA\nyS9doXSfX5lEpDgmk7nATyOrKQkl1D3/bWvoFMR372i0WKopj5FvLNY42jrcRzjF\nTlbJuwP4WAU652ss3qEvnUgd+mD7CcjOWd9bAA6vPJAJDo/TtTleZNQWd96y2WbT\nH/BqI9UCxdWNfsuYHQtpVViPdviizU3AxFtD6NTN/KmUX9mlM6RuF2RXAc5N/p4X\nhbeSV+rSfEgb9PA2U+fwobGzeR97V4SwK15btPpSN5twf0Wy49zGQLONFcmfwhRc\n+3r3gpPfqb+cb1xWiiD5fgO4yWYcWQXJJgUumVtVZxikc6k+9Vbko9zw20NNzRgp\nKfZdtm1jAgMBAAECggEABx+l2h4bntFWSQc3yu26UkfQ4y0/37pe4WVcCtxMwpS3\nUEbV+7Gv+mbYwVjKqpvlVNSY3YD4f+3UiOR5RIzK6UpTRep+ppoPzGh4iREMYk3k\n9PiQQkwCsDSil3IE65xp3F4die6FC3jWNFdSVNeBQtmxoD7H0GtpRJ4+0mK+fXbW\nr5f6O3WES4nOTNRonOdg9bIJJKklt3GSjtd1X5JWfGU53sbrksvy31+hL71pXCQn\nUZlkoilc3KYGnesd3KwIpxX9Pi5TldNUWuSnibvgXnDjM05PuQ0YI9VEfVR+eDfI\nBZAw2b/dmCWyU3QVAMtRbhwISmbxB33rZ133gTVN/QKBgQD5ZTZSnf7/b0YdKcAD\nP3bevN3/0s9EXO+D62MTRdrNeyb46hAcbNHmzAvgqtB74bQxiF5hs6RbmTmUpVpL\nSyCl6lqf3eMzP2gdECRLmkeZKpiWtfbPNbTefGVvbvWG6vi3E6+b/5cKPVHMLSV6\n4LIbqpVyWFWM905MXU9cgFgJDwKBgQDdTL5Yl3G/91HnyFieQ9pju6C9v1S3277k\nN10hcmldkJWludgT3WzDsNmbcAdCp+KOtQusf6KMKT5sd5ickMmAI3IZkzsgb7rS\n7AVBf3bpLG+3kOGJ4PVGKXfTEONw7hSo1UwLQxSZj1SMTtOd63pFcVea1hYQXifr\nADUrkwhObQKBgQCTb9pljTIrIEV7CCuTwChTv6QekSonaCnQ+19fDXUE9UFc9kMA\nCvUsVITRFSqbkhHXlp71c5Y+3J6x2e3/g/KRI7Lfv/WJXnrWc6yBZXveeOgscPaK\nQ13iCfiNndX5JQBXb+vo3iEU1Jt+3VGvCxc/3IjtSHuLEskfLCq2rMle0QKBgQCX\nsTJM0gGKT8KCCc/M9J/vez6Msmkk+mkYUGbzNVTKQQCDMCfQPhh+72vKY3lmlGP1\nBF7zKC5Iu0DB4xzmPU0SG/DBzS1bZ5r9V7GmmvPsk3wkrRgcheo65NPxBwOQdnIM\n5OCSW7H0LM58us/N0UG+Zhnx1cwb/h6ItIS90LSB5QKBgCwZPxhDhlKXGn3J8sLn\nuZ9WjFTBlabt8mksHpnE4xgj5BeOXee29CtaX+mPIcPEOO9ynsbizaSv7I2kBM+d\n9DZt9XiM6NcjrqtP7FCdgvZeQV0GIHjlqj2zH0UDxImGmENyHeXA1X2d0fZwzuJ+\n5dEZAfYh4QAnnPiAF5K9QFEi\n-----END PRIVATE KEY-----\n", "client_email": "jamesbond-cloud-repo@rock-range-805623.iam.gserviceaccount.com", "client_id": "1815195052297641083965", "auth_uri": "https://accounts.google.com/o/oauth2/auth", "token_uri": "https://oauth2.googleapis.com/token", "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/jamesbond-cloud-repo%40rock-range-805623.iam.gserviceaccount.com" } To verify the repository has been successfully added, run the following command: .. code-block:: console $ robin repo list +-------------+------+------------------+--------------+-----------------------+------+-------------+ | Name | Type | Owner/Tenant | BackupTarget | Bucket | Path | Permissions | +-------------+------+------------------+--------------+-----------------------+------+-------------+ | demo-backup | GCS | robin/K8sCluster | 1 | demos-backup-tutorial | - | readwrite | +-------------+------+------------------+--------------+-----------------------+------+-------------+ For further information on how to register a repository or additional repo commands, click `here `_. Attaching a Repository ~~~~~~~~~~~~~~~~~~~~~~~ Since snapshots are linked to applications, repositories to which their backups need to be pushed to also need to be attached to the respective applications. To attach a registered repository to an appliction, run the following command: .. code-block:: console $ robin repo attach demo-backup demo --wait Job: 21 Name: K8SApplicationAddRepo State: DONE Error: 0 Job: 21 Name: K8SApplicationAddRepo State: COMPLETED Error: 0 To verify the repository `demo-backup` has been attached to app `demo`, run the following command: .. code-block:: console $ robin repo info demo-backup Name : demo-backup Type : GCS Bucket : demos-backup-tutorial Path : - Permissions : readwrite Scan Details ------- Scan State : SUCCESS Start Time : 2019-05-25 01:17:02 End Time : 2019-05-25 01:17:02 Time Taken : 0s Scan Error : - Scan Diff : {'added': 0, 'removed': 0} Apps attached: 1 helm/demo For further information on additional repo commands, click `here `_. Creating a Backup ~~~~~~~~~~~~~~~~~~ After your destination repository has been successfully registered and attached to the appropriate app one can create a backup by running the following command: .. code-block:: console $ robin backup create backup1 0283d21e7ebc11e9ba4e39b23cfec954 demo-backup --wait Job: 22 Name: K8SApplicationBackup State: VALIDATED Error: 0 Job: 22 Name: K8SApplicationBackup State: AGENT_WAIT Error: 0 Job: 22 Name: K8SApplicationBackup State: COMPLETED Error: 0 .. note:: Snapshot IDs are randomly generated with every snapshot creation and hence the command run here will have to be changed to reflect the Snapshot ID generated by your ROBIN cluster. To verify the backup has been successfully pushed, run the following command: .. code-block:: console $ robin backup list +----------------------------------+-------------+-------------+---------------+--------+ | Backup ID | Backup Name | Repo | Snapshot Name | State | +----------------------------------+-------------+-------------+---------------+--------+ | 2a4edd9a7ec611e9a36c9fa69c009ecb | backup1 | demo-backup | demo_snap1 | Pushed | +----------------------------------+-------------+-------------+---------------+--------+ For further information on additional repo commands, click `here `_.