Skip to content

Resource pools and quotas

Every tenant on Kestrel has exactly one Capsule ResourcePool. The pool is cluster-scoped and shared across every namespace the tenant owns — it is provisioned at the standard tier by default. A label selector (capsule.clastix.io/tenant: <your-tenant>) matches every namespace the tenant owns, so each new namespace you create automatically draws from the same pool.

Splitting work across namespaces does not split the quota. A Job running in <your-tenant>-experiments and a Deployment running in <your-tenant>-prod both pull from the same pool — the second namespace gives you scoping, naming, and RBAC separation, not resource isolation.

This is organization-neutral by design. Namespaces on Kestrel are for logical separation — permissions, network policy scope, ownership boundaries — not for quota isolation. If you want a ceiling per namespace, you enforce it yourself on top of the shared pool.

Each namespace also ships with a LimitRange that fills in defaults for containers that do not set their own values: a default limit of 1 CPU / 1Gi memory and a default request of 100m CPU / 128Mi memory. Setting explicit requests / limits on your Pods overrides these defaults — relying on them is convenient for quick tests but leaves the scheduler guessing for real workloads.

Every tenant is provisioned at one of four tiers. limits is the ceiling your workloads cannot exceed; requests is the floor the scheduler reserves for you; storage requests is the sum of PersistentVolumeClaim size across the whole tenant.

TierCPU limitsMemory limitsCPU requestsMemory requestsStorage requests
sandbox24Gi24Gi10Gi
standard816Gi816Gi50Gi
premium3264Gi3264Gi200Gi
customplanner-specifiedplanner-specifiedplanner-specifiedplanner-specifiedplanner-specified

custom is negotiated per tenant — RCS picks the pool shape from the CPU, memory, and storage footprint you describe in the request. See “Requesting a tier change” below for the flow.

Two read-only kubectl commands answer the “how much have I used” question:

  • kubectl describe resourcepool <name> shows the tenant-wide allocated versus used totals — CPU, memory, and storage broken out. ResourcePool is cluster-scoped, so this command takes no namespace; passing -n is ignored.
  • kubectl describe resourcequota -n <your-tenant>-<namespace> shows the usage attributed to a single namespace, which is how you see where the shared pool is being spent.

The ResourcePool resource itself is Capsule-managed: you can read it but you cannot edit it. A Grafana view of the same numbers, with trend lines per namespace, is covered in Monitoring.

Tier changes are an RCS ticket, not an API call. Open a ticket naming:

  • your current tier,
  • the tier you want,
  • a one-line rationale (for example “workload now runs nightly and needs 16Gi of memory for the training step”).

Moving from sandbox to standard is the common path once a research team has proven their workload runs and wants to move from experiments to a scheduled pipeline. Moving to premium requires more justification because it reserves a non-trivial slice of the cluster. custom is negotiated per-project — give RCS the approximate CPU / memory / storage footprint you need and they will pick a pool shape that covers it.

Tier moves on Kestrel are an RCS operation. However, the upstream allocation that backs your tenant is an Alliance Cloud RAP — if you are hitting the ceiling on a def-profname default RAP and your workload has grown into production, the durable fix may be applying to the annual Alliance Resource Allocation Competition (RAC) for a crg-profname-xx Cloud RAP with a larger footprint. RCS can advise on whether a tier change, a new Cloud RAP, or a custom allocation is the right move for your workload.

The deeper reference for the flow, including the fields RCS needs in the ticket and the SLO on turnaround, lives at tenant-admin/quota-requests. For anything more complex than “bump me to the next tier”, start with a ticket and RCS will walk the shape with you.