Secure Kubernetes Multi-tenancy with Capsule: Isolate Teams without Cluster Sprawl

DevOps tutorial - IT technology blog
DevOps tutorial - IT technology blog

The 2 AM Wake-up Call: Why Namespaces Aren’t Enough

My phone started screaming at 2:14 AM. PagerDuty reported that our entire staging cluster had gone dark. Ten minutes into the investigation, I found the culprit: a developer from the Data Science team had launched a Spark job requesting 128 cores without any resource limits. It devoured every available CPU cycle, starving the Frontend and API services until they collapsed.

The real issue wasn’t just a missing quota. I had granted broad permissions because managing individual RBAC roles for 15 different teams was becoming a full-time job. I was trapped in ‘Namespace Hell.’ Boundaries were porous, and one mistake could sink the entire ship.

Mastering multi-tenancy is a mandatory skill for platform engineers. You need to provide a cloud-like experience where teams feel they own their environment, but you maintain control over the blast radius. Capsule makes this possible.

Comparing Multi-tenancy Approaches

Choosing the right strategy depends on your budget and team size. Here is how the most common methods stack up against Capsule.

1. The “Cluster-per-Team” Approach

This offers the best isolation but destroys your budget. If you support 15 teams, you pay for 15 control planes and 15 sets of logging stacks. Maintenance is a nightmare. Upgrading 15 clusters one by one is not a productive use of your time.

2. Standard Kubernetes Namespaces

This is the default, flat approach. You create a namespace and hand out a RoleBinding. However, namespaces can’t be grouped. You cannot easily tell Kubernetes, “This specific team gets 64GB of RAM across all five of their projects combined.” It’s an all-or-nothing game.

3. Capsule (The “Tenant” Operator)

Capsule adds a Tenant abstraction that sits above namespaces. It groups namespaces into a single administrative unit. By using an Admission Controller, it intercepts API calls to ensure teams stay within their sandbox. Users never need cluster-wide permissions.

Pros and Cons of Using Capsule

Pros Cons
Native Experience: Teams use standard kubectl. There is no proprietary CLI to learn. CRD Management: You are adding more Custom Resource Definitions to your cluster overhead.
Resource Aggregation: Set limits across multiple namespaces (e.g., Team A gets 20 total CPUs). Webhook Dependency: If the Capsule pod fails, users might be unable to create or update namespaces.
Automated Governance: Enforce Ingress hostnames and registry whitelists automatically. OIDC Setup: Integrating with providers like Okta or Keycloak requires upfront planning.

The Recommended Production Stack

Don’t just install the operator and stop there. A production-grade sandbox requires a few extra components to be truly secure:

  • Cert-Manager: Essential for managing the TLS certificates used by Capsule’s admission webhooks.
  • OIDC Provider (Dex/Keycloak): This maps your corporate AD groups directly to Capsule Tenants.
  • Capsule Proxy: This clever add-on ensures that when a user runs kubectl get namespaces, they only see their own.

Implementation Guide: Building the Sandbox

Let’s build a Tenant for a ‘Fintech’ team. They need the freedom to create their own namespaces, but we must restrict them to 32GB of RAM and a specific corporate domain.

Step 1: Install Capsule via Helm

We’ll start by deploying the controller. I assume you have a cluster ready and Helm installed.

# Add the repository
helm repo add projectcapsule https://projectcapsule.github.io/charts

# Update and install
helm repo update
helm install capsule projectcapsule/capsule -n capsule-system --create-namespace

Step 2: Define the Tenant

The Tenant object is the heart of the configuration. This manifest defines the strict boundaries for our Fintech team.

# fintech-tenant.yaml
apiVersion: capsule.clastix.io/v1beta2
kind: Tenant
metadata:
  name: fintech-team
spec:
  owners:
    - name: [email protected]
      kind: User
  namespaceOptions:
    quota: 10 # Alice can create up to 10 namespaces
  resourceQuotas:
    - scope: Tenant
      hard:
        requests.cpu: "8"
        requests.memory: 16Gi
        limits.cpu: "16"
        limits.memory: 32Gi
  ingressOptions:
    allowedHostnames:
      allowedRegex: ".*\.fintech.mycompany.com"
  limitRanges:
    - limits:
        - default:
            cpu: "500m"
            memory: "512Mi"
          defaultRequest:
            cpu: "100m"
            memory: "256Mi"
          type: Container

Apply this with kubectl apply -f fintech-tenant.yaml. Alice is now the official owner of this sandbox.

Step 3: Creating Namespaces as a Tenant Owner

This is where the workflow improves. Alice does not need cluster-admin rights. When she requests a new namespace, Capsule validates the request against her Tenant limits. If it passes, Capsule creates the namespace for her.

Alice can now run:

kubectl create ns fintech-prod
kubectl create ns fintech-dev

If she tries to create an 11th namespace, Capsule will reject the request. If her team tries to deploy a pod that pushes the total memory usage to 33Gi, the API server will block it instantly.

Step 4: Automating Network Isolation

Standard Kubernetes allows all pods to talk to each other. That is a security risk in multi-tenant setups. Capsule can automatically inject Network Policies into every new namespace the Fintech team creates.

# Add this to your Tenant spec
  networkPolicies:
    items:
      - policyTypes:
          - Ingress
        podSelector: {}
        ingress:
          - from:
              - podSelector: {} # Only allow traffic from within the same tenant

Troubleshooting Common Roadblocks

If your namespaces aren’t appearing, check the Capsule logs first. Use this command: kubectl logs -l app.kubernetes.io/instance=capsule -n capsule-system.

Most failures stem from certificate mismatches between the Kubernetes API and the Capsule webhook. If you use a custom CA, Capsule must be configured to trust it. Also, remember that Capsule manages identities, not users. You still need a basic ClusterRoleBinding that allows users to attempt namespace creation; Capsule simply acts as the gatekeeper that approves or denies the action.

Final Thoughts

Consolidating our fragmented clusters with Capsule slashed our monthly AWS bill by roughly $4,200—a 40% saving. More importantly, it restored my peace of mind. I no longer worry about a rogue Spark job taking down mission-critical services. You give developers the autonomy they crave, and you get the guardrails you need to stay sane.

Share: