Membangun fondasi Kubernetes sebagai platform: cluster provisioning yang konsisten, namespace per-team, resource quotas, dan RBAC yang aman sebagai lapisan pertama abstraksi untuk multi-team

Setelah di episode 3 kita merancang golden path sebagai abstraksi, saatnya membangun fondasi teknis yang menopangnya: Kubernetes platform. Golden path tidak bisa eksis di atas cluster yang asal-asalan — setiap developer yang men-deploy akan merasakan setiap kekacauan namespace, setiap namespace yang kehabisan resource, dan setiap permission yang salah.
Mengapa episode ini penting? Karena semua episode berikutnya (IDP, GitOps, observability, zero trust) menumpuk di atas fondasi ini. Platform yang dibangun di atas cluster tanpa struktur multi-team yang jelas akan runtuh sendiri ketika tim kedua mulai men-deploy. Kita akan membangun empat pilar: provisioning, namespaces, quotas, dan RBAC.
Cluster harus lahir dari kode, bukan dari wizard konsol. Ini adalah prinsip yang sama dengan IaC, dan di episode 5 kita akan menyempurnakannya dengan GitOps. Untuk sekarang, fondasi minimalnya: setiap cluster (dev, staging, prod) di-provisioning dengan konfigurasi yang bisa diulang.
Contoh dengan k3d untuk lab, dan konsep yang sama berlaku untuk EKS/GKE:
k3d cluster create platform-dev \
--agents 2 \
--servers 1 \
--k3s-arg "--disable=traefik"Yang lebih penting dari command-nya adalah disiplinnya: simpan konfigurasi cluster di repo, beri nama yang bermakna per environment, dan jangan pernah membuat cluster ad-hoc di luar proses ini. Platform engineer adalah musuh dari "saya buatkan cluster khusus sekali ini saja".
Namespace adalah batas isolasi paling fundamental di Kubernetes. Untuk platform multi-team, aturan standarnya: satu tim = satu set namespace dengan nama yang konsisten (team-x-dev, team-x-prod). Kunci konsistensi namespace adalah asal-usulnya harus jelas: siapa pemiliknya dan untuk environment apa.
kubectl create namespace team-payments-dev
kubectl label namespace team-payments-dev \
team=payments environment=dev
kubectl label namespace team-payments-dev \
pod-security.kubernetes.io/enforce=restrictedLabel team dan environment adalah kunci yang nanti dipakai NetworkPolicy (episode 20), quota, dan cost attribution (episode 11). Jangan menganggap label sebagai hiasan — ia adalah struktur data platform.
Tetapkan dan pertahankan naming convention sejak hari pertama:
| Objek | Contoh | Keterangan |
|---|---|---|
| Namespace | team-payments-dev | {team}-{environment} |
| Deployment | payments-api | Nama service, bukan nama tim |
| Service | payments-api | Sama dengan deployment |
| Secret | payments-api-db | {service}-{purpose} |
Naming convention yang konsisten membuat observability (episode 9), billing (episode 11), dan automation (episode 12) jauh lebih mudah. Ini contoh "biaya kecil, keuntungan besar" dalam platform engineering.
Quota adalah cara platform memastikan satu tim tidak menghabiskan resource tim lain. Ada dua lapisan:
apiVersion: v1
kind: ResourceQuota
metadata:
name: team-quota
namespace: team-payments-dev
spec:
hard:
requests.cpu: "8"
requests.memory: 16Gi
limits.cpu: "16"
limits.memory: 32Gi
persistentvolumeclaims: 10
pods: "50"Quota ini adalah kontrak kapasitas: tim tahu batasnya, dan platform tidak perlu terus-menerus menolak deployment secara manual.
LimitRange menetapkan default dan batas per-Pod, mencegah Pod meminta resource gila-gilaan:
apiVersion: v1
kind: LimitRange
metadata:
name: default-limits
namespace: team-payments-dev
spec:
limits:
- default:
cpu: 500m
memory: 512Mi
defaultRequest:
cpu: 100m
memory: 128Mi
max:
cpu: "2"
memory: 2Gi
type: ContainerImportant
Quota tanpa monitoring adalah bom waktu. Ketika quota hampir penuh, tim harus tahu sebelum deployment gagal. Integrasikan prometheus kube_resourcequota (episode 9) dan pertimbangkan soft limit 80% yang memicu peringatan, bukan sekadar hard limit 100% yang menolak deployment.
RBAC adalah lapisan keamanan yang menentukan siapa bisa apa di platform. Prinsipnya sama untuk semua: least privilege — beri hak seminimal mungkin yang cukup untuk bekerja.
Tim hanya perlu mengelola resource di namespace mereka sendiri. Contoh Role yang mengizinkan workload management di namespace tim:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: team-payments-dev
name: team-operator
rules:
- apiGroups: [""]
resources: [pods, services, configmaps, secrets, persistentvolumeclaims]
verbs: [get, list, watch, create, update, patch, delete]
- apiGroups: [apps]
resources: [deployments, statefulsets, daemonsets]
verbs: [get, list, watch, create, update, patch, delete]
- apiGroups: [autoscaling]
resources: [horizontalpodautoscalers]
verbs: [get, list, watch, create, update, patch, delete]RoleBinding menghubungkan Role dengan user/group tim. Pola platform yang umum: satu group per tim di SSO, sehingga manajemen user tersentralisasi di identity provider:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
namespace: team-payments-dev
name: team-operator-binding
subjects:
- kind: Group
name: team-payments@example.com
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: team-operator
apiGroup: rbac.authorization.k8s.ioKunci di sini: binding ke group, bukan ke user individual. Admin yang mengelola team-payments@example.com di SSO tidak perlu menyentuh cluster sama sekali.
Tim platform sendiri butuh hak yang lebih luas tapi tetap terbatas. Pola yang umum: tim platform punya cluster-admin di cluster lab, tapi di produksi memakai hak selectif — misalnya membaca semua namespace untuk observability, dan hanya menulis di namespace milik platform.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: platform-observability
rules:
- apiGroups: [""]
resources: [pods, services, events, namespaces]
verbs: [get, list, watch]
- apiGroups: [metrics.k8s.io]
resources: [pods, nodes]
verbs: [get, list]
- apiGroups: [""]
resources: [nodes, persistentvolumes]
verbs: [get, list]Setiap tim punya namespace terisolasi dengan quota dan RBAC sendiri; tim platform mengelola lapisan lintas-tim (observability, ingress, security) di namespace khusus platform.
default, RBAC menyebar, dan tidak ada yang tahu batas tanggung jawab.requests vs limits — tanpa requests yang benar, scheduler tidak bisa menempatkan Pod dengan baik dan quota terasa sempit padahal node longgar.Tip
Gunakan kubectl auth can-i untuk menguji RBAC sebelum menyerahkan akses ke tim: kubectl auth can-i create deployments -n team-payments-dev --as system:group:team-payments@example.com. Verifikasi lebih baik daripada menebak.
Inti yang harus dibawa pulang:
team/environment adalah struktur multi-team yang sesungguhnya.Di episode 5 selanjutnya kita akan membuat fondasi ini bisa di-review dan direproduksi: IaC & GitOps untuk platform — Terraform/OpenTofu untuk provisioning, ArgoCD/Flux untuk sinkronisasi state, dan policy-as-code. Fondasi Kubernetes kita akan berubah dari "config yang benar" menjadi "config yang benar, otomatis, dan terdokumentasi"!