Before modifying any of the routes, a default route must be set to just v1 of the Hello World service deployment. Otherwise, the round robin between v1 and v2 of the service deployment will continue.
-
Set the default version for all requests to the Hello World service.
istioctl create -f guestbook/route-rule-force-hello-v1.yaml
This Ingress rule forces
v1of the service by giving it a weight of 100. We can see this by describing the resource we created:kubectl describe routerules helloworld-default Name: helloworld-default Namespace: default Labels: <none> Annotations: <none> API Version: config.istio.io/v1alpha2 Kind: RouteRule Metadata: ... Spec: Destination: Name: helloworld-service Precedence: 1 Route: Labels: Version: 1.0
-
Now when you curl the echo service, it should always return
v1of the Hello World service.curl http://$INGRESS_IP/echo/universe {"greeting":{"hostname":"helloworld-service-v1-286408581-9204h","greeting":"Hello universe from helloworld-service-v1-286408581-9204h with 1.0","version":"1.0"},"
curl http://$INGRESS_IP/echo/universe {"greeting":{"hostname":"helloworld-service-v1-286408581-9204h","greeting":"Hello universe from helloworld-service-v1-286408581-9204h with 1.0","version":"1.0"},"
-
Clean up
istioctl delete -f guestbook/route-rule-force-hello-v1.yaml
Currently the routing rule only routes to v1 of the Hello World service. What we want to do is canary a deployment of v2 of the Hello World service by allowing only a small amount of traffic to it. This can be done by creating another rule with a higher precedence that routes some of the traffic to v2. We'll canary based on HTTP headers: if the user-agent is "mobile", it will go to v2; otherwise, requests will go to v1. Written as a route rule, this looks like:
destination:
name: helloworld-service
match:
request:
headers:
user-agent:
exact: mobile
precedence: 2
route:
- labels:
version: "2.0"Note that rules with a higher precedence number are applied first. If a precedence is not specified, then it defaults to 0. So with these two rules in place, the one with precedence 2 will be applied before the rule with precedence 1.
-
Test this out by creating the canary rule.
istioctl create -f guestbook/route-rule-canary.yaml
-
Now when you curl the end point, set the user agent to be mobile. You should only see
v2.curl http://$INGRESS_IP/echo/universe -A mobile {"greeting":{"hostname":"helloworld-service-v2-3297856697-6m4bp","greeting":"Hola world from helloworld-service-v2-1131997838-qnwcm version 2.0","version":"2.0"}
Without the user agent being set to mobile, you should still only see
v1:$ curl http://$INGRESS_IP/echo/universe {"greeting":{"hostname":"helloworld-service-v1-286408581-9204h","greeting":"Hello universe from helloworld-service-v1-286408581-9204h with 1.0","version":"1.0"},"
Note that the user-agent HTTP header is propagated in the span baggage. Check out these two classes for details on how the header is injected and extracted.
It is also possible to route based on the web browser used. For example, the following rule routes to v2 if the browser is Chrome:
match:
request:
headers:
user-agent:
regex: ".*Chrome.*"
route:
- labels:
version: "2.0"-
To apply this route rule, run:
istioctl create -f guestbook/route-rule-user-agent-chrome.yaml
-
Navigate to
http://$INGRESS_IP/echo/universein Chrome. You should see:Hola test from helloworld-service-v2-87744028-x20j0 version 2.0 -
Navigate to
http://$INGRESS_IP/echo/universein another browser. You should see:Hello sdsdffsd from helloworld-service-v1-4086392344-42q21 with 1.0