Reputation: 196
Let's assume that I have a configuration for istio (I use GCP):
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: my-route
namespace: my-service
spec:
hosts:
- "service.cluster.local"
http:
- match:
- headers:
specific-id:
regex: ^(1|2|3|4|5)$
route:
- destination:
host: "service.cluster.local"
subset: s-01
- match:
- headers:
specific-id:
regex: ^(6|7|8|9|10)$
route:
- destination:
host: "service.cluster.local"
subset: s-02
My destination rules are based on specific header (int value).
Now I want to change this configuration (because I need to do resharding), and I will have something like this:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: my-route
namespace: my-service
spec:
hosts:
- "service.cluster.local"
http:
- match:
- headers:
specific-id:
regex: ^(1|2|3|9|10)$
route:
- destination:
host: "service.cluster.local"
subset: s-03
- match:
- headers:
specific-id:
regex: ^(4|5|6|7|8|)$
route:
- destination:
host: "service.cluster.local"
subset: s-04
- match:
- headers:
specific-id:
regex: ^(1|3|5|7|9|)$
route:
- destination:
host: "service.cluster.local"
subset: s-05
My questions are:
Does istio rules allows to have intersections inside subsets (like to
have for one service regex: ^(1|2|3|4|5)$
and for another
^(1|3|5|7|9|)$
)?
After deployment of the new schema with new rules, when istio will apply it? Does istio guarantee that it won't be applied (to not remove old rules) before all of my new instances will be ready for traffic?
Upvotes: 2
Views: 711
Reputation: 3667
Does istio rules allows to have intersections inside subsets (like to have for one service regex:
^(1|2|3|4|5)$
and for another^(1|3|5|7|9|)$
)?
According to istio documentation:
Routing rules are evaluated in sequential order from top to bottom, with the first rule in the virtual service definition being given highest priority. In this case you want anything that doesn’t match the first routing rule to go to a default destination, specified in the second rule. Because of this, the second rule has no match conditions and just directs traffic to the v3 subset.
- route: - destination: host: reviews subset: v3
We recommend providing a default “no condition” or weight-based rule (described below) like this as the last rule in each virtual service to ensure that traffic to the virtual service always has at least one matching route.
The routing rules are evaluated in order. So the first match will always be selected.
regex: ^(1|2|3|9|10)$
would end up in subset: s-03
regex: ^(4|5|6|7|8|)$
would end up in subset: s-04
No matches would end up in subset: s-05
as regex: ^(1|3|5|7|9|)$
is already covered by subset: s-03
and subset: s-04
.
Note that You could set the subset: s-05
as default match with “no condition”.
However You can use "weight" to distribute traffic between matching rules.
And with little bit of creativity (by splitting intersecting groups into unique subsets) We can get the following configuration:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: my-route
namespace: my-service
spec:
hosts:
- "service.cluster.local"
http:
- match:
- headers:
specific-id:
regex: ^(1|3|9)$
route:
- destination:
host: "service.cluster.local"
subset: s-03
weight: 50
- destination:
host: "service.cluster.local"
subset: s-05
weight: 50
- match:
- headers:
specific-id:
regex: ^(2|10)$
route:
- destination:
host: "service.cluster.local"
subset: s-03
- match:
- headers:
specific-id:
regex: ^(5|7)$
route:
- destination:
host: "service.cluster.local"
subset: s-04
weight: 50
- destination:
host: "service.cluster.local"
subset: s-05
weight: 50
- match:
- headers:
specific-id:
regex: ^(4|6|8|)$
route:
- destination:
host: "service.cluster.local"
subset: s-04
This way You can have:
subset: s-03
that matches regex: ^(1|3|9)$ OR ^(2|10)$
subset: s-04
that matches regex: ^(5|7)$ OR ^(4|6|8|)$
subset: s-05
that matches regex: ^(1|3|9)$ OR ^(5|7)$
Where traffic for regex:
^(1|3|9)$
is split evenly between subset: s-03
and subset: s-05
.
^(5|7)$
is split evenly between subset: s-04
and subset: s-05
.
After deployment of the new schema with new rules, when istio will apply it? Does istio guarantee that it won't be applied (to not remove old rules) before all of my new instances will be ready for traffic?
Istio uses envoy for routing and Envoy documentation has the following statement:
Service discovery and dynamic configuration: Envoy optionally consumes a layered set of dynamic configuration APIs for centralized management. The layers provide an Envoy with dynamic updates about: hosts within a backend cluster, the backend clusters themselves, HTTP routing, listening sockets, and cryptographic material. For a simpler deployment, backend host discovery can be done through DNS resolution (or even skipped entirely), with the further layers replaced by static config files.
So as soon as istio object modifies the envoy dynamic configuration, it pushes its changes to envoy proxy. Yes envoy will make sure that new instances will be ready for traffic and drain the old traffic gracefully before shutting down.
More info: Runtime configuration, Hot restart
Hope this helps.
Upvotes: 1