Skip to content

Create Your First Tenant

A tenant cluster cannot exist on its own. Three objects come first, in order:

Layer Object What it establishes
Tenant Capsule Tenant Who the tenant is, and which identity owns their namespaces.
Environment Namespace, adopted by the Tenant Where their workloads live. A Tenant is a collector of Environments.
Network VpcClaim + SubnetClaim The VPC and subnet the Environment's clusters attach to.

Only then does a Cluster have a namespace to be created in and a subnet to attach to.

This page covers the first of the three: the Tenant. It creates a tenant called dynamo. Run it as a platform administrator on the under cluster.

Create the tenant identity

The Tenant's owner is an identity that already exists on the under cluster. Start with a ServiceAccount:

# The namespace holding the ServiceAccounts that own Tenants. kMetal does not
# create it — the name is a convention, and yours to choose.
apiVersion: v1
kind: Namespace
metadata:
  name: kmetal-tenants
---
# The ServiceAccount required for multi-tenancy
apiVersion: v1
kind: ServiceAccount
metadata:
  name: dynamo
  namespace: kmetal-tenants

Capsule has to have been told about this identity

Capsule enforces tenancy only for subjects named in spec.multiTenancy.users on the KMetal object, and kMetal names none for you. A Tenant whose owner is missing from that list is accepted and then ignored: the owner's namespaces are created outside every tenant, with no quota and no constraint applied, and nothing reports it.

ServiceAccounts are matched through the group covering their namespace, so one entry covers every tenant identity created here:

spec:
  multiTenancy:
    users:
      - kind: Group
        name: system:serviceaccounts:kmetal-tenants

Install kMetal sets this in the values overlay. If you skipped it, add it now — kubectl edit km kmetal — before creating the Tenant.

Onboard the Tenant

Once the identity has been declared, create the Tenant naming that ServiceAccount as its owner:

# The tenant definition
apiVersion: capsule.clastix.io/v1beta2
kind: Tenant
metadata:
  name: dynamo
spec:
  owners:
    - kind: ServiceAccount
      name: system:serviceaccount:kmetal-tenants:dynamo

The owner is referenced by its full identity string — for a ServiceAccount that is system:serviceaccount:<namespace>:<name>, which is what the API server presents it as.

Other owner kinds

Group and User owners are supported too, and are usually the right choice once tenants map to an identity provider rather than to in-cluster ServiceAccount resources. Each of those needs its own entry in spec.multiTenancy.users — see Make Capsule aware of the owner.

Quotas are deferred

A Tenant can also carry spec.resourceQuotas, which is how tenant-wide limits (storage, network, VMs, etc.) are enforced across every Environment it owns. Enforcing quotas with multi-tenancy is covered separately; a Tenant without them is valid.

Apply them and confirm the Tenant is active:

$ kubectl get tenant dynamo
NAME     STATE    NAMESPACE QUOTA   NAMESPACE COUNT   NODE SELECTOR   READY   STATUS       AGE
dynamo   Active                     0                                 True    reconciled   28h

Next Steps

The Tenant owns no namespaces yet, so there is nowhere for a workload to live. Give it one — Create First Environment.