S3 多租户

租户命令

师成师成· 更新于 2026-09-28· 阅读 21 分钟· 0 次阅读

登录后可跨设备保存划线和私人笔记登录

如需从更高层面了解多租户架构,请参阅多租户概述。

所有多租户子命令都位于 CLI 的 ozone tenant 之下。

以下命令均假设 Ozone 集群启用了 Kerberos 并安装了 Ranger。为 S3 Gateway 启用 HTTPS 是可选的,但建议启用。

租户命令成功时的退出码应为 0。非零退出码表示失败,此时应伴随一条错误信息。

如果 OzoneManager 运行在 HA 模式下,请在相应命令后追加 --om-service-id= 参数。

创建租户

在当前 Ozone 集群中创建一个新租户。此操作需要 Ozone 集群管理员权限。

除了新增 OM 数据库条目之外,创建租户还会在后台执行以下操作:

  1. 创建一个名称完全相同的卷。因此,卷名的限制同样适用于租户名。目前尚不支持在创建租户时指定自定义卷名。租户创建后,其卷名不可更改。
  2. 创建两个新的 Ranger 角色:tenantName-UserRole 和 tenantName-AdminRole。
  3. 创建新的 Ranger 策略,默认允许所有租户用户在租户卷下列出和创建存储桶,但只有存储桶所有者和租户管理员才能访问存储桶内容。
ozone tenant [--verbose] create <TENANT_NAME>

示例:

bash-4.2$ kinit -kt /etc/security/keytabs/om.keytab om/om@EXAMPLE.COM
bash-4.2$ ozone tenant create tenantone
2022-02-16 00:00:00,000 [main] INFO rpc.RpcClient: Creating Tenant: 'tenantone', with new volume: 'tenantone'

详细输出示例:

bash-4.2$ ozone tenant --verbose create tenantone
2022-02-16 00:00:00,000 [main] INFO rpc.RpcClient: Creating Tenant: 'tenantone', with new volume: 'tenantone'
{
  "tenantId": "tenantone"
}

列出租户

列出 Ozone 集群中的所有租户。可选使用 --json 以 JSON 格式打印详细结果。

ozone tenant list [--json]

示例:

bash-4.2$ ozone tenant list
tenantone
bash-4.2$ ozone tenant list --json
[
  {
    "tenantId": "tenantone",
    "bucketNamespaceName": "tenantone",
    "userRoleName": "tenantone-UserRole",
    "adminRoleName": "tenantone-AdminRole",
    "bucketNamespacePolicyName": "tenantone-VolumeAccess",
    "bucketPolicyName": "tenantone-BucketAccess"
  }
]

将用户分配给租户

租户中的第一个用户必须由 Ozone 集群管理员来分配。

默认情况下,当用户 testuser 被分配给租户 tenantone 时,该用户在此租户中生成的访问 ID 为 tenantone$testuser。

  • 在 Bash 中使用访问 ID 时,请务必用单引号将其括起来,以防止它被展开为环境变量。

一个用户可以被分配给多个租户。

ozone tenant [--verbose] user assign <USER_NAME> --tenant=<TENANT_NAME>

<USER_NAME> 应为 Kerberos 主体的简短用户名,例如当 Kerberos 主体为 testuser/scm@EXAMPLE.COM 时,可使用 testuser。

示例:

bash-4.2$ ozone tenant user assign testuser --tenant=tenantone
export AWS_ACCESS_KEY_ID='tenantone$testuser'
export AWS_SECRET_ACCESS_KEY='<GENERATED_SECRET>'

bash-4.2$ ozone tenant user assign testuser --tenant=tenantone
TENANT_USER_ACCESS_ID_ALREADY_EXISTS accessId 'tenantone$testuser' already exists!
bash-4.2$ ozone tenant --verbose user assign testuser2 --tenant=tenantone
export AWS_ACCESS_KEY_ID='tenantone$testuser2'
export AWS_SECRET_ACCESS_KEY='<GENERATED_SECRET>'
Assigned 'testuser2' to 'tenantone' with accessId 'tenantone$testuser2'.

将用户指定为租户管理员

租户中的第一个用户必须由 Ozone 集群管理员指定。

受委托的租户管理员和非受委托的租户管理员都可以指定和撤销普通租户用户。

受委托租户管理员与非受委托租户管理员唯一的区别在于:受委托租户管理员可以在租户中指定和撤销租户管理员,而非受委托租户管理员不能。

默认情况下,ozone tenant assignadmin 指定的是非受委托租户管理员。若要指定受委托租户管理员,请指定 --delegated 或 -d。

可以将一个用户指定为多个租户的租户管理员。需要提醒的是,该用户在每个租户下将拥有不同的访问 ID。

ozone tenant user assignadmin <ACCESS_ID> [-d|--delegated] --tenant=<TENANT_NAME>

示例:

bash-4.2$ ozone tenant user assignadmin 'tenantone$testuser' --tenant=tenantone

默认情况下,命令成功时以 0 退出,且不输出任何内容。使用 --verbose 可以以 JSON 格式打印结果。

bash-4.2$ ozone tenant --verbose user assignadmin 'tenantone$testuser' --tenant=tenantone
{
  "accessId": "tenantone$testuser",
  "tenantId": "tenantone",
  "isAdmin": true,
  "isDelegatedAdmin": true
}

一旦 testuser 成为 tenantone 的租户管理员,就可以以 testuser 身份执行 kinit,并为该租户分配新用户,甚至分配新的租户管理员(如果已获授权)。以下命令仅作示例说明:

kinit -kt /etc/security/keytabs/testuser.keytab testuser/scm@EXAMPLE.COM
ozone tenant user assign testuser2 --tenant=tenantone
ozone tenant user assignadmin 'tenantone$testuser2' --tenant=tenantone

列出租户中的用户

ozone tenant user list [--json] <TENANT_NAME>

示例:

bash-4.2$ ozone tenant user list tenantone
- User 'testuser' with accessId 'tenantone$testuser'
- User 'testuser2' with accessId 'tenantone$testuser2'
bash-4.2$ ozone tenant user list --json tenantone
[
  {
    "user": "testuser",
    "accessId": "tenantone$testuser"
  },
  {
    "user": "testuser2",
    "accessId": "tenantone$testuser2"
  }
]

获取租户用户信息

此命令会列出用户被分配到的所有租户。

ozone tenant user info [--json] <USER_NAME>

示例:

bash-4.2$ ozone tenant user info testuser
User 'testuser' is assigned to:
- Tenant 'tenantone' delegated admin with accessId 'tenantone$testuser'
bash-4.2$ ozone tenant user info --json testuser
{
  "user": "testuser",
  "tenants": [
    {
      "accessId": "tenantone$testuser",
      "tenantId": "tenantone",
      "isAdmin": true,
      "isDelegatedAdmin": true
    }
  ]
}

获取租户用户密钥

根据租户用户访问 ID 获取密钥。

与 ozone s3 getsecret 不同,如果访问 ID 不存在,该命令不会生成密钥。

ozone tenant user get-secret <ACCESS_ID>

或

ozone tenant user getsecret <ACCESS_ID>

示例:

bash-4.2$ ozone tenant user get-secret 'tenantone$testuser'
export AWS_ACCESS_KEY_ID='tenantone$testuser'
export AWS_SECRET_ACCESS_KEY='<GENERATED_SECRET>'

设置租户用户密钥

为租户用户访问 ID 设置密钥。

密钥长度应至少为 8 个字符。

ozone tenant user set-secret <ACCESS_ID> --secret <SECRET_KEY>

或

ozone tenant user setsecret <ACCESS_ID> --secret <SECRET_KEY>

示例:

bash-4.2$ ozone tenant user set-secret 'tenantone$testuser' --secret 'NEW_SECRET'
export AWS_ACCESS_KEY_ID='tenantone$testuser'
export AWS_SECRET_ACCESS_KEY='NEW_SECRET'

撤销租户管理员

ozone tenant [--verbose] user revokeadmin <ACCESS_ID>

示例:

bash-4.2$ ozone tenant user revokeadmin 'tenantone$testuser'
bash-4.2$ ozone tenant --verbose user revokeadmin 'tenantone$testuser'
{
  "accessId": "tenantone$testuser",
  "isAdmin": false,
  "isDelegatedAdmin": false
}

撤销用户对租户的访问权限

ozone tenant [--verbose] user revoke <ACCESS_ID>

示例:

bash-4.2$ ozone tenant user revoke 'tenantone$testuser'

使用详细输出:

bash-4.2$ ozone tenant --verbose user revoke 'tenantone$testuser'
Revoked accessId 'tenantone$testuser'.

删除租户

要能够删除租户,该租户必须为空,即在删除租户之前需要先撤销所有用户。否则 OM 会抛出 TENANT_NOT_EMPTY 异常并拒绝删除该租户。

请注意,按照设计意图,租户创建期间创建并与该租户关联的卷不会被删除。如有必要,管理员需按照 CLI 中的提示手动删除该卷。

此外,使用详细输出选项还会以 JSON 格式打印 Ozone Manager 的原始响应。

ozone tenant [--verbose] delete <TENANT_NAME>

示例:

bash-4.2$ ozone tenant delete tenantone
Deleted tenant 'tenantone'.
But the associated volume 'tenantone' is not removed. To delete it, run
    ozone sh volume delete tenantone

详细输出:

bash-4.2$ ozone tenant --verbose delete tenantone
Deleted tenant 'tenantone'.
But the associated volume 'tenantone' is not removed. To delete it, run
    ozone sh volume delete tenantone

{
  "tenantId": "tenantone",
  "volumeName": "tenantone",
  "volumeRefCount": 0
}

如果 Ozone 集群管理员(或 Ranger 中拥有删除卷权限的任何人)在租户删除之前尝试使用上述命令删除卷,则 ozone sh volume delete 命令会失败,因为该卷的引用计数不为零:

bash-4.2$ ozone sh volume delete tenantone
VOLUME_IS_REFERENCED Volume reference count is not zero (1). Ozone features are enabled on this volume. Try `ozone tenant delete <tenantId>` first.

创建存储桶链接

存储桶链接可用于允许访问租户卷之外的存储桶。

存储桶(符号)链接是一种特殊的存储桶,它指向同一 Ozone 集群中的其他存储桶,类似于 POSIX 符号链接。

创建存储桶链接的示例:

ozone tenant linkbucket /vol1/bucket1 /tenantone/linked-bucket1

上述命令在卷 tenantone 中创建了一个存储桶符号链接 linked-bucket1,它指向 vol1 中的 bucket1。

只要运行该命令的用户拥有在目标卷 tenantone 中创建存储桶的权限,命令就会成功。

  • link bucket 命令本身不会检查是否具有访问源卷和源存储桶的权限。

  • link bucket 命令甚至不会检查源卷和源存储桶是否存在。

  • 权限检查将在实际访问该存储桶符号链接时执行。

    • 若要授予租户 tenantone 中的某个用户访问该存储桶的权限,需要由 Ranger 管理员添加一条新的策略,允许该用户对卷 vol1 中的源存储桶 bucket1 拥有预期的权限(READ、WRITE、LIST、CREATE、DELETE 等)。
  • 目前,ozone tenant linkbucket 命令等同于 ozone sh bucket link 命令。更多详情请参阅存储桶链接文档。

示例:通过 S3 网关访问存储桶

以下示例演示了在已创建租户 tenantone 并将 testuser 分配给该租户的情况下,使用 AWS CLI 访问该存储桶的方法。

配置 AWS CLI

bash-4.2$ aws configure
AWS Access Key ID [****************fslf]: tenantone$testuser
AWS Secret Access Key [****************fslf]: <GENERATED_SECRET>
Default region name [us-west-1]:
Default output format [None]:

列出存储桶、创建存储桶

bash-4.2$ aws s3api --endpoint-url http://s3g:9878 list-buckets
{
    "Buckets": []
}
bash-4.2$ aws s3api --endpoint-url http://s3g:9878 create-bucket --bucket bucket-test1
{
    "Location": "http://s3g:9878/bucket-test1"
}
bash-4.2$ aws s3api --endpoint-url http://s3g:9878 list-buckets
{
    "Buckets": [
        {
            "Name": "bucket-test1",
            "CreationDate": "2022-02-16T00:05:00.000Z"
        }
    ]
}

使用 aws s3api 创建的存储桶在 Ozone CLI 中同样可见:

bash-4.2$ ozone sh bucket list /tenantone
[ {
  "metadata" : { },
  "volumeName" : "tenantone",
  "name" : "bucket-test1",
  "storageType" : "DISK",
  "versioning" : false,
  "usedBytes" : 0,
  "usedNamespace" : 0,
  "creationTime" : "2022-02-16T00:05:00.000Z",
  "modificationTime" : "2022-02-16T00:05:00.000Z",
  "quotaInBytes" : -1,
  "quotaInNamespace" : -1,
  "bucketLayout" : "OBJECT_STORE",
  "owner" : "root",
  "link" : false
} ]

将对象(键)放入存储桶并列出对象

bash-4.2$ aws s3api --endpoint-url http://s3g:9878 put-object --bucket bucket-test1 --key file1 --body README.md
bash-4.2$ aws s3api --endpoint-url http://s3g:9878 list-objects --bucket bucket-test1
{
    "Contents": [
        {
            "Key": "file1",
            "LastModified": "2022-02-16T00:10:00.000Z",
            "ETag": "e99f93dedfe22e9a133dc3c634f14634",
            "Size": 3811,
            "StorageClass": "STANDARD"
        }
    ]
}

从存储桶中获取对象(键)

bash-4.2$ aws s3api --endpoint-url http://s3g:9878 get-object --bucket bucket-test1 --key file1 file1-get.txt
{
    "AcceptRanges": "bytes",
    "LastModified": "Wed, 16 Feb 2022 00:10:00 GMT",
    "ContentLength": 3811,
    "CacheControl": "no-cache",
    "ContentType": "application/octet-stream",
    "Expires": "Wed, 16 Feb 2022 00:15:00 GMT",
    "Metadata": {}
}
bash-4.2$ diff file1-get.txt README.md

评论

登录后参与评论

正在加载评论…