kedacore / keda

KEDA is a Kubernetes-based Event Driven Autoscaling component. It provides event driven scale for any container running in Kubernetes
https://keda.sh
Apache License 2.0
8.49k stars 1.07k forks source link

Redis Scaler: Allow name resolution of service based on namespaced short name. #6247

Open dfsdevops opened 2 weeks ago

dfsdevops commented 2 weeks ago

Proposal

Allow short hostnames for redis services, for namespace-agnostic scaledobject definitions.

spec:
  triggers:
  - type: redis
    metadata:
      port: "6379"
      host: redis
      databaseIndex: "0"
      listName: mylist
      listLength: "1"
  Warning  KEDAScalerFailed         39s (x2 over 72s)      keda-operator  connection to redis failed: dial tcp: lookup redis on 172.20.0.10:53: no such host

Alternative solution: Allow interpolated environment variables so the URL including the namespace can be constructed via the downward API. Currently it does not expand.

keda-operator  connection to redis failed: dial tcp: lookup redis.$(NAMESPACE).svc.cluster.local: no such host

Use-Case

When deploying a scaledObject to multiple namespaces with kustomize, there is no way to template a portion of a field with a namespace, so each and every overlay requires specifically patching it per-instance in order to support connecting to the correct endpoint for scaling. Couple this with an app with X number of microservices all scaling off of redis lists and you have to repeat this tedious process or violate a principle of using kustomize by adding a templating step. By supporting dynamic namespace overrides in some capacity, we could reduce reliance on templating and tedious workarounds.

Is this a feature you are interested in implementing yourself?

Maybe

Anything else?

I'm not sure if this is something that would be more of a general solution for all scalers, or specific to redis. I'm not sure if other scalers have solved this issue. I apologize if theres another discussion on this, I already tried searching for this issue and didn't see anything similar.

JorTurFer commented 2 weeks ago

I think that this is a recurrent issue and we could introduce any kind of templating to replace at least the namespace. The downward API doesn't work here as KEDA's namespace isn't the same as the redis (that's why the short name doesn't work) but maybe we could introduce a "pattern matching" to replace a given key with the ScaledObject namespace. WDYT @kedacore/keda-core-contributors ?

dfsdevops commented 2 weeks ago

A couple thoughts.

  1. I think I overreacted about how tedious it would be to patch. I realized I can broadly set the host field in the Redis trigger via a more generalized patch for all autoscalers in Kustomize. (or based on a label). Not so bad as a per-instance override. So, I'm quite a bit less concerned at this point. Barebones example:

    ---
    apiVersion: kustomize.config.k8s.io/v1beta1
    kind: Kustomization
    namespace: mynamespace
    
    resources:
    - ../base/myapp
    
    patches:
    - target:
        kind: ScaledObject
        labelSelector: "scaler=redis"
      patch: |-
        - op: replace
          path: /spec/triggers/0/metadata/host
          value: redis.mynamespace.svc.cluster.local
  2. I think a prior-art implementation of using templating in a custom resource can be seen in ArgoCD applicationSets. Might be inspiration. https://argo-cd.readthedocs.io/en/latest/operator-manual/applicationset/#parameter-substitution-into-templates
  3. An alternative per-scaler solution I just thought of would be to add a field called namespacedHost or something like that, in which case, append .<namespace>.svc to whatever is in the host field.