Plans and configures multi-tenancy on GKE. Covers namespace isolation, RBAC planning for teams, resource quotas, LimitRanges, network isolation, and cost allocation. Use when designing GKE multi-tenancy, configuring GKE namespaces, setting up resource quotas, or isolating GKE teams. Don't use for single-tenant cluster configuration or general deployment instructions (use gke-basics or gke-app-onboarding instead).
Scanned 9/2/2026
Install to Claude Code
npx -y skills add nuroctane/nur-cli --skill gke-multitenancy --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Gke Multitenancy?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/nuroctane-gke-multitenancy)More formats (shields.io, HTML) on the badges page.
---
name: gke-multitenancy
description: >-
Plans and configures multi-tenancy on GKE. Covers namespace isolation, RBAC
planning for teams, resource quotas, LimitRanges, network isolation, and
cost allocation. Use when designing GKE multi-tenancy, configuring GKE
namespaces, setting up resource quotas, or isolating GKE teams. Don't use
for single-tenant cluster configuration or general deployment instructions
(use gke-basics or gke-app-onboarding instead).
metadata:
category: Containers
---
# GKE Multi-Tenancy
This reference covers enterprise multi-tenancy patterns on GKE, including
namespace isolation, RBAC planning, resource quotas, and network segmentation.
> **MCP Tools:** `apply_k8s_manifest`, `get_k8s_resource`, `check_k8s_auth`,
> `describe_k8s_resource`, `delete_k8s_resource`
## When to Use
- Multiple teams sharing a single GKE cluster
- Isolating workloads by environment (dev/staging/prod) within one cluster
- Implementing least-privilege access control
- Cost allocation across teams or projects
## Multi-Tenancy Models
| Model | Isolation | Complexity | Cost |
| ----------------------------- | ------------ | ---------- | -------------- |
| **Namespace-per-team** | Soft (RBAC + | Low | Lowest (shared |
: : Network : : cluster) :
: : Policy) : : :
| **Namespace-per-environment** | Soft | Low | Low |
| **Node pool-per-team** | Medium | Medium | Medium |
: : (dedicated : : :
: : compute) : : :
| **Cluster-per-team** | Hard (full | High | Highest |
: : isolation) : : :
> **Golden path recommendation**: Start with namespace-per-team for cost
> efficiency. Escalate to stronger isolation only when compliance requires it.
## Namespace Isolation Setup
### 1. Create Namespaces
```bash
kubectl create namespace team-a
kubectl create namespace team-b
kubectl label namespace team-a team=a
kubectl label namespace team-b team=b
```
### 2. RBAC Configuration
**Principle**: Grant minimal permissions per namespace. Never bind to
`system:authenticated`.
```yaml
# Namespace-scoped role for a team
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: team-a-developer
namespace: team-a
rules:
- apiGroups: ["", "apps", "batch"]
resources: ["pods", "deployments", "services", "configmaps", "jobs"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: team-a-developers
namespace: team-a
subjects:
- kind: Group
name: "team-a@example.com" # Google Group
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: team-a-developer
apiGroup: rbac.authorization.k8s.io
```
**RBAC best practices:** Use Google Groups for subject bindings. Prefer
namespace-scoped Roles over ClusterRoles. See the `gke-platform-security` skill
for full RBAC hardening guidance.
### 3. Resource Quotas
Prevent any single team from consuming all cluster resources:
```yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: team-a-quota
namespace: team-a
spec:
hard:
requests.cpu: "10"
requests.memory: "20Gi"
limits.cpu: "20"
limits.memory: "40Gi"
pods: "50"
services: "10"
persistentvolumeclaims: "10"
```
### 4. LimitRanges
Set default and maximum resource constraints per container:
```yaml
apiVersion: v1
kind: LimitRange
metadata:
name: team-a-limits
namespace: team-a
spec:
limits:
- type: Container
default:
cpu: "500m"
memory: "512Mi"
defaultRequest:
cpu: "100m"
memory: "128Mi"
max:
cpu: "4"
memory: "8Gi"
```
> [!IMPORTANT] **Mandatory Defaults**: When defining `min` or `max` limits in a
> `LimitRange`, you **must** also define corresponding `default` and
> `defaultRequest` values. If you set a `min` or `max` without defaults, any pod
> deployed without explicit resource requests/limits will be rejected by the
> admission controller.
### 5. Network Isolation
Apply default-deny per namespace (see the `gke-workload-security` skill), then
allow intra-team traffic:
```yaml
# Allow same-namespace pods to talk + DNS
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-same-namespace
namespace: team-a
spec:
podSelector: {}
ingress:
- from:
- podSelector: {}
egress:
- to:
- podSelector: {}
- to: # Allow DNS
- namespaceSelector: {}
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53
```
## Cost Allocation
### Labels for Cost Attribution
```bash
# Label namespaces for billing
kubectl label namespace team-a cost-center=engineering
kubectl label namespace team-b cost-center=data-science
```
### GKE Cost Allocation
Enable GKE cost allocation to break down costs by namespace and label:
```bash
gcloud container clusters update <CLUSTER_NAME> --region <REGION> \
--enable-cost-allocation
```
View in Cloud Billing > GKE Cost Allocation.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!