玩命加载中 . . .

ceph S3 多租户


什么是multi-tenancy

在J版之前,同一个ceph集群中不允许有同名的bucket和S3账号的存在,从J版本开始,引入multi-tenancy功能,使得不同tenant(租户)下的账号和bucket可以同名,为了兼容J之前的版本,提供了一名为空的“legacy” 租户,如果没有指定tenant,则从这个“legacy” tenant去获取账号/bucket信息。

查看默认tenant中S3账号信息

root@node76:/var/log/ezcloudstor# radosgw-admin metadata list user
[
    "admin",
    "user01"
]

上述信息中,有两个S3账号,admin账号先忽略,此账号为超级管理员, user01为我创建的一个普通S3账号,此账号信息如下:

root@node76:/var/log/ezcloudstor# radosgw-admin user info --uid=user01
{
    "user_id": "user01",
    "display_name": "user01",
    "email": "user01@126.com",
    "suspended": 0,
    "max_buckets": 1000,
    "auid": 0,
    "subusers": [
        {
            "id": "user01:user01",
            "permissions": "full-control"
        }
    ],
    "keys": [
        {
            "user": "user01",
            "access_key": "U3SNDWWAJRSTQU2YZAMG",
            "secret_key": "5l1fg5VgsWo1z9fCd2IvCdrTwGi1asHBqb4b6DTQ"
        }
    ],
    "swift_keys": [
        {
            "user": "user01",
            "secret_key": "1"
        },
        {
            "user": "user01:user01",
            "secret_key": "1"
        }
    ],
    "caps": [],
    "op_mask": "read, write, delete",
    "default_placement": "",
    "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",
    "bigtera_roles": {
        "cluster_admin": false,
        "deleting": false,
        "migrated": false,
        "s3_admin": false,
        "sds_admin": false,
        "sns": false,
        "sqs": false
    }
}

root@node76:/var/log/ezcloudstor# 

直接指定tenant为空,再次查询一下这个S3账号

root@node76:~# radosgw-admin user info --uid=user01 --tenant=''
{
    "user_id": "user01",
    "display_name": "user01",
    "email": "user01@126.com",
    "suspended": 0,
    "max_buckets": 1000,
    "auid": 0,
    "subusers": [
        {
            "id": "user01:user01",
            "permissions": "full-control"
        }
    ],
    "keys": [
        {
            "user": "user01",
            "access_key": "U3SNDWWAJRSTQU2YZAMG",
            "secret_key": "5l1fg5VgsWo1z9fCd2IvCdrTwGi1asHBqb4b6DTQ"
        }
    ],
    "swift_keys": [
        {
            "user": "user01",
            "secret_key": "1"
        },
        {
            "user": "user01:user01",
            "secret_key": "1"
        }
    ],
    "caps": [],
    "op_mask": "read, write, delete",
    "default_placement": "",
    "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",
    "bigtera_roles": {
        "cluster_admin": false,
        "deleting": false,
        "migrated": false,
        "s3_admin": false,
        "sds_admin": false,
        "sns": false,
        "sqs": false
    }
}

可以确认一点,当不携带tenant或者指定的tenant为空时,从一个为空的tenant中获取S3账号信息,ceph只所以这么做,是为了兼容J之前的版本。

创建不同租户下的相同账号

这里会预先创建两个租户下的同名账号,tenant1下的user01,和tenant2下的user01

radosgw-admin user create --tenant tenant1 --uid user01 --display-name "tenant1_user01"
radosgw-admin user create --tenant tenant2 --uid user01 --display-name "tenant2_user01"
root@node76:~# radosgw-admin user list
[
    "admin",
    "tenant1$user01",
    "tenant2$user01",
    "user01"
]
root@node76:~# 

这里可以看到两个账号,“tenant1$user01” 和 “tenant2$user01”,以符号“$”间隔开,用户名相同,只是属于不同的租户(tenant),不相互冲突。

通过user info,指定tenant,获取到这两个账号的access key 和 secret key,示例如下:

root@node76:~# radosgw-admin --uid=user01 user info --tenant tenant1
{
    "user_id": "tenant1$user01",
    "display_name": "tenant1_user01",
    "email": "",
    "suspended": 0,
    "max_buckets": 1000,
    "auid": 0,
    "subusers": [],
    "keys": [
        {
            "user": "tenant1$user01",
            "access_key": "SSCBPW100ED03TI0MU51",
            "secret_key": "Tnnjsw7e8A7Gu4qblQlHaka4uoOq5rVVR2cDEfOz"
        }
    ],
    "swift_keys": [],
    "caps": [],
    "op_mask": "read, write, delete",
    "default_placement": "",
    "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",
    "bigtera_roles": {
        "cluster_admin": false,
        "deleting": false,
        "migrated": false,
        "s3_admin": false,
        "sds_admin": false,
        "sns": false,
        "sqs": false
    }
}

root@node76:~# 

对象上传

分别给这两个租户下的同名账号创建相同的bucket,以及上传对象。

node75上,使用tenant1的user01账号;node76上,使用tenant2的user01账号分别创建同名的bucket,以及上传对象到bucket中:

root@node75:~# cat .s3cfg | grep _key | grep -v kms
access_key = SSCBPW100ED03TI0MU51
secret_key = Tnnjsw7e8A7Gu4qblQlHaka4uoOq5rVVR2cDEfOz
root@node76:~# cat .s3cfg | grep _key | grep -v kms
access_key = 22XOFAUIPFR11C45483R
secret_key = vN5C1bNMcBbprfPm0v3ozKQ4rvvgsZeLuNRoVJ9B
root@node76:~# 

尝试创建同名bucket:

root@node75:~# s3cmd mb s3://tenant-bucket01
Bucket 's3://tenant-bucket01/' created
root@node75:~# 
root@node76:~# s3cmd mb s3://tenant-bucket01
Bucket 's3://tenant-bucket01/' created
root@node76:~# 
root@node76:~# radosgw-admin bucket list
[
    "tenant1/tenant-bucket01",
    "tenant2/tenant-bucket01",
    "bigtera-admin-log-target-bucket"
]
root@node76:~#

这里并不需要指定tenant,因为rgw是以key去区分用户数据使用哪一个tenant的,至此,同名的bucket创建成功,可以看到,bucket是以符号"/"间隔开。

开始上传对象到这两个bucket中,分别上传不同的对象:

root@node75:~# s3cmd put tenant1.png s3://tenant-bucket01
upload: 'tenant1.png' -> 's3://tenant-bucket01/tenant1.png'  [1 of 1]
 8 of 8   100% in    0s   610.87 B/s  done
root@node75:~#
root@node76:~# s3cmd put tenant2.png s3://tenant-bucket01
upload: 'tenant2.png' -> 's3://tenant-bucket01/tenant2.png'  [1 of 1]
 27 of 27   100% in    0s  2019.45 B/s  done
root@node76:~#

查看对象上传效果:

root@node75:~# s3cmd ls s3://tenant-bucket01
2020-06-16 06:58         8   s3://tenant-bucket01/tenant1.png
root@node75:~#
root@node76:~# s3cmd ls s3://tenant-bucket01/
2020-06-16 07:03        27   s3://tenant-bucket01/tenant2.png
root@node76:~#

总结

本文所示的多租户,解决了如下问题:

  • 实现同集群中创建同名bucket和S3账号,即实现租户的数据隔离。

而实际应用要远比本文所示要复杂的多,比如不同tenant之间不同bucket下的数据共享,这就涉及到RGW bucket policy 设置问题了。


文章作者: Gavin Wang
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Gavin Wang !
  目录