-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Add support for configurable precedence of FilterChainMatch rules. #3411
Comments
Another thing that @lizan pointed out is that in routes we're using "first match wins" approach, i.e. the order of filter chain blocks would matter. With current implementation, following configuration:
would match 2nd filter chain if connection matched all requirements, but per @lizan it should match 1st filter chain, since it matches all of its requirements as well, and it's configured first. Thoughts? @mattklein123 @ggreenway @htuch @lizan |
That is what actually @ggreenway said:
|
In general I think first match wins is going to be the simplest to understand for most people, and when we implement other rules like IP/CIDR matching, it may be the only way it makes sense. However, I know that there are use cases in which we want to optimize and do hash lookups (e.g., large number of SNI matches). My feeling on this is that the documented behavior should be FIFO, but if envoy can detect that a hash lookup is correct, it can switch to that (depending on the match conditions across all matches). |
Perhaps first-match-wins with LRU cache? |
@mattklein123 I think the "simplest to understand" is going to be based on the prior experience with other software, e.g. for me (and probably many others) the most obvious choice is the-most-specific-match-wins, since that's what NGINX does for the server name matching, and I would be extremely surprised if the filter chain match for Having said that, I recognize that it's inconsistent with how the matching for HTTP routing rules is done, which is definitely a valid concern, and if most of the maintainers agree that first-match-wins is a better approach, then I can work on the change... But please note that it isn't going to scale well. first-match-wins: @mattklein123 @lizan I'd like to hear from @alyssawilk @htuch and @ggreenway (and anyone else who has opinion on this, really) before making any changes. |
As I said before, I think this can be fixed by intelligent detection of when a set of matching criteria can be optimized into a hash lookup. But, personally, I would treat that as the common case. Anyway, I do think that given the other match types we have planned, FIFO with AND semantics (like router) is going to be the easiest for people to understand given other Envoy semantics. But, also agreed, let's hear from other folks. |
I prefer the faster hash-lookup for SNI with most-specific-wins. If we mostly do first-match-wins, but we try to detect cases where we can use a different algorithm, I think we'll run into problems where a small config change causes a massive performance degradation, and that can be confusing for users. |
How will this work for IP/CIDR matching? Will it be a hash lookup/most-specific followed by a FIFO match of CIDRs? |
A series of hash-lookups with wider and wider netmask, i.e.:
with a limit on the widest netmask configured, and perhaps with an optimization to only try the netmasks that were configured. |
Couldn't this be done with the LcTrie implementation we have? |
...or that :) I wasn't aware we have LcTrie already. |
My question was less about how to do the lookup for IP but more of whether the type of nested hash lookups we are doing is going to be confusing from a configuration standpoint for users. I guess this gets to @htuch question about allowing the precedence rules to be configurable so the nesting order is dynamic. The reason I think it's confusing, FWIW, is that the configuration is specified essentially as a list of matching rules, and I think most users would interpret that as a set of AND conditions that if they match would win. They might not immediately realize that some of the rules are more important than others. I don't know if this is going to be confusing, but with the various options we have already laid out (https://github.com/envoyproxy/envoy/blob/master/api/envoy/api/v2/listener/listener.proto#L69) it seems like it might be. Anyhow, I guess as long as we have good examples and very clear documentation the nested hash approach (with maybe configurable precedence in the future) is OK with me. Can we potentially commit to doing some good examples in the docs in addition to the SNI ones we already have in the FAQ? |
Yeah, I'll add more examples and the docs, regardless of the decision here.
It's still a set of AND conditions, i.e. ALL rules must match in order for any filter chain to be selected. Example:
For the configuration above (with a fallback for non-HTTP/2 traffic for
However, even with only 2 matching rules, this is already much more complex routing than usually performed on the same port, and if we assume that this feature is going to be used mostly for SNI routing, then I don't see any advantage of the first-match-wins approach (and it might be simply confusing, if you look at the first config in this comment). |
@PiotrSikora for the relatively simple rules we are going to have (compared to HTTP routing for example) you have convinced me that the precedence system makes sense with nested hash/trie/whatever lookups, so I think my vote has switched over. We can always make precedence configurable later as @ggreenway and @htuch suggested and as long as wen have good examples I think it's probably fine for most (all?) uses cases. |
I'm fine with most-specific-match-wins as long as we have clear field precedence order, either pre-defined or user-configured, and good documentation. In @PiotrSikora 's example I still think that:
should be able to fallback to 1st filter chain (empty, thus catchall) without adding |
Catch-alls are some of the corner cases I'm concerned about. I think if we have a set of really good examples we should be able to iterate together on the best final behavior, though I think we all now agree we can do this largely within the confines of the existing implementation. |
I'd just point out that in addition to the above discussion, first-match-wins is not suitable for extremely large CIDR matching scenarios as it is O(n) in the number of filter chains, e.g. O(100k) of filter chains, each matching on different CIDR. We have some internal scenarios that need this level of scale. So, whatever we do, we should provide the ability to do a classical most-specific match solution for CIDR. FWIW, the first-match-wins semantics of route configurations also need some thought for a similar scaling concern. I think that providing a sensible precedence ordering initially based on most-specific match and usual use cases, and the ability to later add flexible ordering sounds good. |
@htuch lets open a different issue on that. The complexity of the existing routing rules are going to make it almost impossible to build a hashing implementation (especially due to regex). I think we can do some interesting things with HTTP routing along the lines of having an optional new type of route configuration that is designed for a most specific wins hashing implementation and by definition implements a much smaller set of matching conditions. It could even be a layered implementation where once a match is found an L2 FIFO match using the existing routing rules can optionally take place. |
From discussion in #3217 (comment):
@htuch
@ggreenway
@htuch
@PiotrSikora
This is mostly a place-holder to gauge interest in configurable precedence of the
FilterChainMatch
rules, with no immediate plans for adding it.The text was updated successfully, but these errors were encountered: