Routing Example

- By: Thomas Jungbauer ( Lastmod: 2021-08-14 )

In part 5 of the OpenShift 4 and Service Mesh tutorials, basic routing, using the objects VirtualService and DesitnationRule, are described. All operations have been successfully tested on OpenShift 4.3.

Some Theory

In this section another version of the recommendation microservice will be deployed. The traffic to the new version will be controlled with different settings of the VirtualService. Multiple scenarios can be realized with ServiceMesh. In general these are defined as follows ([1]):

Blue-Green Deployments

In a Blue-Green deployment the old version (green) is kept running, while a new version (blue) is deployed and tested. When testing is successful, the 100% of the traffic is switched to the new version. If there is any error, the traffic could be switched back to the green version.

A/B Deployments

A/B deployments, in difference to Blue-Green deployments, will enable you to try a new version of the application in a limited way in the production environment. It is possible to specify that the production version gets most of the user requests, while a limited number of requests is sent to the new version. This could be specified by location of the user for example, so that all users from Vienna are sent to the new version, while all others are still using the old version.

Canary Deployments

Canary releases can be used to allow a small, minimum amount of traffic to the new version of your application. This traffic can be increased gradually until all traffic is sent to the new version. If any issues are found, you can roll back and send the traffic to the old version.

Prerequisites

It is assumed that an OpenShift environment is up and running and that Issues #1 - #3 are done at least:

Prepare Simple Routing

OPTIONAL: Build the recommendation microservice

If you want to locally build the microservice, you must change the source code from version v1 to v2 the following way:

Open the file:

istio-tutorial/recommendation/java/vertx/src/main/java/com/redhat/developer/demos/recommendation/RecommendationVerticle.java

and change the following line from v1 to v2

private static final String RESPONSE_STRING_FORMAT = "recommendation v2 from '%s': %d\n";

Now you can build the image:

cd istio-tutorial/recommendation/java/vertx
mvn package
podman build -t example/recommendation:v2 . (1)
1 Note the v2 tag

Create second deployment with version2

A deployment with our recommendation:v2 microservice must be created. A service object must not be created this time, as it already exists.

cd ~/istio-tutorial/recommendation/
oc apply -f kubernetes/Deployment-v2.yml -n tutorial
oc get pods -w

If you want to diff v1 and v2 deployment, you will notice that the main change is the image which gets pulled.

diff recommendation/kubernetes/Deployment-v2.yml  recommendation/kubernetes/Deployment.yml
6,7c6,7
<     version: v2
<   name: recommendation-v2
---
>     version: v1
>   name: recommendation-v1
13c13
<       version: v2
---
>       version: v1
18c18
<         version: v2
---
>         version: v1
27c27
<         image: quay.io/rhdevelopers/istio-tutorial-recommendation:v2.1
---
>         image: quay.io/rhdevelopers/istio-tutorial-recommendation:v1.1

Call application

Execute the test command to access the application. Since no rules are defined yet, the traffic is split by 50% to version 1 and version 2 (round robin):

sh ~/run.sh 10 $GATEWAY_URL

# 0: customer => preference => recommendation v2 from '3cbba7a9cde5': 27
# 1: customer => preference => recommendation v1 from 'f11b097f1dd0': 27
# 2: customer => preference => recommendation v2 from '3cbba7a9cde5': 28
# 3: customer => preference => recommendation v1 from 'f11b097f1dd0': 28
...

In Kiali presents this as well:

Kiali v1 v2 trafficsplit1
Figure 1. Kiali sends 50% to v1 and v2

Send all traffic to recommendation:v2

To route the traffic accordingly a DestinationRule and a VirtualService must be created for recommendation. While the DesinationRule will add a name to each version, VirtualService specifies the actual destination of the traffic.

Define DestinationRule for recommendation

The object DestinationRule will define the versions in subsets.

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: recommendation
spec:
  host: recommendation
  subsets:
  - labels:
      version: v1
    name: version-v1
  - labels:
      version: v2
    name: version-v2

Create the object with the command: oc create -f <filename>

Define VirtualService for recommendation

The VirtualService defines that 100% (weight) of the traffic for recomendation (host) will be sent to the subset (version-v2), which is defined in the DefinationRule

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: recommendation
spec:
  hosts:
  - recommendation
  http:
  - route:
    - destination:
        host: recommendation
        subset: version-v2
      weight: 100

Create the object with the command: oc create -f <filename>

Call application

If you now call the application, only traffic to v2 should be shown:

sh ~/run.sh 1000 $GATEWAY_URL

# 0: customer => preference => recommendation v2 from '3cbba7a9cde5': 27
# 1: customer => preference => recommendation v1 from 'f11b097f1dd0': 27
# 2: customer => preference => recommendation v2 from '3cbba7a9cde5': 28
# 3: customer => preference => recommendation v1 from 'f11b097f1dd0': 28
...

In Kiali presents this as well and send 100% of the traffic to recommendation:v2:

Kiali 100 v2 trafficsplit2
Figure 2. Kiali sends 100% to v2