Skip to content

keda: multitenant setup#423

Merged
wozniakjan merged 12 commits into
kedify:mainfrom
wozniakjan:mt
Jun 12, 2026
Merged

keda: multitenant setup#423
wozniakjan merged 12 commits into
kedify:mainfrom
wozniakjan:mt

Conversation

@wozniakjan

@wozniakjan wozniakjan commented Mar 13, 2026

Copy link
Copy Markdown
Member

KEDA chart modifications for multitenant KEDA setup.

By default, KEDA is deployed in single-tenant mode. By setting kedify.multitenant.mode to default, KEDA deploys the full KEDA stack while staying aware of tenant deployments that may join later. There can be only a single KEDA with kedify.multitenant.mode: default. Additional tenants are deployed with kedify.multitenant.mode: tenant.

Each install (the default and every tenant) creates a kedify.io/tenant-registration ConfigMap describing its operator address and TLS secret. The kedify-agent discovers these across namespaces and populates the kedify-multitenancy-config Secret in the default install's namespace, which the shared metrics adapter reads to route each namespace's HPA requests to the right tenant operator.

Requires kedify-agent with multitenant feature enabled

agent:
  features:
    multitenantKEDAEnabled: true

Default KEDA multitenant deployment (must be exactly one default KEDA):

watchNamespace: foo
kedify:
  multitenant:
    mode: default

Secondary tenant KEDA deployments (an arbitrary number of tenants can be installed). In tenant mode the shared singletons (metrics apiserver, admission webhooks, CRDs) are disabled automatically, so a tenant just needs a unique operator.name:

watchNamespace: bar
kedify:
  multitenant:
    mode: tenant
operator:
  name: keda-operator-bar

When several tenants share a single namespace, also override serviceAccount.operator.name and certificates.secretName so they stay unique.

see also: #424

@wozniakjan wozniakjan changed the title multitenant KEDA keda: multitenant setup Mar 16, 2026
@wozniakjan wozniakjan force-pushed the mt branch 4 times, most recently from 4990cd5 to 22bb202 Compare March 18, 2026 12:44
@wozniakjan wozniakjan force-pushed the main branch 2 times, most recently from eff3384 to e349f69 Compare June 1, 2026 17:06
@wozniakjan wozniakjan requested a review from Copilot June 4, 2026 11:42

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds initial Helm chart support for a Kedify-flavored multi-tenant KEDA deployment by introducing new multitenancy values and wiring them into rendered manifests (metrics-server config, tenant registration, and scoped RBAC), while also preventing webhook ClusterRole(/Binding) creation when webhooks are disabled.

Changes:

  • Introduce kedify.multitenant.* values to model "default" vs "tenant" deployment modes.
  • Add tenant registration + agent secret-reader RBAC manifests, and default-tenant multitenancy Secret/Role wiring for the metrics API server.
  • Gate webhook ClusterRole/ClusterRoleBinding creation on webhooks.enabled (in addition to rbac.create).

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
keda/values.yaml Adds kedify.multitenant configuration surface and inline docs.
keda/templates/webhooks/clusterrolebindings.yaml Only renders webhook ClusterRoleBinding when webhooks are enabled.
keda/templates/webhooks/clusterrole.yaml Only renders webhook ClusterRole when webhooks are enabled.
keda/templates/metrics-server/kedify-role.yaml Adds namespaced Role/RoleBinding used in multitenant default mode.
keda/templates/metrics-server/kedify-multitenancy-config.yaml Adds the (initially empty) Secret used for multitenancy configuration in default mode.
keda/templates/metrics-server/deployment.yaml Wires multitenancy env var + Secret/emptyDir mounts into the metrics API server pod.
keda/templates/manager/deployment.yaml Adds tenant-mode env var and tweaks arg formatting.
keda/templates/kedify-tenant-registration-configmap.yaml Adds tenant registration ConfigMap emitted when multitenancy mode is enabled.
keda/templates/kedify-agent-secret-rbac.yaml Adds Role/RoleBinding granting the kedify-agent read access to the tenant TLS Secret.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread keda/values.yaml Outdated
Comment thread keda/values.yaml
Comment thread keda/templates/kedify-tenant-registration-configmap.yaml Outdated
Comment thread keda/templates/manager/deployment.yaml Outdated
zroubalik and others added 9 commits June 10, 2026 07:13
Signed-off-by: Zbynek Roubalik <zroubalik@gmail.com>
Signed-off-by: Jan Wozniak <wozniak.jan@gmail.com>
Signed-off-by: Jan Wozniak <wozniak.jan@gmail.com>
Signed-off-by: Jan Wozniak <wozniak.jan@gmail.com>
Signed-off-by: Jan Wozniak <wozniak.jan@gmail.com>
Two fixes so multiple keda operators can coexist (multitenant tenant mode),
including in the same namespace as the default install:

- webhook ServiceAccount was created regardless of webhooks.enabled, so a
  tenant install (webhooks.enabled=false) collided with the default release's
  keda-webhook SA. Gate it on webhooks.enabled like every other webhook object.
- tenant operators sharing a namespace contended for the same leader-election
  lock (operator.keda.sh) and only one became leader. Default the lock to the
  (unique) operator.name in tenant mode.

Both per-namespace and single-namespace multi-operator topologies now install
and run with the chart's normal RBAC, no manual cluster-admin.
- tenant registration ConfigMap derives the operator gRPC address from
  .Values.clusterDomain instead of a hardcoded cluster.local, so non-default
  cluster domains register the correct address.
- fix the multitenant mode description (grammar + correct *-metrics-apiserver
  naming) and note that tenant installs need a unique operator.name to avoid
  cluster RBAC collisions.
- drop trailing whitespace on the cert-rotation arg.
The hand-maintained values.schema.json had no entry for the kedify.* values, so
kedify.multitenant.* was unvalidated. Add a Kedify definition (mode enum
""/default/tenant, configSecretName, address, authority, agentNamespace,
agentServiceAccount) so Helm validates these on lint/template/install and IDEs
can autocomplete them.
The multitenant provider (kedify/keda#88) now emits Events via the new
events.k8s.io API instead of the deprecated core/v1 record.EventRecorder.
Point the metrics-server's dedicated kedify Role at the events.k8s.io
group so connection-state events aren't rejected as forbidden.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 11 out of 11 changed files in this pull request and generated 3 comments.

Comment thread keda/values.yaml Outdated
Comment thread keda/templates/metrics-server/kedify-multitenancy-config.yaml
Comment thread keda/templates/kedify-tenant-registration-configmap.yaml Outdated
@wozniakjan wozniakjan marked this pull request as ready for review June 10, 2026 08:17
- apply standard keda.labels (+ additionalAnnotations) to the tenant
  registration ConfigMap and the multitenancy-config Secret, matching the
  rest of the chart so label/annotation-based policies select them
- fix the values.yaml gRPC address doc to reference <clusterDomain> (the
  template default) instead of hardcoded cluster.local

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@wozniakjan wozniakjan requested a review from Copilot June 10, 2026 08:32
Comment thread keda/templates/manager/deployment.yaml

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 11 out of 11 changed files in this pull request and generated 1 comment.

Comment thread keda/templates/kedify-tenant-registration-configmap.yaml Outdated
ConfigMap data values must be strings; an all-numeric namespace would render
as a YAML int and be rejected. Quote it like the other data fields.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A tenant install only runs its own keda-operator; the metrics apiserver,
admission webhooks and CRDs are cluster singletons owned by the single
mode=default install. Gate those templates (and the operator's webhook /
apiservice caBundle patching) on mode!=tenant so a tenant never deploys a
second adapter, re-installs CRDs, or patches the default's webhook/APIService.

Tenants no longer need to set metricsServer.enabled=false / webhooks.enabled=false
/ crds.install=false: mode=tenant + a unique operator.name is enough. Cert
generation, the operator and its RBAC still render for tenants.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@wozniakjan wozniakjan merged commit 4a66db8 into kedify:main Jun 12, 2026
25 checks passed
@github-actions github-actions Bot added this to the keda/next milestone Jun 12, 2026
@github-actions github-actions Bot modified the milestones: keda/next, keda/v2.20.1-2 Jun 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants