-
Notifications
You must be signed in to change notification settings - Fork 101
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support routing and scaling based on path #338
Comments
@philomory this seems very reasonable since we can easily save a lot of work and moving parts for operators. would you be interested in implementing this feature? no problem if not, just want to check. By the way, thanks for the detailed explanation. that was very helpful for my understanding |
I would love to help implement this, but I don't think I have the required time or the required skillset. I can sort of read Go, a little bit, but I'm not going to be able to write Go to an acceptable level of quality for a project like this. |
@philomory no problem. We can implement it. Before that, though, I'd like to get clarity on how this feature should interact with #281. Do you have any thoughts? |
@arschles That's a good question! I don't have a strong opinion, since we wouldn't be using the wildcard support, ourselves. That said, I think it probably should be supported to use both at once, even if I wouldn't recommend anyone actually do so. There's no (explicit) documentation that I can see on the behavior of apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-specific-host
spec:
rules:
- host: "foo.bar.com"
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: service1
port:
number: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-wildcard-host
spec:
rules:
- host: "*.foo.com"
http:
paths:
- pathType: Prefix
path: "/api"
backend:
service:
name: service2
port:
number: 80 That is, one of those has an exact match of the host but a less specific path prefix, and the other has a more specific path prefix but only a wildcard host match (assuming a request for |
@philomory perhaps this would be a start to a unified spec for path-based routing and wildcard support:
What are your thoughts? cc/ @comron and @andresrsanchez because you are both involved with #281 I'd ultimately like to come up with an over-arching issue that covers all use-cases in here and #281, before we proceed with implementing anything. |
I think there are significant advantages to matching the specified behavior of Three up-front concerns come to mind:
In general I don't think it's a good idea to define rules that say resource b is invalid because resource a already exists (with the obvious exception of multiple resources of the same type in the same namespace with the same name); I think it's better to simply define precedence rules that clearly specify which option will be chosen when multiple valid options exist (something that the Ingress documentation spells out for paths but oddly omits for hosts) |
@philomory you're right, there are indeed holes in my spec. perhaps you're right and it's best to just duplicate the ingress rules, along with a rule for overlapping wildcard hosts, as you said. I don't know enough of the specifics of those rules and I have to go read up. Do you have any preliminary ideas on what do with overlapping wildcard hosts? |
@arschles So, I did some digging, and I finally found some at least some information on the mandated behavior of Ingress, in the API reference (Emphasis mine):
The immediately relevant portion (the part I bolded) is fairly terse, and honestly could be interpreted multiple ways. I decided to verify the behavior of the specific controller we use,
The practical upshot of this is that This behavior may be specific to All that said, I did a bit more digging around, because a full-on replacement for the entirety of Ingress is already in development by
(It's worth looking at the actual specification, there's a lot of interesting detail in there). There's also a more general section on resolving conflicts. Obviously, the Gateway API is still in alpha and isn't widely supported (and also, may change), but the way the rules are currently written seems to indicate that the behavior of the |
@philomory thanks for this detail. This gives me an idea - I wonder if we should simply reference an With this scheme, WDYT? |
@arschles For the project, that does sound like a great idea (although it may become more complicated once the Gateway API is GA, since, then what do you do? I guess you could reference by The only problem I see is that, currently, apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-specific-host
spec:
rules:
- host: "foo.bar.com"
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: service1
port:
number: 80
- host: "*.foo.com"
http:
paths:
- pathType: Prefix
path: "/api"
backend:
service:
name: service2
port:
number: 80
In any case, when presented with an Ingress object with multiple rules and multiple paths, I'm not sure how
Another (less pressing) problem is that, for example, we have an older application which consists of multiple microservices behind an API gateway, and there's only one Ingress, which points to the API gateway (and the API gateway, in turn, routes traffic to different backend services depending on the request path; honestly the API Gateway's functionality became mostly redundant after we moved the application to Kubernetes, but it's not entirely redundant). Ultimately my goal for that particular application is to have |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 7 days if no further activity occurs. Thank you for your contributions. |
I don't think this is stale, exactly, although personally I'm investigating at this point using a service mesh (linkerd) to scale off of traffic metrics as an alternative to using the KEDA http-add-on (there will probably be cases that the http-add-on adresses that service mesh metrics do not, and vice versa, but I don't think any of them apply to my situation specifically). |
This issue has been automatically closed due to inactivity. |
This is a very crucial feature so that Keda http-add-on and ingress objects work in tandem. This issue should be re-opened |
This is a necessary feature for using http-add-on with ingress. |
Please, reopen this issue. Routing path's definitely should be supported - any complex app scenario usually have it. |
I vote this feature too. I understand team not have much capacity, but we can put it in backlog items first. @tomkerkhove |
@arschles is this project maintained ? we are considering to add a solution for this but we are not sure it is maintained... |
This project is definitely still maintained but community driven. We definitely welcome contributions! |
@tomkerkhove thanks for the response... The reason I have asked is that this issue seems to be really important if one is willing to work with the Keda interceptor and path-based routing ... this use case is pretty standard in our scenarios ... |
I started working on this |
I think this is related to @t0rr3sp3dr0's proposal in #605 as well |
The interceptor should be able to route requests for the same host to different services based on the request path.
Use-Case
When using an ingress controller, you can create Ingress objects that route different requests for the same host to different backend services, depending on the path portion of the request. This can be done by within a single Ingress object or across multiple of them.
When using the HTTP add-on, however, this won't work; you can, of course, still define multiple Ingress objects with different paths (or one Ingress object with multiple path entries), but they all need to point to the
keda-add-ons-http-interceptor-proxy
as their backend. Unfortunately, once the interceptor has intercepted them, it's not able to route them or scale them appropriately. The routing portion of this problem could be cumbersomely worked around by having a second ingress controller that the proxy could just route all traffic too (actually you could just make the proxy a service of type LoadBalancer and only have an ingress controller behind the proxy), but that still means that the scaling won't be handled as intended.Consider the following setup (pre-KEDA):
This will route a request for e.g.
https://api.example.com/media/foo
to themedia-provider
service, and a request tohttps://api.example.com/customer/bar?baz=1
to thecustomer-provider
service.Once you put the KEDA HTTP Add-on in place, things begin to break down:
Both
HTTPScaledObject
specs have the samehost
field, and there's nopath
field, so there's no way for the scaler to know where to route traffic to. Even if you put the Ingress Controller "behind" the interceptor (once a cluster-global installation is possible) to handle the routing, there's still no way for the scaler to know that when a bunch of requests come in for a/customer
endpoint, it should scale thecustomer-provider
Deployment rather than themedia-provider
Deployment.To resolve this problem, the
HTTPScaledObject
field should have an optionalspec.path
field, and possibly also an optionalspec.pathType
field. For example:Specification
For simplicity, I think you could get away with supporting only either 0 or 1 paths per
HTTPScaledObject
resource. Resolution would work as follows:HTTPScaledObject
which omitsspec.path
is equivalent to one which specifiesspec.path: /
spec.pathType
is implemented at all, it should have the same basic semantics asspec.rules[*].http.paths[*].pathType
inIngress
, except that the only supported values would bePrefix
andExact
(no need to include historical baggage likeImplementationSpecific
since there's only one implementation and there's also no history to derive baggage from)spec.pathType
is implemented at all, omittingspec.pathType
will be equivalent tospec.pathType: Prefix
HTTPScaledObject
s with a matchinghost
and evaluate them as follows:spec.pathType
is implemented, check all matchedHTTPScaledObject
resources withspec.pathType: Exact
and see if thespec.path
listed in theHTTPScaledObject
exactly matches the path part of the request URI. If so, the first match found is selected.spec.pathType
isn't implemented, or if none of theExact
typeHTTPScaledObject
s matched the path, take the remainingHTTPScaledObject
s matching thehost
field and sort them by the length of thespec.path
field. Check each resource'sspec.path
field to see if it is an "element-wise prefix" of the path portion of the request URI, given a separator of "/"; the first match found is selected.HTTPScaledObject
resource was selected in step 4, route the request to the service specified in thatHTTPScaledObject
, and scale the deployment specified in thatHTTPScaledObject
accordingly.This procedure defined in step 4 is essentially the same as that defined for matching requests to Ingress objects by the
networking.k8s.io
API, except for the absence of theImplementationSpecific
path type.With Ingress, users have the option to specify multiple
path
s for the same host (or even multiple hosts) in a single Ingress resource, but, I think that would be unnecessary complexity forHTTPScaledObject
; simply creating a distinctHTTPScaledObject
per path/prefix should suffice.The text was updated successfully, but these errors were encountered: