<< All versions

Skill v1.0.1

currentAutomated scan100/100
gke-labs/kube-agents/gke-multitenancy

+3 new

──Details
PublishedOctober 26, 2026 at 06:10 AM
Content Hashsha256:bfd88668dd064a97...
Git SHA3e5be2e0e307
Bump Typepatch
Compare with v1.0.0
──Files
Files (1 file, 5.8 KB)
SKILL.md5.8 KBactive
SKILL.md · 202 lines · 5.8 KB

version: "1.0.1" 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: get_k8s_resource, check_k8s_auth, describe_k8s_resource
A change goes out as a pull request to the GitOps repository, never as a write from here: Kubernetes objects as YAML through gke-manifest-generation, cluster settings and other Google Cloud resources as Config Connector YAML through gcp-config-connector, opened with submit-suggestion. Each profile's config offers only the gke MCP server's read tools, and the broker refuses kubectl and gcloud writes.

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

ModelIsolationComplexityCost
Namespace-per-teamSoft (RBAC +LowLowest (shared

: : Network : : cluster) : : : Policy) : : :

Namespace-per-environmentSoftLowLow
Node pool-per-teamMediumMediumMedium

: : (dedicated : : : : : compute) : : :

: : 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

The namespaces are proposed as a pull request through submit-suggestion:

yaml
apiVersion: v1
kind: Namespace
metadata:
name: team-a
labels:
team: a
---
apiVersion: v1
kind: Namespace
metadata:
name: team-b
labels:
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

Label namespaces for billing in their manifests, proposed as a pull request through submit-suggestion: for example cost-center: engineering on team-a and cost-center: data-science on team-b.

GKE Cost Allocation

Enable GKE cost allocation to break down costs by namespace and label. It is a cluster setting (spec.costManagementConfig.enabled), changed as Config Connector YAML on the cluster's ContainerCluster through gcp-config-connector.

View in Cloud Billing > GKE Cost Allocation.

← v1.0.0All versions