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
Priority for VirtualService when conflict happen #10464
Comments
@Yisaer You can merge the two virtualservices. Currently istio will match virtualservices by creation timestamp. |
@hzxuzhonghu Thanks for your reply. After I merge 2 VirtualService in folloing YAML, How can it guarantee the HTTP request for www.example.com/api/xxx will be delivered to the Service-B ,not Service-A? apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: vsc-A
spec:
hosts:
- "www.example.com"
gateways:
- example-gateway
http:
- match:
- uri:
prefix: /
route:
- destination:
port:
number: 80
host: service-A
- match:
- uri:
prefix: /api
route:
- destination:
port:
number: 80
host: service-B |
The priority is by order, you should also change the match rule order |
This forces a significant deploy order for I vote no. What if I need to update a Can we just have sensible defaults that can be overridden with some EDIT EDIT 2 EDIT 3 EDIT 4 |
+1 for the above suggestions. I agree that But for exactly the reasons outlined here: https://istio.io/docs/ops/traffic-management/deploy-guidelines/#multiple-virtual-services-and-destination-rules-for-the-same-host We could have a case that the different backend services (different teams) do not have a deployment order defined. Which would lead to issues like #10485 (and this one) Anyway, we could also have an optional or EDIT 4 of @mehemken could also work -
find the rule which matches the most. (but that would mean matching all rules for every incoming request) |
Why is this issue closed? I met a similar situation, is there any solution? |
I would like to reopen this issue. We have a significant issue here with managing distributed VirtualServices. Having the most specific route match take priority, as @mehemken mentioned, would help. Although I can imagine this would also introduce issues (eg. how do you compare specificity between a I propose a different solution. Though I need to specify that I'm unfamiliar with the codebase here, so I don't know how much work it would be.
Why 1: Why 2: |
I vote reopen this issue too. Priority feature can make vs more flexible. And all virtual services with same hosts will be merged by create timestamp, the order is out of control. For example with a problem we are having now: |
@hzxuzhonghu Is there anyway to reopen this issue to find a working solution for VS route priorities? |
I donot think there is anyone working on it |
We are also facing the exact same issue with multiple VS tied up to the same host. In our case, the catch-all is per port, so we do have a match condition on the port number, but for URI it is still catch-all and we have multiple VS defining URI-based routes for the same port. |
I am facing a similar scenario. I think the logic is sensible despite order or creation timestamp: a. Priority: b. The longer route would always override the shorter one when using c. The header matched route would override the other one when they both matched in uri, eg: |
@hzxuzhonghu Is it a graceful way to reload or reorder the virtual service ? |
For all the above comments: the http match conditions are complex, code can not handle it well.
But looks like introducing priority for http route is necessary and is an imperious demand. |
@hzxuzhonghu I think the rule that first matched route override the others might be a performance consideration. |
What do you mean by reload |
For example, I created a virtual service using # service-a.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: service-a-vs
spec:
hosts:
- "www.example.com"
gateways:
- example-gateway
http:
- match:
- uri:
prefix: /
route:
- destination:
port:
number: 80
host: service-a Then I have a new route: # service-b.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: service-b-vs
spec:
hosts:
- "www.example.com"
gateways:
- example-gateway
http:
- match:
- uri:
prefix: /api
route:
- destination:
port:
number: 80
host: service-b I don't want to use the below commands to recreate. kubectl delete -f service-a.yaml
kubectl apply -f service-b.yaml
kubectl apply -f service-a.yaml Instead, I want to use the below commands to reload. kubectl apply -f service-b.yaml
kubectl apply -f service-a.yaml |
Look my comment above #10464 (comment) |
@hzxuzhonghu Just for imagination, is it possible to provide a crd like |
I've implement an operator and a crd "sub virtual service" to handle the priority. Please fell free to check whether it's useful for you. |
implementing the priority field is definitely a must.
maybe you can dig into the code and contribute this to the original istio solution ? |
Same as @amitde69 /stale, voting for reopen |
Ingress only has path match, while vs provides so many match conditions. They are different. |
@howardjohn @ramaraochavali This problem is worth a solution, it is usually a big blocker for people setting up south-north traffic policy. I am totally agree it should align with gateway API merging strategy |
We discussed this some where else and John also commented here - May be we should add api/feature flag in VS to indicate match_merge_semantics_with_gateway_api or some thing like that? |
Agree, for any compatibility feature we should have one flag |
https://istio.io/latest/docs/ops/best-practices/traffic-management/#split-virtual-services As the current behaviour is undefined, I think it's not a breaking change (or requires a flag) to make it defined? |
You could send headers to do a header match along with the service so you are checking on two areas for the route. Then if service a has a route match of /path and service b has a route match of /path there would be an addition check on the header. I have not tested it yet so I am not aware of any precedence issues. You could even have a service c with no header and I assume that any non header traffic would go there. The header could be { path : service-a } then the VS would match path = /path and header key : path with key : service-a . |
@hzxuzhonghu I understand they're different, I only meant the behavior to give precedence to the longest path match makes intuitive sense for any "prefix" type path matching behavior. |
This would be an egregious breaking change that would cause front page news outages. "not well documented" does not imply we can break everyone unfortunately. There are literally millions of virtualservices in production at this point |
There doesn't seem to be any plans to improve it, right? |
There is an improvement recently in #48071 |
#48071 fixes scenarios where there are overlapping wildcards; overlapping specific hosts should still be oldest first |
I realize now that my suggestion earlier will not help with North South traffic. It would only really safely work with internal traffic. It would make more sense if it was just ordered by path and put in reverse order so the longest match is first like @AlanMasciangelo suggested above. All the istiod logs output are the same so I assume they all get the same values and could easily add this to a tree. Then in match just march down the tree as far as you can. Based on current usage of adding a VS it appears to just add the match in order of the VS for prefix. You can tell this because it you simply add multiple matches in a single VS with the longer first it works like below Match The problem, as established, is when it's split over several VS there is no guaranteed order, but I would imagine the proxy could order this just fine with the correct data structure like a tree or trie when it gets added. This change should be backwards compatible as well since any work around would very likely still work and going from undefined behavior (random) to defined (ordered) is not breaking. Of course there is a case for people that already take advantage of order for some reason, which likely is the way I mentioned above, but folks be crazy sometimes so a feature flag for order by string or whatever the current way is called would be good. Also, in reading the gateway conflict resolution spec https://gateway-api.sigs.k8s.io/concepts/guidelines/?h=conflict#conflicts |
Hey istio maintainers, any news about this? Strange to see this not here, we have same situation where we need to have priority in resolution of it. |
The current approach is to use the HTTPRoute which has this baked in. |
@howardjohn I don't see in HTTPRoute possibility to set priority. This is from VirtualService. Question here is how to handle situations properly when we have several VirtualService's that serves traffic for the same url. Example:
Need have possibility to set high priority for prefix Can you provide a solution here? |
@Hronom my apologies, the terms are overloaded. I meant https://gateway-api.sigs.k8s.io/api-types/httproute/?h=httpro#merging, which has a clearly defined merging order |
We have added priority to envoyfilter, the same explicit setting could be applied to vs. |
@howardjohn thank you! Unfortunately we are not migrated yet to gateway api, is this works for service to service communication? (not edge to service)
@hzxuzhonghu this will be awesome! And I think this resolves this task and satisfy our needs. For now we stuck with vs Thank you a lot all of you! |
@hzxuzhonghu can you explain how did this? We are running into this problem ourselves and have migrated to using Gateway API. If we can priority by envoy filters then that is path we can consider. |
It is not implemented yet. I am not sure how gateway API can solve this |
Gateway API solves this by having a precedence order for routes that is decouple from list ordering (https://gateway-api.sigs.k8s.io/api-types/httproute/?h=httpro#merging) |
Yeah, that is ideal, in real use case users can still meet conflict. Even not sure how this ordered, not to mention regex semantics.
So in a word, k8s HTTPRoute almost have similar issue as istio VS |
Can we publicly document this creation timestamp behavior today on https://istio.io/latest/docs/ops/best-practices/traffic-management/#split-virtual-services if we are not planning to modify this behavior? |
Hi Team, sorry to bother, I want to confirm if I only have If my request has both header and uri, I can 100% route to aaa(First one)? I checked the document, the
Thanks! apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: istio-rollout-vsvc
spec:
gateways:
- istio-rollout-gateway
hosts:
- istio-rollout.apps.argoproj.io
http:
- match:
- headers:
sss:
exact: latest
uri:
prefix: /aaa/
route:
- destination:
host: aaa
- match:
- uri:
prefix: /aaa/
route:
- destination:
host: aaa-old |
Yes, you are right, first route mateched can be guaranteed to be routed to |
Describe the feature request
Hi, I'm wondering is it possible to set priority for each VirtualService when multi VirtualService Match get conflict.
In my case , I have 2 services , A and B. And my virtualservice configuration is following YAML.
When I visit www.example.com/api/xxx ,i noticed that the http request was arranged to the Service-A by istio-ingressgateway.
It seems the request also hit the virtualService Match of Service-A .
Describe alternatives you've considered
I guess we can add define priority attribute in virtualService in following way.
As 99 means the lowest level and 0 means the highest level, the request in my case will be arranged to the service-B
Additional context
The text was updated successfully, but these errors were encountered: