Amankan KEDA di cluster yang dipakai banyak tim: isolasi namespace, ClusterTriggerAuthentication, RBAC untuk CRD, pembatasan scaler per namespace, hingga kebijakan OPA/Gatekeeper yang mengontrol penggunaan KEDA.

Di episode 13 kita membahas keamanan kredensial: secret management, pod identity, dan least privilege untuk akses queue atau stream. Namun KEDA sendiri adalah komponen cluster-wide — ia memiliki CRD (ScaledObject, ScaledJob, TriggerAuthentication) yang bisa dipakai siapa saja yang punya akses cluster. Di episode ini kita membahas Multi-Tenancy & RBAC: bagaimana menjadikan KEDA aman dipakai bersama banyak tim, dari isolasi namespace hingga policy admission yang mengontrol penggunaan KEDA secara global.
Prinsip pertama multi-tenancy di Kubernetes: satu tim, satu namespace. Semua workload dan konfigurasi KEDA milik tim berada dalam namespace milik mereka. KEDA sebenarnya operator cluster-scoped — operator dan metrics server di namespace keda mengelola ScaledObject di seluruh cluster. Isolasi datang dari RBAC, bukan dari KEDA itu sendiri.
Periksa komponen KEDA dan scope-nya:
kubectl get pods -n keda
kubectl get deploy -n keda
kubectl api-resources | grep keda.shOutput kubectl api-resources | grep keda.sh menunjukkan bahwa ScaledObject, ScaledJob, TriggerAuthentication adalah resource namespaced, sedangkan ClusterTriggerAuthentication adalah resource cluster-scoped. Artinya: sebuah ScaledObject hidup di dalam satu namespace dan mengacu pada Deployment di namespace yang sama. Ini garis pemisah alami — tim A tidak bisa membuat ScaledObject yang mengautoscale Deployment milik tim B selama RBAC membatasi pembuatan ScaledObject pada namespace-nya.
Isolasi namespace saja tidak cukup. Kita perlu mengontrol konfigurasi apa yang boleh dibuat. Tiga area utama:
| Area | Risiko | Kontrol |
|---|---|---|
| Scaler credentials | Membaca secret milik tim lain | TriggerAuthentication per namespace |
| Max replicas | maxReplicaCount tinggi = resource cluster habis | ResourceQuota + LimitRange + policy |
| Trigger type | Scaler berbahaya atau tidak diizinkan | OPA/Gatekeeper |
TriggerAuthentication default bersifat namespaced — ia bisa dipakai oleh ScaledObject di namespace yang sama. Untuk kredensial yang dibagikan lintas namespace (misal satu akun service SQS untuk seluruh cluster), gunakan ClusterTriggerAuthentication. Ia bisa direferensikan dari namespace mana pun:
apiVersion: keda.sh/v1alpha1
kind: ClusterTriggerAuthentication
metadata:
name: cluster-sqs-auth
spec:
podIdentity:
provider: aws-eks
identityOwner: kedaScaledObject di namespace mana pun bisa memakainya:
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: sqs-consumer
namespace: orders
spec:
scaleTargetRef:
name: order-worker
maxReplicaCount: 20
triggers:
- type: aws-sqs-queue
clusterTriggerAuthenticationRef:
name: cluster-sqs-authPerhatikan perbedaannya dengan triggerAuthenticationRef biasa: referensi cluster menggunakan awalan cluster. Karena kredensial ini dibagikan, berikan hak aksesnya lewat RBAC agar hanya team platform yang bisa membuat ClusterTriggerAuthentication — pengguna biasa cukup memakai TriggerAuthentication namespaced milik tim mereka.
KEDA tidak membundel peran RBAC untuk pengguna akhir — kita yang mendefinisikannya. Pola umum: beri setiap tim hak penuh atas resource KEDA di namespace mereka, tanpa akses lintas namespace.
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: keda-user
namespace: orders
rules:
- apiGroups: ["keda.sh"]
resources: ["scaledobjects", "scaledjobs", "triggerauthentications"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]Binding Role tersebut ke ServiceAccount tim dalam namespace yang sama:
kubectl create rolebinding keda-user --role keda-user \
--serviceaccount orders:team-orders -n ordersTip
Uji RBAC dengan kubectl auth can-i: kubectl auth can-i create scaledobject -n orders --as system:serviceaccount:orders:team-orders. Perintah ini memberi jawaban cepat sebelum Anda mengganti pipeline.
KEDA menginstal admission webhooks — server HTTPS yang dicegat Kubernetes sebelum resource KEDA disimpan. Ada dua jenis: validating (menolak konfigurasi invalid) dan mutating (menulis default ke konfigurasi). Periksa webhook yang terpasang:
kubectl get validatingwebhookconfigurations | grep keda
kubectl get mutatingwebhookconfigurations | grep keda
kubectl logs -n keda deploy/keda-admission -fContoh yang divalidasi: minReplicaCount lebih besar dari maxReplicaCount, pollingInterval di bawah 10 detik, atau cooldownPeriod kurang dari 0. KEDA menolak konfigurasi semacam itu di depan, sehingga operator tidak pernah menerima ScaledObject rusak.
Mutating webhook mengisi nilai default, misalnya pollingInterval: 30, cooldownPeriod: 300, dan minReplicaCount: 1 saat tidak disebutkan. Ini penting untuk ketenangan tim: ScaledObject tanpa field eksplisit tetap berperilaku dapat diprediksi.
Validasi bawaan KEDA mengecek kesintasan konfigurasi. Untuk kebijakan bisnis — "maxReplicaCount maksimal 50", "dilarang scaler jenis kubernetes-api", "minReplicaCount harus 0 hanya untuk dev" — gunakan policy engine seperti OPA/Gatekeeper. Gatekeeper adalah admission controller dengan kebijakan Rego.
apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
name: keda-maxreplica
spec:
crd:
spec:
names:
kind: KedaMaxReplica
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package keda
violation[{"msg": msg}] {
input.review.kind.kind == "ScaledObject"
spec := input.review.object.spec
spec.maxReplicaCount > input.parameters.maxReplica
msg := sprintf("maxReplicaCount %v melebihi batas %v", [
spec.maxReplicaCount, input.parameters.maxReplica])
}Terapkan constraint-nya per namespace, misalnya cap maxReplicaCount di angka 50 untuk semua tim:
kubectl apply -f constrainttemplate.yaml
kubectl apply -f - <<EOF
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: KedaMaxReplica
metadata:
name: maxreplica-50
spec:
parameters:
maxReplica: 50
match:
kinds:
- apiGroups: ["keda.sh"]
kinds: ["ScaledObject"]
EOFKarena ConstraintTemplate berisi blok rego dengan syntax mirip template, pastikan manifest-nya selalu dalam fenced code block seperti di atas. Kebijakan lain yang umum: melarang ClusterTriggerAuthentication dibuat pengguna non-platform, mewajibkan fallback.replicas untuk workload critical, atau menolak minReplicaCount: 0 di namespace production.
Warning
KEDA dan Gatekeeper keduanya berbasis admission webhook — urutan eksekusi tidak dijamin. Jangan mengandalkan KEDA validating webhook untuk kebijakan bisnis, dan jangan mengandalkan Gatekeeper untuk validasi sintaks. Dua lapis dengan peran berbeda adalah pola yang benar.
TriggerAuthentication via ConfigMap antar namespace. ConfigMap adalah namespaced; cara yang benar adalah ClusterTriggerAuthentication atau memisahkan kredensial per tim.ClusterRole KEDA ke semua tim menghancurkan isolasi. Selalu Role namespaced.identityOwner: keda. Pada podIdentity, nilai ini menentukan apakah kredensial dibaca dari ServiceAccount milik KEDA (bukan workload) — penting untuk ClusterTriggerAuthentication yang dibagikan.maxReplicaCount: 100 tetap dibatasi kapasitas CPU/memory oleh ResourceQuota; tanpa quota, satu ScaledObject bisa menguras node.Episode ini menjadikan KEDA platform yang aman dipakai banyak tim: isolasi namespace sebagai batas logis, perbedaan TriggerAuthentication vs ClusterTriggerAuthentication, RBAC untuk CRD KEDA, peran validating/mutating webhook, dan kebijakan OPA/Gatekeeper yang menegakkan batasan bisnis.
Poin yang harus kalian bawa:
ClusterTriggerAuthentication untuk kredensial bersama lintas namespace, dengan identityOwner yang tepat.maxReplicaCount.kubectl auth can-i sebelum roll out pipeline.Semakin banyak tim memakai KEDA, semakin besar biaya yang bisa dihemat — tetapi juga semakin besar risiko tanpa tata kelola. Di episode 15 selanjutnya kita membahas Best Practice & Cost: FinOps dengan scale-to-zero untuk batch dan AI inference, tuning activation agar tidak thrashing, serta strategi reliability seperti fallback replicas dan monitoring aktivasi scaler. Sampai jumpa di episode 15!