Multi-Tenancy #
Saat banyak tim berbagi satu cluster, pertanyaan yang muncul adalah: seberapa terisolasi mereka satu sama lain? Tim A tidak boleh bisa baca data tim B. Bug di aplikasi tim C tidak boleh mengambil resource tim D. Perubahan RBAC oleh admin tim tidak boleh memengaruhi namespace tim lain. Inilah multi-tenancy — dan Kubernetes menyediakan beberapa lapisan isolasi dengan trade-off yang berbeda.
Soft vs Hard Multi-Tenancy #
Soft Multi-Tenancy (namespace-based):
→ Isolasi via RBAC, NetworkPolicy, ResourceQuota
→ Semua tenant share kernel yang sama
→ Misconfiguration di satu namespace bisa memengaruhi yang lain
(misalnya: DaemonSet yang tidak terbatas, kernel exploit)
→ Cocok untuk tim internal yang dipercaya di satu organisasi
Hard Multi-Tenancy:
→ Isolasi yang lebih kuat: cluster terpisah atau virtual cluster
→ Tenant tidak bisa memengaruhi satu sama lain sama sekali
→ Lebih mahal (overhead per cluster/vCluster)
→ Cocok untuk SaaS yang layani pelanggan eksternal,
atau tim dengan level kepercayaan yang berbeda
Namespace sebagai Unit Isolasi #
Namespace adalah unit isolasi dasar di Kubernetes. Untuk multi-tenancy yang baik, setiap tim atau aplikasi harus punya namespace sendiri dengan batasan yang jelas:
# Namespace untuk tim backend
apiVersion: v1
kind: Namespace
metadata:
name: team-backend
labels:
team: backend
environment: production
pod-security.kubernetes.io/enforce: restricted
---
# ResourceQuota untuk batasi resource yang bisa dikonsumsi
apiVersion: v1
kind: ResourceQuota
metadata:
name: team-backend-quota
namespace: team-backend
spec:
hard:
requests.cpu: "10"
requests.memory: "20Gi"
limits.cpu: "20"
limits.memory: "40Gi"
pods: "50"
services: "10"
persistentvolumeclaims: "10"
---
# LimitRange: default dan batas resource per container
apiVersion: v1
kind: LimitRange
metadata:
name: team-backend-limits
namespace: team-backend
spec:
limits:
- type: Container
default:
cpu: "500m"
memory: "512Mi"
defaultRequest:
cpu: "100m"
memory: "128Mi"
max:
cpu: "4000m"
memory: "4Gi"
RBAC untuk Isolasi Akses #
# Buat ServiceAccount dan RBAC untuk tim backend
# Mereka bisa manage resource di namespace mereka sendiri
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: team-backend-admin
namespace: team-backend
subjects:
- kind: Group
name: team-backend-engineers # Azure AD / Google Group / OIDC group
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: admin # admin di namespace ini saja
apiGroup: rbac.authorization.k8s.io
---
# Mereka tidak boleh akses namespace tim lain
# Cukup dengan tidak buat RoleBinding di namespace lain
# RBAC default: tidak ada permission = tidak ada akses
---
# Platform/SRE team: akses cluster-wide untuk monitoring
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: sre-cluster-view
subjects:
- kind: Group
name: sre-team
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: view # read-only cluster-wide
apiGroup: rbac.authorization.k8s.io
NetworkPolicy untuk Isolasi Jaringan #
# Default deny antar namespace, izinkan hanya yang eksplisit
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: isolate-namespace
namespace: team-backend
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
ingress:
# Izinkan traffic dari namespace yang sama
- from:
- podSelector: {}
namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: team-backend
# Izinkan dari Ingress Controller (untuk HTTP traffic dari luar)
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: ingress-nginx
ports:
- port: 8080
# Izinkan dari monitoring (Prometheus scraping)
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: monitoring
egress:
# DNS
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
ports:
- port: 53
protocol: UDP
- port: 53
protocol: TCP
# Internet (outbound)
- to:
- ipBlock:
cidr: 0.0.0.0/0
except:
- 10.0.0.0/8 # block akses ke cluster internal range lain
- 172.16.0.0/12
- 192.168.0.0/16
vCluster: Virtual Clusters #
Untuk isolasi yang lebih kuat tanpa overhead cluster fisik terpisah, vCluster menjalankan Kubernetes control plane virtual di dalam namespace:
# Install vCluster CLI
brew install loft-sh/tap/vcluster
# Buat virtual cluster untuk tim frontend
vcluster create team-frontend \
--namespace vcluster-team-frontend \
--connect
# Tim frontend sekarang punya cluster Kubernetes "sendiri"
# dengan API server, scheduler, dan controller manager sendiri
# Mereka bisa buat namespace, RBAC, CRD sesuka mereka
# Tapi semua Pod tetap berjalan di node host cluster
kubectl get nodes
# NAME STATUS ROLES AGE
# virtual-node Ready agent 1m
# Disconnect dari virtual cluster
vcluster disconnect
Kapasitas vCluster vs namespace biasa:
Namespace biasa:
→ Shared control plane (API server, etcd)
→ Tidak bisa install CRD sendiri (butuh ClusterRole)
→ Shared node pool
vCluster:
→ API server, etcd, scheduler sendiri (ringan, berjalan sebagai Pod)
→ Bisa install CRD sesuka mereka
→ Isolasi yang lebih kuat (tenant punya "cluster sendiri")
→ Shared node pool (efisien)
→ Overhead: ~200-500MB RAM per virtual cluster
Kapan Gunakan Cluster Terpisah #
Gunakan cluster terpisah untuk:
1. Lingkungan yang berbeda level kepercayaan
Production vs Development — engineer bisa bereksperimen di dev
tanpa risiko memengaruhi production
2. Compliance isolation
Workload yang butuh isolasi fisik untuk audit (PCI-DSS, HIPAA)
"Workload payment harus di cluster terpisah yang ter-audit"
3. Pelanggan eksternal
SaaS yang menyediakan Kubernetes untuk tiap pelanggan
Data isolation yang diperlukan antar pelanggan
4. Tim yang butuh control plane access
Tim yang butuh install CRD, admission webhook, atau
modifikasi cluster-level resource
Decision matrix:
Isolasi ringan (tim internal): → Namespace + RBAC + NetworkPolicy
Isolasi sedang (tim dengan CRD sendiri): → vCluster
Isolasi kuat (multi-org/compliance): → Cluster fisik terpisah
Ringkasan #
- Namespace + RBAC + NetworkPolicy + ResourceQuota untuk isolasi tim — empat lapisan ini memberikan isolasi yang cukup untuk sebagian besar organisasi dengan tim internal.
- ResourceQuota mencegah satu tim monopoli resource — tanpa quota, tim yang tidak disiplin dalam resource requests bisa membuat Pod tim lain tidak bisa di-schedule.
- NetworkPolicy default-deny antar namespace — isolasi jaringan harus eksplisit; jangan asumsikan namespace otomatis terisolasi jaringannya.
- vCluster untuk tim yang butuh control plane sendiri — jika tim butuh install CRD atau admission webhook, vCluster memberikan API server sendiri tanpa biaya cluster fisik.
- Cluster fisik terpisah untuk compliance dan kepercayaan yang berbeda — production vs development sebaiknya di cluster terpisah; pelanggan eksternal harus di cluster terpisah.
- Pod Security Standards di setiap namespace — label
pod-security.kubernetes.io/enforce=restricteddi setiap namespace tenant mencegah eskalasi privilege lintas tenant.
← Sebelumnya: Disaster Recovery Berikutnya: Anti-Pattern Production →