You can use Traffic Management policies in Tanzu Service Mesh to perform weight-based Traffic Splitting and Request Routing based on HTTP(s) parameters (path, headers, and query parameters). The Traffic Management policies enable a variety of use cases including graceful traffic shifting techniques such as blue/green deployment, canary deployment, and A/B testing. For example, deploying a new version of a service is typically risky when you expose 100% of traffic to the new version even if it has passed the tests in staging. Using Traffic Management, you can define weight-based traffic splitting across multiple versions. This topic describes examples of how to create Traffic Management policies using the Tanzu Service Mesh API.

Note:

For a brief summary of the endpoints and HTTP methods in Traffic Management API, refer to API Quick Reference on Traffic Management.

Prerequisites

Verify that the following prerequisites are met:

  • You have onboarded the clusters where your services are deployed. For this example, you must onboard at least one cluster. For more information about onboarding a cluster, see Onboard a Cluster to Tanzu Service Mesh.

  • Create a global namespace. For more information about creating a global namespace, see Create a Global Namespace.

  • You have an API token and an access code to authenticate your requests to the Tanzu Service Mesh API. You must use the access code in the csp-auth-token header in your requests. For information about generating an API token and getting an access code, see Authentication with the Tanzu Service Mesh REST API.

  • Your deployments must have a "version" label (for example, "version": "reviews-v2") that uniquely identifies each version. In your traffic routing policies, the "version" values will be used to target specific versions. Below is an example spec:

    apiVersion: apps/v1
    kind: Deployment
    metadata: 
      name: reviews-v1 
      labels: 
        app: reviews 
        version: reviews-v1
    spec: 
      selector: 
        matchLabels: 
          app: reviews 
          version: reviews-v1 
      template: 
        metadata: 
          labels: 
          app: reviews 
          version: reviews-v1 
        spec:
          ... 
          ...

Request to Create or Update a Traffic Management Policy

Submit the following PUT request to create the traffic management policy named "tm-policy1" in Global Namespace "gns1" with ProjectId "default". You can update the Traffic Management policies at anytime by varying the parameter values. For more details on path parameters, refer to API Quick Reference.

PUT https://{server_name}/tsm/v1alpha2/project/default/global-namespaces/gns1/traffic-routing-policies/tm-policy1
Attention:

Use projectIdvalue as "default" since it is the only project that is currently supported.

The traffic management policies are of following capabilites:

Traffic Splitting

  • Weight-based traffic splitting

Request Routing

  • Header-based request routing

  • Query parameters-based request routing

  • Path-based request routing

Weight-based Traffic Splitting Policy

Traffic splitting is a method of distributing traffic to different versions of your service. It is possible to split traffic to forward 100% of traffic to a single version or to forward percentages of traffic to multiple versions. Define values for weight property to create percentage-based traffic splits across multiple versions. For example, 90% of the traffic can be sent to version 2 and the remaining 10% to version 3. If only service versions are mentioned without defining values for weight in the target, then the traffic is distributed evenly among all the versions in round robin fashion.

Important:

The percentage weights of all target routes must sum to exactly 100 or 0.

Use the following properties in the request body. In the following example, reviews is the service, while reviews-v2 and reviews-v3 are the versions. The traffic splits between versions v2 and v3 in 90-10 percentage.

{
  "description": "policy to split 90% of traffic to version 2 and 10% of    traffic to version 3",
  "service": "reviews",
  "traffic_policy": {
    "http": [
      {
        "targets": [
          {
            "service_version": "reviews-v2",
            "weight": 90
          },
          {
            "service_version": "reviews-v3",
            "weight": 10
          }
        ]
      }
    ]
  }
}

Overview of Request Routing

In request routing, traffic is dynamically routed to multiple versions of a service using a routing rule. The routing rule contains one or more match conditions and the destination to which traffic should be routed when those conditions match. Routing rules are evaluated sequentially from top to bottom, with the first rule having the highest priority. If you want anything that does not match the first routing rule to go to a default destination, do not specify any match conditions in the last rule.

Important:

Match types can either be Exact, Prefix, or Regex.

Match Type

Description

Exact

Property needs to be an exact match to the provided value. For example, Exact: Jason will only match if the property value is "Jason". It will not match even if the value is "JASON" or "jason".

Prefix

Only prefix of the property will get matched. For example, prefix: Jason will match if the value is "JasonWood" or "Jason".

Regex

The value will get matched based on the regex. For example, regex: '.*Jason.*' will match if the value is "Author Jason Wood".

Attention:

In the forthcoming examples of request routing policies, the first routing rule has a condition and starts with the matches field. The last rule is a default "no condition", which means that any requests that don't match the first routing rule will be routed to the default destination (in the examples below, it is the v2 version).

a) Header-based Request Routing Policy

Define the key-value pair for headers property in request body to route traffic based on the macthing condition on header. For example, if a request comes with end-user: Jason in the request header, traffic is routed to version 3, and the rest of the traffic to version 2 by default.

Use the following properties in the request body.

{
  "description": "policy to route traffic that comes with end-user: Jason in header to version 3",
  "service": "reviews",
  "traffic_policy": {
    "http": [
      {
        "name": "user-based",
        "matches": [
          {
            "headers": {
              "type": "Exact",
              "value": [
                {
                  "k": "end-user",
                  "v": "Jason"
                }
              ]
            }
          }
        ],
        "targets": [
          {
            "service_version": "reviews-v3"
          }
        ]
      },
      {
        "targets": [
          {
            "service_version": "reviews-v2"
          }
        ]
      }
    ]
  }
}

b) Query parameters-based Request Routing Policy

Define the key-value pair for queryParams property in request body to route traffic based on the matching condition on query parameter. The match rule evaluates the incoming request based on the HTTP(S) query parameter. For example, if a request contains app-id: 1 in the queryParams, traffic is routed to version 3, and the rest of the traffic to version 2 by default.

Use the following properties in the request body. In the following example, k is the key (app-id), v is the value (1), and value [] is an array of key-value pairs.

{
  "description": "policy to route traffic that comes with request  app-id-user: 1 in query parameter to version 3",
  "service": "reviews",
  "traffic_policy": {
    "http": [
      {
        "name": "user-based",
        "matches": [
          {
            "queryParams": {
              "type": "Exact",
              "value": [
                {
                  "k": "app-id",
                  "v": "1"
                }
              ]
            }
          }
        ],
        "targets": [
          {
            "service_version": "reviews-v3"
          }
        ]
      },
      {
        "targets": [
          {
            "service_version": "reviews-v2"
          }
        ]
      }
    ]
  }
}

c) Path-based Request Routing Policy

Define the key-value pair for path property in request body to route traffic based on the matching condition on path. Path rules are evaluated on the the longest-path-matches-first basis, and they can be specified in any order. Once the most specific match is found, the traffic is routed to the corresponding version. If no match is found, the default version is used. For example, if a request has /review/5 in the path, traffic is routed to version 3, and the rest of the traffic to version 2 by default.

Use the following properties in the request body.

{
  "description": "policy to route traffic that comes with path: /review/5   request to v3",
  "service": "reviews",
  "traffic_policy": {
     "http": [
       {
	 "name": "user-based",
	 "matches": [
           {
	    "path":   {
	    "type": "Exact",
	    "value": "/review/5"
                  }
	       }
             ],
	   "targets": [
             {
               "service_version": "reviews-v3"
              }
            ]
	},
	    {
	    "targets": [
             {
	       "service_version": "reviews-v2"
              }
           ]
         }
       ]
    }
}

Response Codes

If the traffic management policy was created successfully, the response header from the Tanzu Service Mesh REST API contains a status code of 200 Traffic Routing policy upserted. The operations that fail due to an error with the client request (for example, invalid input) will return 4xx codes.

Common 4xx error conditions include:

  • Submitted data was invalid (traffic routing policy is empty/null/undefined, GNS ID is empty or null, no routingRules specified, the weights do not add up to 100 or 0).

  • Some HTML attributes are ignored (for example, HTTP or TCP is not specified).

For more information about the typical error codes, see Response Codes.