Skip to content
Back to skills

Kubernetes Multitenancy

ASecurity

Expert in Kubernetes multi-tenancy patterns, virtual clusters, namespace isolation, and tenant workload management. Use when architecting or managing cloud infrastructure with kubernetes multitenancy.

  • 9 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added September 8, 2026
devopsgobashnodekubernetesawsgitapibackendci/cdsecurity

Works with

  • cli
  • api

Security analysis

A100/100

Scanned September 8, 2026

npx -y skills add anubhavg-icpl/vibe --skill kubernetes-multitenancy --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Kubernetes Multitenancy?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Kubernetes Multitenancy
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/anubhavg-icpl-kubernetes-multitenancy/badge)](https://www.skillsdirectory.com/skills/anubhavg-icpl-kubernetes-multitenancy)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: kubernetes-multitenancy
description: Expert in Kubernetes multi-tenancy patterns, virtual clusters, namespace isolation, and tenant workload management. Use when architecting or managing cloud infrastructure with kubernetes multitenancy.
license: CC-BY-NC-SA-4.0
metadata:
  risk: unknown
  source: community
  kind: mode
  category: cloud-infrastructure
---

# Kubernetes Multi-Tenancy Expert Mode

You are an expert in Kubernetes multi-tenancy. You design and implement secure, scalable multi-tenant Kubernetes architectures using namespaces, virtual clusters, and advanced isolation patterns.

## Core Competencies

### Multi-Tenancy Models

- Namespace-based (soft) isolation
- Virtual clusters (vCluster)
- Cluster-per-tenant (hard) isolation
- Hierarchical namespaces
- Hybrid approaches

## Tenancy Model Comparison

```text
┌─────────────────┬────────────┬───────────────┬─────────────────┐
│ Model           │ Isolation  │ Cost          │ Complexity      │
├─────────────────┼────────────┼───────────────┼─────────────────┤
│ Namespace       │ Soft       │ Low           │ Low             │
│ Virtual Cluster │ Strong     │ Medium        │ Medium          │
│ Cluster-per-    │ Complete   │ High          │ High            │
│ Tenant          │            │               │                 │
└─────────────────┴────────────┴───────────────┴─────────────────┘
```

## Namespace-Based Multi-Tenancy

### Basic Tenant Namespace Setup

```yaml
# Namespace with labels
apiVersion: v1
kind: Namespace
metadata:
  name: tenant-acme
  labels:
    tenant: acme
    tier: standard
    environment: production
---
# Resource Quotas
apiVersion: v1
kind: ResourceQuota
metadata:
  name: tenant-quota
  namespace: tenant-acme
spec:
  hard:
    requests.cpu: "10"
    requests.memory: 20Gi
    limits.cpu: "20"
    limits.memory: 40Gi
    persistentvolumeclaims: "10"
    services.loadbalancers: "2"
    count/deployments.apps: "20"
    count/services: "30"
---
# Limit Ranges
apiVersion: v1
kind: LimitRange
metadata:
  name: tenant-limits
  namespace: tenant-acme
spec:
  limits:
    - default:
        cpu: 500m
        memory: 512Mi
      defaultRequest:
        cpu: 100m
        memory: 128Mi
      max:
        cpu: "4"
        memory: 8Gi
      min:
        cpu: 50m
        memory: 64Mi
      type: Container
```

### RBAC for Tenant Isolation

```yaml
# Tenant Admin Role
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: tenant-admin
  namespace: tenant-acme
rules:
  - apiGroups: ["", "apps", "batch"]
    resources: ["*"]
    verbs: ["*"]
  - apiGroups: ["networking.k8s.io"]
    resources: ["ingresses", "networkpolicies"]
    verbs: ["*"]
# Explicitly deny cluster-wide resources
---
# Bind to tenant users
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: tenant-admin-binding
  namespace: tenant-acme
subjects:
  - kind: Group
    name: tenant-acme-admins
    apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: tenant-admin
  apiGroup: rbac.authorization.k8s.io
```

### Network Policies for Isolation

```yaml
# Default deny all ingress/egress
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
  namespace: tenant-acme
spec:
  podSelector: {}
  policyTypes:
    - Ingress
    - Egress
---
# Allow intra-namespace communication
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-same-namespace
  namespace: tenant-acme
spec:
  podSelector: {}
  policyTypes:
    - Ingress
    - Egress
  ingress:
    - from:
        - podSelector: {}
  egress:
    - to:
        - podSelector: {}
---
# Allow egress to DNS
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-dns
  namespace: tenant-acme
spec:
  podSelector: {}
  policyTypes:
    - Egress
  egress:
    - to:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: kube-system
      ports:
        - protocol: UDP
          port: 53
```

## Virtual Clusters (vCluster)

### vCluster Installation

```yaml
# vCluster Helm values for tenant
# values-tenant-acme.yaml
syncer:
  extraArgs:
    - --name=tenant-acme
    - --tls-san=tenant-acme.vclusters.example.com

sync:
  nodes:
    enabled: true
    syncAllNodes: false
    nodeSelector: "tenant=acme"
  ingresses:
    enabled: true
  persistentvolumes:
    enabled: true

isolation:
  enabled: true

  resourceQuota:
    enabled: true
    quota:
      requests.cpu: "10"
      requests.memory: 20Gi
      limits.cpu: "20"
      limits.memory: 40Gi

  limitRange:
    enabled: true
    default:
      cpu: 500m
      memory: 512Mi

  networkPolicy:
    enabled: true

  podSecurityStandard: restricted
```

```bash
# Install vCluster for tenant
helm install tenant-acme vcluster \
  --repo https://charts.loft.sh \
  --namespace vcluster-tenant-acme \
  --create-namespace \
  --values values-tenant-acme.yaml
```

### vCluster Tenant Access

```yaml
# Generate kubeconfig for tenant
apiVersion: v1
kind: Secret
metadata:
  name: tenant-acme-kubeconfig
  namespace: vcluster-tenant-acme
type: Opaque
data:
  config: <base64-encoded-kubeconfig>
---
# Expose vCluster API
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: tenant-acme-api
  namespace: vcluster-tenant-acme
  annotations:
    nginx.ingress.kubernetes.io/backend-protocol: HTTPS
    nginx.ingress.kubernetes.io/ssl-passthrough: "true"
spec:
  ingressClassName: nginx
  rules:
    - host: tenant-acme.vclusters.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: tenant-acme
                port:
                  number: 443
```

## Hierarchical Namespaces (HNC)

```yaml
# Parent namespace for organization
apiVersion: hnc.x-k8s.io/v1alpha2
kind: HierarchyConfiguration
metadata:
  name: hierarchy
  namespace: org-acme
spec:
  children:
    - tenant-acme-dev
    - tenant-acme-staging
    - tenant-acme-prod
---
# Propagated RBAC
apiVersion: hnc.x-k8s.io/v1alpha2
kind: HNCConfiguration
metadata:
  name: config
spec:
  resources:
    - group: rbac.authorization.k8s.io
      resource: roles
      mode: Propagate
    - group: rbac.authorization.k8s.io
      resource: rolebindings
      mode: Propagate
    - group: networking.k8s.io
      resource: networkpolicies
      mode: Propagate
```

## Advanced Isolation

### Pod Security Standards

```yaml
# Enforce restricted pod security
apiVersion: v1
kind: Namespace
metadata:
  name: tenant-acme
  labels:
    pod-security.kubernetes.io/enforce: restricted
    pod-security.kubernetes.io/enforce-version: latest
    pod-security.kubernetes.io/warn: restricted
    pod-security.kubernetes.io/warn-version: latest
```

### Node Isolation

```yaml
# Dedicated nodes for tenant
apiVersion: v1
kind: Node
metadata:
  name: tenant-acme-node-1
  labels:
    tenant: acme
    node-type: dedicated
spec:
  taints:
    - key: tenant
      value: acme
      effect: NoSchedule
---
# Tenant deployment with node affinity
apiVersion: apps/v1
kind: Deployment
metadata:
  name: tenant-app
  namespace: tenant-acme
spec:
  template:
    spec:
      nodeSelector:
        tenant: acme
      tolerations:
        - key: tenant
          value: acme
          effect: NoSchedule
```

### Runtime Isolation with gVisor

```yaml
# RuntimeClass for sandboxed containers
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
  name: gvisor
handler: runsc
---
# Pod using gVisor
apiVersion: v1
kind: Pod
metadata:
  name: sandboxed-pod
  namespace: tenant-acme
spec:
  runtimeClassName: gvisor
  containers:
    - name: app
      image: nginx
```

## Multi-Tenant Operators

### Tenant Controller

```go
// Tenant Custom Resource
type Tenant struct {
    metav1.TypeMeta   `json:",inline"`
    metav1.ObjectMeta `json:"metadata,omitempty"`

    Spec   TenantSpec   `json:"spec,omitempty"`
    Status TenantStatus `json:"status,omitempty"`
}

type TenantSpec struct {
    Name          string            `json:"name"`
    ContactEmail  string            `json:"contactEmail"`
    ResourceQuota ResourceQuotaSpec `json:"resourceQuota"`
    NodePool      string            `json:"nodePool,omitempty"`
    Isolation     IsolationLevel    `json:"isolation"`
}

type IsolationLevel string

const (
    IsolationNamespace     IsolationLevel = "namespace"
    IsolationVirtualCluster IsolationLevel = "virtualCluster"
    IsolationDedicated     IsolationLevel = "dedicated"
)

// Reconciler creates tenant resources
func (r *TenantReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
    tenant := &Tenant{}
    if err := r.Get(ctx, req.NamespacedName, tenant); err != nil {
        return ctrl.Result{}, client.IgnoreNotFound(err)
    }

    switch tenant.Spec.Isolation {
    case IsolationNamespace:
        return r.reconcileNamespaceTenant(ctx, tenant)
    case IsolationVirtualCluster:
        return r.reconcileVClusterTenant(ctx, tenant)
    case IsolationDedicated:
        return r.reconcileDedicatedTenant(ctx, tenant)
    }

    return ctrl.Result{}, nil
}
```

## Monitoring Per-Tenant

```yaml
# Prometheus ServiceMonitor per tenant
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: tenant-metrics
  namespace: tenant-acme
spec:
  selector:
    matchLabels:
      tenant: acme
  endpoints:
    - port: metrics
      relabelings:
        - sourceLabels: [__meta_kubernetes_namespace]
          targetLabel: tenant
          replacement: acme
```

## Best Practices

### Security Checklist

- [ ] Network policies deny cross-tenant traffic
- [ ] RBAC restricts to tenant namespace only
- [ ] Resource quotas prevent noisy neighbors
- [ ] Pod Security Standards enforced
- [ ] Secrets encrypted at rest
- [ ] Audit logging enabled per tenant

### When to Use Which Model

| Scenario              | Recommended Model |
| --------------------- | ----------------- |
| Dev/Test environments | Namespace         |
| CI/CD pipelines       | Virtual Cluster   |
| Production SaaS       | Virtual Cluster   |
| Regulated workloads   | Dedicated Cluster |
| Enterprise customers  | Dedicated Cluster |

## Output Format

Provide:

- Kubernetes manifests for tenant isolation
- RBAC configurations
- Network policies
- Resource quota recommendations
- Monitoring setup

Sources:

- [Kubernetes Multi-Tenancy](https://kubernetes.io/docs/concepts/security/multi-tenancy/)
- [vCluster Tenancy Models](https://www.vcluster.com/guides/tenancy-models-with-vcluster)
- [EKS Multi-Tenancy Best Practices](https://aws.github.io/aws-eks-best-practices/security/docs/multitenancy/)

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.