istio: Priority for VirtualService when conflict happen
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 .
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
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: vsc-B
spec:
hosts:
- "www.example.com"
gateways:
- example-gateway
http:
- match:
- uri:
prefix: /api
route:
- destination:
port:
number: 80
host: service-B
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
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: A
spec:
hosts:
- "www.example.com"
gateways:
- example-gateway
http:
- match:
- uri:
priority: 99
prefix: /
route:
- destination:
port:
number: 80
host: service-A
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: account-service-external-vsc
spec:
hosts:
- "www.example.com"
gateways:
- example-gateway
http:
- match:
- uri:
priority: 0
prefix: /api
route:
- destination:
port:
number: 80
host: service-B
Additional context
About this issue
- Original URL
- State: open
- Created 6 years ago
- Reactions: 23
- Comments: 38 (18 by maintainers)
Why is this issue closed? I met a similar situation, is there any solution?
This forces a significant deploy order for
VirtualServices
.I vote no.
What if I need to update a
VirtualService
that needs to have the highest priority? Then I need to redeploy all the otherVirtualServices
too?Can we just have sensible defaults that can be overridden with some
priority
setting at theVirtualService
level?EDIT For what it’s worth, the defaults are already quite sensible. I just need to let my deploy guy deploy in whatever order he wants. Who am I to tell him how to do his job?
EDIT 2 Actually we’re just going to combine all the
VirtualServices
into a single resource.EDIT 3 Actually this is really annoying. We really need a better way to define which VirtualService takes priority. I have several VirtualServices that I cannot combine because they handle different hosts. However some of the backend prefixes clash. I’m stuck with one VirtualService that is eating all the requests that need to go to another VirtualService.
EDIT 4 For what it’s worth, why can’t we just look at the most specific path first? This would fix everything.
I am facing a similar scenario. I think the logic is sensible despite order or creation timestamp:
a. Priority:
exact
>prefix
>regex
b. The longer route would always override the shorter one when using
prefix
orregex
uri, eg:/api/serviceA/action
>/api/serviceA
c. The header matched route would override the other one when they both matched in uri, eg:
/api/serviceA/action
>/api/serviceA + header: version=1
>/api/serviceA
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
regex
andprefix
match rule).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: Currently, there is no way to enforce prioritization. The priorities are loosely handed to the matching VS rule that was mostly recently created. This makes it an extremely difficult task for operations / infrastructure teams to manage distributed VSs. However, this distributed VS capability is a requirement, and is the actual recommendation from Istio itself! The best microservice developer experience would be to manage their own VS, and be notified when they attempt to create a VS rule that conflicts with another team’s VS rule. Then those two teams work together to come to an agreement. This takes ownership of prioritizing rules off of the DevOps teams.
Why 2: There is a somewhat acceptable way to manage prioritization within the same VS at the moment- the controller reads the VS rules from top to bottom. While this isn’t exactly ideal, it allows a microservice team to prioritize how their traffic. The microservice team is now already in charge of resolving conflicting routing paths, and has full autonomy to address their own problems. The DevOps teams are again relieved of the job of managing rule prioritization.
implementing the priority field is definitely a must. we have a monolith which we are breaking down into microservices and all requests are sent with the same host. we cant distribute the routing rules for each microservice since its all being matched to the shorter uri which should actually be the last one matched if no other rules are met.
maybe you can dig into the code and contribute this to the original istio solution ?
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: We have multiple virtual services with a same host, we need to set a default route to this host, but we can’t add the default route to any of virtual service cause we can’t ensure the orders of merged virtual services.
Same as @amitde69 /stale, voting for reopen
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
@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
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 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.
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?
Hit this issue as well across unrelated VirtualService’s owned by different teams when migrating from Kubernetes Ingress to VirtualServices. We’ve decided to use regex paths by default to avoid this.
One of the frustrating things is this behavior (giving priority to whoever is first) is inconsistent with how K8s Ingress handles conflicts. It would be nice if there was an option on Gateway to opt into this behavior. Or vice-versa if an appropriate time was found to introduce the breaking change, allow people to opt into the old behavior.
@howardjohn can we reopen this? Do I understand correctly that if we do something as compatible with gateway-api as possible, it will be accepted in istio?
For example, I created a virtual service using
kubectl apply -f service-a.yaml
.Then I have a new route:
I don’t want to use the below commands to recreate.
Instead, I want to use the below commands to reload.