With Istio, a lot of tools are available to help us to easily set routing rules. And today, we will use them to set a routing rule to be able to use two versions of the same app.
Prerequisite
First we need to be able to distinct both version of the app.
Distinct services
If both version of the app has a specific service to expose it, it's ok we can go further.
Same service
Otherwise, if they are using the same service, we need to add something to be able to distinct them.
Here, we will use a Destination Rule. With it, we will say that for our service (here defined in the host element), we have multiple subgroups (subnets).
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: my-api
spec:
host: my-api.default.svc.cluster.local
trafficPolicy:
loadBalancer:
simple: ROUND_ROBIN
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
In this example, we have 2 subgroups:
- v1 with are all the pods of my-api with the label version: v1
- v2 with are all the pods of my-api with the label version: v2
Definition of the routing rule
Now that we are able to distinct our versions, we can define the routing rule with a VirtualService.
URI
First, we can create the rule to redirect traffic depending the URI.
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: my-api
namespace: default
spec:
hosts:
- my-api.default.svc.cluster.local
http:
- match:
- uri:
prefix: "/v1"
route:
- destination:
host: my-api.default.svc.cluster.local
subnet: v1
- route:
- destination:
host: my-api.default.svc.cluster.local
subnet: v2
In this example, if the uri starts with "/v1" the traffic is redirected to the subnet v1. Otherwise, it goes to the v2.
IMPORTANT: The subnets values here must match to the subnets names defined in the DestinationRule.
Header
Then, we can update the VirtualService to change the condition and use a header instead.
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: my-api
namespace: default
spec:
hosts:
- my-api.default.svc.cluster.local
http:
- match:
- headers:
version:
exact: V1
route:
- destination:
host: my-api.default.svc.cluster.local
subnet: v1
- route:
- destination:
host: my-api.default.svc.cluster.local
subnet: v2
With just this little change, we can redirect traffic to the v1 subnet with only a header.
Links
- Istio - DestinationRule : https://istio.io/v1.1/docs/reference/config/networking/v1alpha3/destination-rule/
- Istio - VirtualService : https://istio.io/v1.1/docs/reference/config/networking/v1alpha3/virtual-service/
- Istio - Example of a request routing : https://istio.io/latest/docs/tasks/traffic-management/request-routing/
If you want to go further, all the links are here to see all the options available as :
- use an exact uri
- use a regex for the uri
- use a regex for the header
- add some retries
- ...
I hope you enjoyed it and it will be helpful! 🍺
Top comments (0)