Backing up applications on ROSA clusters using OADP

You can use OpenShift API for Data Protection (OADP) with Red Hat OpenShift Service on AWS (ROSA) clusters to back up and restore application data.

ROSA is a fully-managed, turnkey application platform that allows you to deliver value to your customers by building and deploying applications.

ROSA provides seamless integration with a wide range of Amazon Web Services compute, database, analytics, machine learning, networking, mobile, and other services to speed up the building and delivery of differentiating experiences to your customers.

You can subscribe to the service directly from your AWS account.

After you create your clusters, you can operate your clusters with the OKD web console or through Red Hat OpenShift Cluster Manager. You can also use ROSA with OpenShift APIs and command-line interface (CLI) tools.

For additional information about ROSA installation, see Installing Red Hat Openshift Service on AWS (ROSA) interactive walkthrough.

Before installing OpenShift API for Data Protection (OADP), you must set up role and policy credentials for OADP so that it can use the Amazon Web Services (AWS) API.

This process is performed in the following two stages:

  1. Prepare AWS credentials

  2. Install the OADP Operator and give it an IAM role

Preparing AWS credentials for OADP

An Amazon Web Services (AWS) account must be prepared and configured to accept an OpenShift API for Data Protection (OADP) installation.

Procedure

  1. Create the following environment variables by running the following commands:

    Change the cluster name to match your ROSA cluster, and ensure you are logged into the cluster as an administrator. Ensure that all fields are outputted correctly before continuing.

    1. $ export CLUSTER_NAME=my-cluster (1)
    2. export ROSA_CLUSTER_ID=$(rosa describe cluster -c ${CLUSTER_NAME} --output json | jq -r .id)
    3. export REGION=$(rosa describe cluster -c ${CLUSTER_NAME} --output json | jq -r .region.id)
    4. export OIDC_ENDPOINT=$(oc get authentication.config.openshift.io cluster -o jsonpath='{.spec.serviceAccountIssuer}' | sed 's|^https://||')
    5. export AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
    6. export CLUSTER_VERSION=$(rosa describe cluster -c ${CLUSTER_NAME} -o json | jq -r .version.raw_id | cut -f -2 -d '.')
    7. export ROLE_NAME="${CLUSTER_NAME}-openshift-oadp-aws-cloud-credentials"
    8. export SCRATCH="/tmp/${CLUSTER_NAME}/oadp"
    9. mkdir -p ${SCRATCH}
    10. echo "Cluster ID: ${ROSA_CLUSTER_ID}, Region: ${REGION}, OIDC Endpoint:
    11. ${OIDC_ENDPOINT}, AWS Account ID: ${AWS_ACCOUNT_ID}"
    1Replace my-cluster with your ROSA cluster name.
  2. On the AWS account, create an IAM policy to allow access to AWS S3:

    1. Check to see if the policy exists by running the following command:

      1. $ POLICY_ARN=$(aws iam list-policies --query "Policies[?PolicyName=='RosaOadpVer1'].{ARN:Arn}" --output text) (1)
      1Replace RosaOadp with your policy name.
    2. Enter the following command to create the policy JSON file and then create the policy in ROSA:

      If the policy ARN is not found, the command creates the policy. If the policy ARN already exists, the if statement intentionally skips the policy creation.

      1. $ if [[ -z "${POLICY_ARN}" ]]; then
      2. cat << EOF > ${SCRATCH}/policy.json (1)
      3. {
      4. "Version": "2012-10-17",
      5. "Statement": [
      6. {
      7. "Effect": "Allow",
      8. "Action": [
      9. "s3:CreateBucket",
      10. "s3:DeleteBucket",
      11. "s3:PutBucketTagging",
      12. "s3:GetBucketTagging",
      13. "s3:PutEncryptionConfiguration",
      14. "s3:GetEncryptionConfiguration",
      15. "s3:PutLifecycleConfiguration",
      16. "s3:GetLifecycleConfiguration",
      17. "s3:GetBucketLocation",
      18. "s3:ListBucket",
      19. "s3:GetObject",
      20. "s3:PutObject",
      21. "s3:DeleteObject",
      22. "s3:ListBucketMultipartUploads",
      23. "s3:AbortMultipartUploads",
      24. "s3:ListMultipartUploadParts",
      25. "s3:DescribeSnapshots",
      26. "ec2:DescribeVolumes",
      27. "ec2:DescribeVolumeAttribute",
      28. "ec2:DescribeVolumesModifications",
      29. "ec2:DescribeVolumeStatus",
      30. "ec2:CreateTags",
      31. "ec2:CreateVolume",
      32. "ec2:CreateSnapshot",
      33. "ec2:DeleteSnapshot"
      34. ],
      35. "Resource": "*"
      36. }
      37. ]}
      38. EOF
      39. POLICY_ARN=$(aws iam create-policy --policy-name "RosaOadpVer1" \
      40. --policy-document file:///${SCRATCH}/policy.json --query Policy.Arn \
      41. --tags Key=rosa_openshift_version,Value=${CLUSTER_VERSION} Key=rosa_role_prefix,Value=ManagedOpenShift Key=operator_namespace,Value=openshift-oadp Key=operator_name,Value=openshift-oadp \
      42. --output text)
      43. fi
      1SCRATCH is a name for a temporary directory created for the environment variables.
    3. View the policy ARN by running the following command:

      1. $ echo ${POLICY_ARN}
  3. Create an IAM role trust policy for the cluster:

    1. Create the trust policy file by running the following command:

      1. $ cat <<EOF > ${SCRATCH}/trust-policy.json
      2. {
      3. "Version":2012-10-17",
      4. "Statement": [{
      5. "Effect": "Allow",
      6. "Principal": {
      7. "Federated": "arn:aws:iam::${AWS_ACCOUNT_ID}:oidc-provider/${OIDC_ENDPOINT}"
      8. },
      9. "Action": "sts:AssumeRoleWithWebIdentity",
      10. "Condition": {
      11. "StringEquals": {
      12. "${OIDC_ENDPOINT}:sub": [
      13. "system:serviceaccount:openshift-adp:openshift-adp-controller-manager",
      14. "system:serviceaccount:openshift-adp:velero"]
      15. }
      16. }
      17. }]
      18. }
      19. EOF
    2. Create the role by running the following command:

      1. $ ROLE_ARN=$(aws iam create-role --role-name \
      2. "${ROLE_NAME}" \
      3. --assume-role-policy-document file://${SCRATCH}/trust-policy.json \
      4. --tags Key=rosa_cluster_id,Value=${ROSA_CLUSTER_ID} Key=rosa_openshift_version,Value=${CLUSTER_VERSION} Key=rosa_role_prefix,Value=ManagedOpenShift Key=operator_namespace,Value=openshift-adp Key=operator_name,Value=openshift-oadp \
      5. --query Role.Arn --output text)
    3. View the role ARN by running the following command:

      1. $ echo ${ROLE_ARN}
  4. Attach the IAM policy to the IAM role by running the following command:

    1. $ aws iam attach-role-policy --role-name "${ROLE_NAME}" \
    2. --policy-arn ${POLICY_ARN}

Installing the OADP Operator and providing the IAM role

AWS Security Token Service (AWS STS) is a global web service that provides short-term credentials for IAM or federated users. OKD (ROSA) with STS is the recommended credential mode for ROSA clusters. This document describes how to install OpenShift API for Data Protection (OADP) on ROSA with AWS STS.

Restic and Kopia are not supported in the OADP on ROSA with AWS STS environment. Verify that the Restic and Kopia node agent is disabled. For backing up volumes, OADP on ROSA with AWS STS supports only native snapshots and Container Storage Interface (CSI) snapshots.

In an Amazon ROSA cluster that uses STS authentication, restoring backed-up data in a different AWS region is not supported.

The Data Mover feature is not currently supported in ROSA clusters. You can use native AWS S3 tools for moving data.

Prerequisites

  • An OKD ROSA cluster with the required access and tokens. For instructions, see the previous procedure Preparing AWS credentials for OADP. If you plan to use two different clusters for backing up and restoring, you must prepare AWS credentials, including ROLE_ARN, for each cluster.

Procedure

  1. Create an OKD secret from your AWS token file by entering the following commands:

    1. Create the credentials file:

      1. $ cat <<EOF > ${SCRATCH}/credentials
      2. [default]
      3. role_arn = ${ROLE_ARN}
      4. web_identity_token_file = /var/run/secrets/openshift/serviceaccount/token
      5. EOF
    2. Create a namespace for OADP:

      1. $ oc create namespace openshift-adp
    3. Create the OKD secret:

      1. $ oc -n openshift-adp create secret generic cloud-credentials \
      2. --from-file=${SCRATCH}/credentials

      In OKD versions 4.14 and later, the OADP Operator supports a new standardized STS workflow through the Operator Lifecycle Manager (OLM) and Cloud Credentials Operator (CCO). In this workflow, you do not need to create the above secret, you only need to supply the role ARN during the installation of OLM-managed operators using the OKD web console, for more information see Installing from OperatorHub using the web console.

      The preceding secret is created automatically by CCO.

  2. Install the OADP Operator:

    1. In the OKD web console, browse to OperatorsOperatorHub.
  3. Install the OADP Operator:

    1. In the OKD web console, browse to OperatorsOperatorHub.

    2. Search for the OADP Operator.

    3. In the role_ARN field, paste the role_arn that you created previously and click Install.

  4. Create AWS cloud storage using your AWS credentials by entering the following command:

    1. $ cat << EOF | oc create -f -
    2. apiVersion: oadp.openshift.io/v1alpha1
    3. kind: CloudStorage
    4. metadata:
    5. name: ${CLUSTER_NAME}-oadp
    6. namespace: openshift-adp
    7. spec:
    8. creationSecret:
    9. key: credentials
    10. name: cloud-credentials
    11. enableSharedConfig: true
    12. name: ${CLUSTER_NAME}-oadp
    13. provider: aws
    14. region: $REGION
    15. EOF
  5. Check your application’s storage default storage class by entering the following command:

    1. $ oc get pvc -n <namespace>

    Example output

    1. NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
    2. applog Bound pvc-351791ae-b6ab-4e8b-88a4-30f73caf5ef8 1Gi RWO gp3-csi 4d19h
    3. mysql Bound pvc-16b8e009-a20a-4379-accc-bc81fedd0621 1Gi RWO gp3-csi 4d19h
  6. Get the storage class by running the following command:

    1. $ oc get storageclass

    Example output

    1. NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
    2. gp2 kubernetes.io/aws-ebs Delete WaitForFirstConsumer true 4d21h
    3. gp2-csi ebs.csi.aws.com Delete WaitForFirstConsumer true 4d21h
    4. gp3 ebs.csi.aws.com Delete WaitForFirstConsumer true 4d21h
    5. gp3-csi (default) ebs.csi.aws.com Delete WaitForFirstConsumer true 4d21h

    The following storage classes will work:

    • gp3-csi

    • gp2-csi

    • gp3

    • gp2

    If the application or applications that are being backed up are all using persistent volumes (PVs) with Container Storage Interface (CSI), it is advisable to include the CSI plugin in the OADP DPA configuration.

  7. Create the DataProtectionApplication resource to configure the connection to the storage where the backups and volume snapshots are stored:

    1. If you are using only CSI volumes, deploy a Data Protection Application by entering the following command:

      1. $ cat << EOF | oc create -f -
      2. apiVersion: oadp.openshift.io/v1alpha1
      3. kind: DataProtectionApplication
      4. metadata:
      5. name: ${CLUSTER_NAME}-dpa
      6. namespace: openshift-adp
      7. spec:
      8. backupImages: false
      9. features:
      10. dataMover:
      11. enable: false
      12. backupLocations:
      13. - bucket:
      14. cloudStorageRef:
      15. name: ${CLUSTER_NAME}-oadp
      16. credential:
      17. key: credentials
      18. name: cloud-credentials
      19. default: true
      20. config:
      21. region: ${REGION}
      22. configuration:
      23. velero:
      24. defaultPlugins:
      25. - openshift
      26. - aws
      27. - csi
      28. restic:
      29. enable: false
      30. EOF
    2. If you are using CSI or non-CSI volumes, deploy a Data Protection Application by entering the following command:

      1. $ cat << EOF | oc create -f -
      2. apiVersion: oadp.openshift.io/v1alpha1
      3. kind: DataProtectionApplication
      4. metadata:
      5. name: ${CLUSTER_NAME}-dpa
      6. namespace: openshift-adp
      7. spec:
      8. backupLocations:
      9. - bucket:
      10. cloudStorageRef:
      11. name: ${CLUSTER_NAME}-oadp
      12. credential:
      13. key: credentials
      14. name: cloud-credentials
      15. default: true
      16. config:
      17. region: ${REGION}
      18. configuration:
      19. velero:
      20. defaultPlugins:
      21. - openshift
      22. - aws
      23. nodeAgent: (1)
      24. enable: false
      25. uploaderType: restic
      26. snapshotLocations:
      27. - velero:
      28. config:
      29. credentialsFile: /tmp/credentials/openshift-adp/cloud-credentials-credentials (2)
      30. enableSharedConfig: "true" (3)
      31. profile: default (4)
      32. region: ${REGION} (5)
      33. provider: aws
      34. EOF
      1See the following note.
      2The credentialsFile field is the mounted location of the bucket credential on the pod.
      3The enableSharedConfig field allows the snapshotLocations to share or reuse the credential defined for the bucket.
      4Use the profile name set in the AWS credentials file.
      5Specify region as your AWS region. This must be the same as the cluster region.

      You are now ready to back up and restore OKD applications, as described in Backing up applications.

The enable parameter of restic is set to false in this configuration, because OADP does not support Restic in ROSA environments.

If you use OADP 1.2, replace this configuration:

  1. nodeAgent:
  2. enable: false
  3. uploaderType: restic

with the following configuration:

  1. restic:
  2. enable: false

If you want to use two different clusters for backing up and restoring, the two clusters must have the same AWS S3 storage names in both the cloud storage CR and the OADP DataProtectionApplication configuration.

Additional resources

Example: Backing up workload on OADP ROSA STS, with an optional cleanup

Performing a backup with OADP and ROSA STS

The following example hello-world application has no persistent volumes (PVs) attached. Perform a backup with OpenShift API for Data Protection (OADP) with Red Hat OpenShift Service on AWS (ROSA) STS.

Either Data Protection Application (DPA) configuration will work.

  1. Create a workload to back up by running the following commands:

    1. $ oc create namespace hello-world
    1. $ oc new-app -n hello-world --image=docker.io/openshift/hello-openshift
  2. Expose the route by running the following command:

    1. $ oc expose service/hello-openshift -n hello-world
  3. Check that the application is working by running the following command:

    1. $ curl `oc get route/hello-openshift -n hello-world -o jsonpath='{.spec.host}'`

    Example output

    1. Hello OpenShift!
  4. Back up the workload by running the following command:

    1. $ cat << EOF | oc create -f -
    2. apiVersion: velero.io/v1
    3. kind: Backup
    4. metadata:
    5. name: hello-world
    6. namespace: openshift-adp
    7. spec:
    8. includedNamespaces:
    9. - hello-world
    10. storageLocation: ${CLUSTER_NAME}-dpa-1
    11. ttl: 720h0m0s
    12. EOF
  5. Wait until the backup is completed and then run the following command:

    1. $ watch "oc -n openshift-adp get backup hello-world -o json | jq .status"

    Example output

    1. {
    2. "completionTimestamp": "2022-09-07T22:20:44Z",
    3. "expiration": "2022-10-07T22:20:22Z",
    4. "formatVersion": "1.1.0",
    5. "phase": "Completed",
    6. "progress": {
    7. "itemsBackedUp": 58,
    8. "totalItems": 58
    9. },
    10. "startTimestamp": "2022-09-07T22:20:22Z",
    11. "version": 1
    12. }
  6. Delete the demo workload by running the following command:

    1. $ oc delete ns hello-world
  7. Restore the workload from the backup by running the following command:

    1. $ cat << EOF | oc create -f -
    2. apiVersion: velero.io/v1
    3. kind: Restore
    4. metadata:
    5. name: hello-world
    6. namespace: openshift-adp
    7. spec:
    8. backupName: hello-world
    9. EOF
  8. Wait for the Restore to finish by running the following command:

    1. $ watch "oc -n openshift-adp get restore hello-world -o json | jq .status"

    Example output

    1. {
    2. "completionTimestamp": "2022-09-07T22:25:47Z",
    3. "phase": "Completed",
    4. "progress": {
    5. "itemsRestored": 38,
    6. "totalItems": 38
    7. },
    8. "startTimestamp": "2022-09-07T22:25:28Z",
    9. "warnings": 9
    10. }
  9. Check that the workload is restored by running the following command:

    1. $ oc -n hello-world get pods

    Example output

    1. NAME READY STATUS RESTARTS AGE
    2. hello-openshift-9f885f7c6-kdjpj 1/1 Running 0 90s
  10. Check the JSONPath by running the following command:

    1. $ curl `oc get route/hello-openshift -n hello-world -o jsonpath='{.spec.host}'`

    Example output

    1. Hello OpenShift!

For troubleshooting tips, see the OADP team’s troubleshooting documentation.

Cleaning up a cluster after a backup with OADP and ROSA STS

If you need to uninstall the OpenShift API for Data Protection (OADP) Operator together with the backups and the S3 bucket from this example, follow these instructions.

Procedure

  1. Delete the workload by running the following command:

    1. $ oc delete ns hello-world
  2. Delete the Data Protection Application (DPA) by running the following command:

    1. $ oc -n openshift-adp delete dpa ${CLUSTER_NAME}-dpa
  3. Delete the cloud storage by running the following command:

    1. $ oc -n openshift-adp delete cloudstorage ${CLUSTER_NAME}-oadp

    If this command hangs, you might need to delete the finalizer by running the following command:

    1. $ oc -n openshift-adp patch cloudstorage ${CLUSTER_NAME}-oadp -p ‘{“metadata”:{“finalizers”:null}}’ type=merge
  4. If the Operator is no longer required, remove it by running the following command:

    1. $ oc -n openshift-adp delete subscription oadp-operator
  5. Remove the namespace from the Operator:

    1. $ oc delete ns openshift-adp
  6. If the backup and restore resources are no longer required, remove them from the cluster by running the following command:

    1. $ oc delete backup hello-world
  7. To delete backup, restore and remote objects in AWS S3 run the following command:

    1. $ velero backup delete hello-world
  8. If you no longer need the Custom Resource Definitions (CRD), remove them from the cluster by running the following command:

    1. $ for CRD in `oc get crds | grep velero | awk '{print $1}'`; do oc delete crd $CRD; done
  9. Delete the AWS S3 bucket by running the following commands:

    1. $ aws s3 rm s3://${CLUSTER_NAME}-oadp --recursive
    1. $ aws s3api delete-bucket --bucket ${CLUSTER_NAME}-oadp
  10. Detach the policy from the role by running the following command:

    1. $ aws iam detach-role-policy --role-name "${ROLE_NAME}" \
    2. --policy-arn "${POLICY_ARN}"
  11. Delete the role by running the following command:

    1. $ aws iam delete-role --role-name "${ROLE_NAME}"