Transitioning data to Azure cloud service
You can transition data to a remote cloud service as part of the lifecycle configuration using storage classes to reduce cost and improve manageability. The transition is unidirectional and data cannot be transitioned back from the remote zone. This feature is to enable data transition to multiple cloud providers such as Azure. One of the key differences with the AWS configuration is that you need to configure the multi-cloud gateway (MCG) and use MCG to translate from the S3 protocol to Azure Blob.
Use cloud-s3 as tier-type to configure the remote cloud S3
object store service to which the data needs to be transitioned. These do not need a data pool and
are defined in terms of the zonegroup placement targets.
Prerequisites
-
A running IBM Storage Ceph cluster with Ceph Object Gateway installed.
-
User credentials for the remote cloud service, Azure.
-
Azure configured locally to download data.
-
s3cmdinstalled on the bootstrapped node. -
Azure container for the for MCG namespace created. In this example, it is
mcgnamespace.
Procedure
-
Create a user with access key and secret key:
Syntaxradosgw-admin user create --uid=USER_NAME --display-name="DISPLAY_NAME" [--access-key ACCESS_KEY --secret-key SECRET_KEY]Example[ceph: root@host01 /]# radosgw-admin user create --uid=test-user --display-name="test-user" --access-key a21e86bce636c3aa1 --secret-key cf764951f1fdde5e { "user_id": "test-user", "display_name": "test-user", "email": "", "suspended": 0, "max_buckets": 1000, "subusers": [], "keys": [ { "user": "test-user", "access_key": "a21e86bce636c3aa1", "secret_key": "cf764951f1fdde5e" } ], "swift_keys": [], "caps": [], "op_mask": "read, write, delete", "default_placement": "", "default_storage_class": "", "placement_tags": [], "bucket_quota": { "enabled": false, "check_on_raw": false, "max_size": -1, "max_size_kb": 0, "max_objects": -1 }, "user_quota": { "enabled": false, "check_on_raw": false, "max_size": -1, "max_size_kb": 0, "max_objects": -1 }, "temp_url_keys": [], "type": "rgw", "mfa_ids": [] } -
As a root user, configure AWS CLI with the user credentials and create a bucket with default placement:
Syntaxaws s3 --ca-bundle CA_PERMISSION --profile rgw --endpoint ENDPOINT_URL --region default mb s3://BUCKET_NAMEExample[root@host01 ~]$ aws s3 --ca-bundle /etc/pki/ca-trust/source/anchors/myCA.pem --profile rgw --endpoint https://host02.example.com:8043 --region default mb s3://transition -
Verify that the bucket is using
default-placementwith the placement rule:Example[root@host01 ~]# radosgw-admin bucket stats --bucket transition { "bucket": "transition", "num_shards": 11, "tenant": "", "zonegroup": "b29b0e50-1301-4330-99fc-5cdcfc349acf", "placement_rule": "default-placement", "explicit_placement": { "data_pool": "", "data_extra_pool": "", "index_pool": "" }, -
Log into the OpenShift Container Platform (OCP) cluster with OpenShift Data Foundation (ODF) deployed:
Example[root@host01 ~]$ oc project openshift-storage [root@host01 ~]$ oc get clusterversion NAME VERSION AVAILABLE PROGRESSING SINCE STATUS version 4.11.6 True False 4d1h Cluster version is 4.11.6 [root@host01 ~]$ oc get storagecluster NAME AGE PHASE EXTERNAL CREATED AT VERSION ocs-storagecluster 4d Ready 2023-06-27T15:23:01Z 4.11.0 -
Configure the multi-cloud gateway (MCG) namespace Azure bucket running on an OCP cluster in Azure:
Syntaxnoobaa namespacestore create azure-blob az --account-key='ACCOUNT_KEY' --account-name='ACCOUNT_NAME' --target-blob-container='AZURE_CONTAINER_NAME'Example[root@host01 ~]$ noobaa namespacestore create azure-blob az --account-key='iq3+6hRtt9bQ46QfHKQ0nSm2aP+tyMzdn8dBSRW4XWrFhY+1nwfqEj4hk2q66nmD85E/o5OrrUqo+AStkKwm9w==' --account-name='transitionrgw' --target-blob-container='mcgnamespace' -
Create an MCG bucket class pointing to the
namespacestore:Example[root@host01 ~]$ noobaa bucketclass create namespace-bucketclass single aznamespace-bucket-class --resource az -n openshift-storage -
Create an object bucket claim (OBC) for the transition to cloud:
Syntaxnoobaa obc create OBC_NAME --bucketclass aznamespace-bucket-class -n openshift-storageExample[root@host01 ~]$ noobaa obc create rgwobc --bucketclass aznamespace-bucket-class -n openshift-storageNote: Use the credentials provided by OBC to configure zonegroup placement on the Ceph Object Gateway. -
On the bootstrapped node, create a storage class with the tier type as
cloud-s3on the default placement within the default zonegroup on the previously configured MCG in Azure:Note: Once a storage class is created with the--tier-type=cloud-s3option , it cannot be later modified to any other storage class type.Syntaxradosgw-admin zonegroup placement add --rgw-zonegroup =ZONE_GROUP_NAME \ --placement-id=PLACEMENT_ID \ --storage-class =STORAGE_CLASS_NAME \ --tier-type=cloud-s3Example[ceph: root@host01 /]# radosgw-admin zonegroup placement add --rgw-zonegroup=default \ --placement-id=default-placement \ --storage-class=AZURE \ --tier-type=cloud-s3 [ { "key": "default-placement", "val": { "name": "default-placement", "tags": [], "storage_classes": [ "AZURE", "STANDARD" ], "tier_targets": [ { "key": "AZURE", "val": { "tier_type": "cloud-s3", "storage_class": "AZURE", "retain_head_object": "false", "s3": { "endpoint": "", "access_key": "", "secret": "", "host_style": "path", "target_storage_class": "", "target_path": "", "acl_mappings": [], "multipart_sync_threshold": 33554432, "multipart_min_part_size": 33554432 } } } ] } } ] -
Configure the cloud S3 cloud storage class:
Syntaxradosgw-admin zonegroup placement modify --rgw-zonegroup ZONE_GROUP_NAME \ --placement-id PLACEMENT_ID \ --storage-class STORAGE_CLASS_NAME \ --tier-config=endpoint=ENDPOINT_URL,\ access_key=ACCESS_KEY,secret=SECRET_KEY,\ target_path="TARGET_BUCKET_ON",\ multipart_sync_threshold=44432,\ multipart_min_part_size=44432,\ retain_head_object=true region=REGION_NAMEImportant: Setting theretain_head_objectparameter totrueretains the metadata or the head of the object to list the objects that are transitioned. - Example
[ceph: root@host01 /]# radosgw-admin zonegroup placement modify --rgw-zonegroup default --placement-id default-placement \ --storage-class AZURE \ --tier-config=endpoint="https://s3-openshift-storage.apps.ocp410.0e73azopenshift.com",\ access_key=a21e86bce636c3aa2,secret=cf764951f1fdde5f,\ target_path="dfqe-bucket-01",\ multipart_sync_threshold=44432,\ multipart_min_part_size=44432,\ retain_head_object=true region= us-east-1 [ { "key": "default-placement", "val": { "name": "default-placement", "tags": [], "storage_classes": [ "AZURE", "STANDARD", "cold.test", "hot.test" ], "tier_targets": [ { "key": "AZURE", "val": { "tier_type": "cloud-s3", "storage_class": "AZURE", "retain_head_object": "true", "s3": { "endpoint": "https://s3-openshift-storage.apps.ocp410.0e73azopenshift.com", "access_key": "a21e86bce636c3aa2", "secret": "cf764951f1fdde5f", "region": "", "host_style": "path", "target_storage_class": "", "target_path": "dfqe-bucket-01", "acl_mappings": [], "multipart_sync_threshold": 44432, "multipart_min_part_size": 44432 } } } ] } } ] -
Restart the Ceph Object Gateway:
Syntaxceph orch restart CEPH_OBJECT_GATEWAY_SERVICE_NAMEExample[ceph: root@host 01 /]# ceph orch restart client.rgw.objectgwhttps.host02.udyllp Scheduled to restart client.rgw.objectgwhttps.host02.udyllp on host 'host02 Create the lifecycle configuration transition policy for the bucket created previously. In this example, the bucket is
transition:Syntaxcat transition.json { "Rules": [ { "Filter": { "Prefix": "" }, "Status": "Enabled", "Transitions": [ { "Days": 30, "StorageClass": "STORAGE_CLASS" } ], "ID": "TRANSITION_ID" } ] }Note: All the objects in the bucket older than 30 days are transferred to the cloud storage class calledExampleAZURE.[root@host01 ~]$ cat transition.json { "Rules": [ { "Filter": { "Prefix": "" }, "Status": "Enabled", "Transitions": [ { "Days": 30, "StorageClass": "AZURE" } ], "ID": "Transition Objects in bucket to AZURE Blob after 30 days" } ] }-
Apply the bucket lifecycle configuration using AWS CLI:
Syntaxaws s3api --ca-bundle CA_PERMISSION --profile rgw --endpoint ENDPOINT_URL --region default put-bucket-lifecycle-configuration --lifecycle-configuration file://BUCKET.json --bucket BUCKET_NAMEExample[root@host01 ~]$ aws s3api --ca-bundle /etc/pki/ca-trust/source/anchors/myCA.pem --profile rgw --endpoint https://host02.example.com:8043 --region default put-bucket-lifecycle-configuration --lifecycle-configuration file://transition.json --bucket transition -
Optional: Get the lifecycle configuration:
Syntaxaws s3api --ca-bundle CA_PERMISSION --profile rgw --endpoint ENDPOINT_URL--region default get-bucket-lifecycle-configuration --lifecycle-configuration file://BUCKET.json --bucket BUCKET_NAMEExample[root@host01 ~]$ aws s3api --ca-bundle /etc/pki/ca-trust/source/anchors/myCA.pem --profile rgw --endpoint https://host02.example.com:8043 --region default get-bucket-lifecycle-configuration --bucket transition { "Rules": [ { "ID": "Transition Objects in bucket to AZURE Blob after 30 days", "Prefix": "", "Status": "Enabled", "Transitions": [ { "Days": 30, "StorageClass": "AZURE" } ] } ] } -
Optional: Get the lifecycle configuration with the radosgw-admin lc list command:
[root@host 01 ~]# radosgw-admin lc list [ { "bucket": ":transition:d9c4f708-5598-4c44-9d36-849552a08c4d.169377.1", "started": "Thu, 01 Jan 1970 00:00:00 GMT", "status": "UNINITIAL" } ]Note: TheUNINITALstatus implies that the lifecycle configuration is not processed. It moves toCOMPLETEDstate after the transition process is complete. -
Log in to
cephadm shell:[root@host 01 ~]# cephadm shell -
Restart the Ceph Object Gateway daemon:
Syntaxceph orch daemon CEPH_OBJECT_GATEWAY_DAEMON_NAMEExample[ceph: root@host 01 /]# ceph orch daemon restart rgw.objectgwhttps.host02.udyllp [ceph: root@host 01 /]# ceph orch daemon restart rgw.objectgw.host02.afwvyq [ceph: root@host 01 /]# ceph orch daemon restart rgw.objectgw.host05.ucpsrr -
Migrate data from the source cluster to Azure:
Example[root@host 01 ~]# for i in 1 2 3 4 5 do aws s3 --ca-bundle /etc/pki/ca-trust/source/anchors/myCA.pem --profile rgw --endpoint https://host02.example.com:8043 --region default cp /etc/hosts s3://transition/transition$i done -
Verify transition of data:
Example[root@host 01 ~]# aws s3 --ca-bundle /etc/pki/ca-trust/source/anchors/myCA.pem --profile rgw --endpoint https://host02.example.com:8043 --region default ls s3://transition 2023-06-30 10:24:01 3847 transition1 2023-06-30 10:24:04 3847 transition2 2023-06-30 10:24:07 3847 transition3 2023-06-30 10:24:09 3847 transition4 2023-06-30 10:24:13 3847 transition5 -
Verify if the data has moved to Azure with
rados lscommand:Example[root@host 01 ~]# rados ls -p default.rgw.buckets.data | grep transition d9c4f708-5598-4c44-9d36-849552a08c4d.169377.1_transition1 d9c4f708-5598-4c44-9d36-849552a08c4d.169377.1_transition4 d9c4f708-5598-4c44-9d36-849552a08c4d.169377.1_transition2 d9c4f708-5598-4c44-9d36-849552a08c4d.169377.1_transition3 d9c4f708-5598-4c44-9d36-849552a08c4d.169377.1_transition5 -
If the data is not transitioned, you can run the
lc processcommand:Example[root@host 01 ~]# radosgw-admin lc processThis will force the lifecycle process to start and evaluates all the bucket lifecycle policies configured. It then starts the transition of data wherever needed.
Verification
-
Run the
radosgw-admin lc listcommand to verify the completion of the transition:Example[root@host 01 ~]# radosgw-admin lc list [ { "bucket": ":transition:d9c4f708-5598-4c44-9d36-849552a08c4d.170017.5", "started": "Mon, 30 Jun 2023-06-30 16:52:56 GMT", "status": "COMPLETE" } ] -
List the objects in the bucket:
Example[root@host01 ~]$ aws s3api list-objects --bucket awstestbucket --endpoint=http://10.0.209.002:8080 { "Contents": [ { "Key": "awstestbucket/test", "LastModified": "2023-06-25T16:14:23.118Z", "ETag": "\"378c905939cc4459d249662dfae9fd6f\"", "Size": 29, "StorageClass": "STANDARD", "Owner": { "DisplayName": "test-user", "ID": "test-user" } } ] } -
List the objects on the cluster:
Example[root@host01 ~]$ aws s3 --ca-bundle /etc/pki/ca-trust/source/anchors/myCA.pem --profile rgw --endpoint https://host02.example.com:8043 --region default ls s3://transition 2023-06-30 17:52:56 0 transition1 2023-06-30 17:51:59 0 transition2 2023-06-30 17:51:59 0 transition3 2023-06-30 17:51:58 0 transition4 2023-06-30 17:51:59 0 transition5The objects are
0in size. You can list the objects, but cannot copy them since they are transitioned to Azure. -
Check the head of the object using the S3 API:
Example[root@host01 ~]$ aws s3api --ca-bundle /etc/pki/ca-trust/source/anchors/myCA.pem --profile rgw --endpoint https://host02.example.com:8043 --region default head-object --key transition1 --bucket transition { "AcceptRanges": "bytes", "LastModified": "2023-06-31T16:52:56+00:00", "ContentLength": 0, "ETag": "\"46ecb42fd0def0e42f85922d62d06766\"", "ContentType": "binary/octet-stream", "Metadata": {}, "StorageClass": "CLOUDTIER" }You can see that the storage class has changed from
STANDARDtoCLOUDTIER.