RGW Multi-tenancy

New in version Jewel.

The multi-tenancy feature allows to use buckets and users of the samename simultaneously by segregating them under so-called tenants.This may be useful, for instance, to permit users of Swift API tocreate buckets with easily conflicting names such as “test” or “trove”.

From the Jewel release onward, each user and bucket lies under a tenant.For compatibility, a “legacy” tenant with an empty name is provided.Whenever a bucket is referred without an explicit tenant, an implicittenant is used, taken from the user performing the operation. Sincethe pre-existing users are under the legacy tenant, they continueto create and access buckets as before. The layout of objects in RADOSis extended in a compatible way, ensuring a smooth upgrade to Jewel.

Administering Users With Explicit Tenants

Tenants as such do not have any operations on them. They appear anddisappear as needed, when users are administered. In order to create,modify, and remove users with explicit tenants, either an additionaloption –tenant is supplied, or a syntax “<tenant>$<user>” is usedin the parameters of the radosgw-admin command.

Examples

Create a user testx$tester to be accessed with S3:

  1. # radosgw-admin --tenant testx --uid tester --display-name "Test User" --access_key TESTER --secret test123 user create

Create a user testx$tester to be accessed with Swift:

  1. # radosgw-admin --tenant testx --uid tester --display-name "Test User" --subuser tester:test --key-type swift --access full user create
  2. # radosgw-admin --subuser 'testx$tester:test' --key-type swift --secret test123

Note

The subuser with explicit tenant has to be quoted in the shell.

Tenant names may contain only alphanumeric characters and underscores.

Accessing Buckets with Explicit Tenants

When a client application accesses buckets, it always operates withcredentials of a particular user. As mentioned above, every user belongsto a tenant. Therefore, every operation has an implicit tenant in itscontext, to be used if no tenant is specified explicitly. Thus a completecompatibility is maintained with previous releases, as long as thereferred buckets and referring user belong to the same tenant.In other words, anything unusual occurs when accessing another tenant’sbuckets only.

Extensions employed to specify an explicit tenant differ accordingto the protocol and authentication system used.

S3

In case of S3, a colon character is used to separate tenant and bucket.Thus a sample URL would be:

  1. https://ep.host.dom/tenant:bucket

Here’s a simple Python sample:

  1. 1234567
  1. from boto.s3.connection import S3Connection, OrdinaryCallingFormat c = S3Connection( aws_access_key_id="TESTER", aws_secret_access_key="test123", host="ep.host.dom", calling_format = OrdinaryCallingFormat()) bucket = c.get_bucket("test5b:testbucket")

Note that it’s not possible to supply an explicit tenant usinga hostname. Hostnames cannot contain colons, or any other separatorsthat are not already valid in bucket names. Using a period creates anambiguous syntax. Therefore, the bucket-in-URL-path format has to beused.

Due to the fact that the native S3 API does not deal withmulti-tenancy and radosgw’s implementation does, things get a bitinvolved when dealing with signed URLs and public read ACLs.

  • A signed URL does contain the AWSAccessKeyId queryparameters, from which radosgw is able to discern the correct userand tenant owning the bucket. In other words, an applicationgenerating signed URLs should be able to take just the un-prefixedbucket name, and produce a signed URL that itself contains thebucket name without the tenant prefix. However, it is possible toinclude the prefix if you so choose.

Thus, accessing a signed URL of an object bar in a containerfoo belonging to the tenant 7188e165c0ae4424ac68ae2e89a05c50would be possible either viahttp://<host>:<port>/foo/bar?AWSAccessKeyId=b200fb6634c547199e436a0f93c0c46e&Expires=1542890806&Signature=eok6CYQC%2FDwmQQmqvY5jTg6ehXU%3D,or viahttp://<host>:<port>/7188e165c0ae4424ac68ae2e89a05c50:foo/bar?AWSAccessKeyId=b200fb6634c547199e436a0f93c0c46e&Expires=1542890806&Signature=eok6CYQC%2FDwmQQmqvY5jTg6ehXU%3D,depending on whether or not the tenant prefix was passed in onsignature generation.

  • A bucket with a public read ACL is meant to be read by an HTTPclient without including any query parameters that would allowradosgw to discern tenants. Thus, publicly readable objects mustalways be accessed using the bucket name with the tenant prefix.

Thus, if you set a public read ACL on an object bar in acontainer foo belonging to the tenant7188e165c0ae4424ac68ae2e89a05c50, you would need to access thatobject via the public URLhttp://<host>:<port>/7188e165c0ae4424ac68ae2e89a05c50:foo/bar.

Swift with built-in authenticator

TBD – not in test_multen.py yet

Swift with Keystone

In the default configuration, although native Swift has inherentmulti-tenancy, radosgw does not enable multi-tenancy for the SwiftAPI. This is to ensure that a setup with legacy buckets — that is,buckets that were created before radosgw supported multitenancy —,those buckets retain their dual-API capability to be queried andmodified using either S3 or Swift.

If you want to enable multitenancy for Swift, particularly if yourusers only ever authenticate against OpenStack Keystone, you shouldenable Keystone-based multitenancy with the following ceph.confconfiguration option:

  1. rgw keystone implicit tenants = true

Once you enable this option, any newly connecting user (whether theyare using the Swift API, or Keystone-authenticated S3) will promptradosgw to create a user named <tenant_id>$<tenant_id, where<tenant_id> is a Keystone tenant (project) UUID — for example,7188e165c0ae4424ac68ae2e89a05c50$7188e165c0ae4424ac68ae2e89a05c50.

Whenever that user then creates an Swift container, radosgw internallytranslates the given container name into<tenant_id>/<container_name>, such as7188e165c0ae4424ac68ae2e89a05c50/foo. This ensures that if thereare two or more different tenants all creating a container namedfoo, radosgw is able to transparently discern them by their tenantprefix.

It is also possible to limit the effects of implicit tenantsto only apply to swift or s3, by setting rgw keystone implicit tenantsto either s3 or swift. This will likely primarilybe of use to users who had previously used implicit tenantswith older versions of ceph, where implicit tenantsonly applied to the swift protocol.

Notes and known issues

Just to be clear, it is not possible to create buckets in othertenants at present. The owner of newly created bucket is extractedfrom authentication information.