Skip to main content
logoTetrate Service BridgeVersion: next

Service Route

Service Routes can be used by service owners to configure traffic shifting across different versions of a service in a Traffic Group. The traffic to this service can originate from sidecars in the same or different traffic groups, as well as gateways.

The following example yaml defines a Traffic Group t1 in the namespaces ns1, ns2 and ns3, owned by its parent Workspace w1. Then it defines a Service Route for the reviews service in the ns1 namespace with two subsets: v1 and v2, where 80% of the traffic to the reviews service is sent to v1 while the remaining 20% is sent to v2.

apiVersion: traffic.tsb.tetrate.io/v2
kind: Group
metadata:
name: t1
workspace: w1
tenant: mycompany
organization: myorg
spec:
namespaceSelectors:
- name: "*/ns1"
- name: "*/ns2"
- name: "*/ns3"
configMode: BRIDGED
---
apiVersion: traffic.tsb.tetrate.io/v2
kind: ServiceRoute
metadata:
name: reviews
group: t1
workspace: w1
tenant: mycompany
organization: myorg
spec:
service: ns1/reviews.ns1.svc.cluster.local
subsets:
- name: v1
labels:
version: v1
weight: 80
- name: v2
labels:
version: v2
weight: 20

Server side load balancing can be set through the combination of portLevelSettings and stickySession. The following ServiceRoute will generate two routes:

  1. An HTTP route matching traffic on port 8080 and routing it 80:20 between v1:v2, targeting port 8080. The server side load balancing will be based on header.
  2. A TCP route matching traffic on port 443, and routing it 80:20 between v1:v2, targeting port 443. The server side load balancing will be based on source IP.
apiVersion: traffic.tsb.tetrate.io/v2
kind: ServiceRoute
metadata:
name: reviews
group: t1
workspace: w1
tenant: mycompany
organization: myorg
spec:
service: ns1/reviews.ns1.svc.cluster.local
portLevelSettings:
- port: 8080
trafficType: HTTP
stickySession:
header: x-session-hash
- port: 443
trafficType: TCP
stickySession:
useSourceIp: true
subsets:
- name: v1
labels:
version: v1
weight: 80
- name: v2
labels:
version: v2
weight: 20

Note: For TCP routes, only source IP (useSourceIp: true) is a valid load balancing hash key. Any other hash keys will be invalid.

You can also apply port settings just to a subset, such as in the following example where for subset v2 the source IP is used for sticky sessions.

apiVersion: traffic.tsb.tetrate.io/v2
kind: ServiceRoute
metadata:
name: reviews
group: t1
workspace: w1
tenant: mycompany
organization: myorg
spec:
service: ns1/reviews.ns1.svc.cluster.local
portLevelSettings:
- port: 8000
trafficType: TCP
- port: 443
trafficType: HTTP
stickySession:
header: x-sticky-hash
subsets:
- name: v1
labels:
version: v1
weight: 80
- name: v2
labels:
version: v2
weight: 20
portLevelSettings:
- port: 8000
trafficType: TCP
stickySession:
useSourceIp: true

If the service exposes more than one port, then all such ports with protocols need to be specified in top level portLevelSettings. Explicit routes can be specified within httpRoutes or tcpRoutes sections. You can also specify match conditions within each httpRoute to match the incoming traffic and route the traffic accordingly.

Service Routes can also be used to delegate traffic weighting to a Flagger Canary resource. First create the resource with delegation enabled in each cluster, for example:

apiVersion: flagger.app/v1beta1
kind: Canary
metadata:
name: reviews-canary
namespace: bookinfo
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: reviews
service:
port: 9080
delegation: true
analysis:
threshold: 5
maxWeight: 50
stepWeight: 10

Then the following ServiceRoute will delegate all traffic on port 9080 to the above Flagger Canary.

apiVersion: traffic.tsb.tetrate.io/v2
kind: ServiceRoute
metadata:
name: reviews-sr
group: t1
workspace: w1
tenant: mycompany
organization: myorg
spec:
service: bookinfo/reviews.bookinfo.svc.cluster.local
portLevelSettings:
- port: 9080
trafficType: HTTP
httpRoutes:
- name: reviews-flagger
match:
- name: port-9080
port: 9080
flagger:
canary: reviews-canary
namespace: bookinfo

The ServiceRoute below has two HTTP routes:

  1. The first route matches traffic on reviews.ns1.svc.cluster.local:8080/reviews endpoint and end-user: jason header and routes 80% of traffic to subset "v1" and 20% to subset "v2".
  2. The second route is the default HTTP route, which matches traffic on reviews.ns1.svc.cluster.local:8080/reviews endpoint, and routes 50% of traffic to subset "v1" and remaining 50% to subset "v2".
apiVersion: traffic.tsb.tetrate.io/v2
kind: ServiceRoute
metadata:
name: reviews
group: t1
workspace: w1
tenant: mycompany
organization: myorg
spec:
service: ns1/reviews.ns1.svc.cluster.local
portLevelSettings:
- port: 8080
trafficType: HTTP
subsets:
- name: v1
labels:
version: v1
weight: 80
- name: v2
labels:
version: v2
weight: 20
httpRoutes:
- name: http-route-match-reviews-endpoint
match:
- name: match-reviews-endpoint
uri:
prefix: /reviews
headers:
end-user:
exact: jason
port: 8080
destination:
- subset: v1
weight: 80
port: 8080
- subset: v2
weight: 20
port: 8080
- name: http-route-default
match:
- name: match-default
uri:
prefix: /reviews
port: 8080
destination:
- subset: v1
weight: 50
port: 8080
- subset: v2
weight: 50
port: 8080

Note: Default routes will be generated automatically only if a port is specified in top level portLevelSettings but not used in any match conditions of httpRoutes, tcpRoutes or tlsRoutes (or if no routes are specified). In all other conditions, all routes have to be defined explicitly.

For example, the ServiceRoute below will generate a default-http-route matching on port 8080 and will route traffic in the ratio 80:20 between v1:v2.

apiVersion: traffic.tsb.tetrate.io/v2
kind: ServiceRoute
metadata:
name: reviews
group: t1
workspace: w1
tenant: mycompany
organization: myorg
spec:
service: ns1/reviews.ns1.svc.cluster.local
portLevelSettings:
- port: 8080
trafficType: HTTP
subsets:
- name: v1
labels:
version: v1
weight: 80
- name: v2
labels:
version: v2
weight: 20

A similar example for TCP traffic where all the traffic for port 6666 will be sent to the v1 subset.

apiVersion: traffic.tsb.tetrate.io/v2
kind: ServiceRoute
metadata:
name: reviews
group: t1
workspace: w1
tenant: mycompany
organization: myorg
spec:
service: ns1/reviews.ns1.svc.cluster.local
portLevelSettings:
- port: 6666
trafficType: TCP
subsets:
- name: v1
labels:
version: v1
weight: 50
- name: v2
labels:
version: v2
weight: 50
tcpRoutes:
- name: tcp-route-match-port-6666-v1-100
match:
- name: match-condition-port-6666-v1-100
port: 6666
destination:
- subset: v1
weight: 100
port: 6666

For HTTP traffic routes, fault injection allows delaying or aborting requests, and traffic mirroring allows mirroring a percentage of the traffic to multiple different destinations.

In the next example, a Service Route defines a single HTTP route that matches traffic on the reviews service on port 8080, with a 80/20 weight for v1/v2 subsets. For the specific /reviews path and end-user: jason-chaos header, an HTTP Route is defined with a different subset where 100% of requests will go to v1, and have a the following fault injections:

  • 2 out of 100 requests will have a 5 second delay
  • 1 out of 1000 will return a 400 HTTP status code.

On top of that, for all the /reviews requests, 5 out of 1000 will be mirrored to the service debug-reviews.ns1.svc.cluster.local on port 8888.

apiVersion: traffic.tsb.tetrate.io/v2
kind: ServiceRoute
metadata:
name: reviews
group: t1
workspace: w1
tenant: mycompany
organization: myorg
spec:
service: ns1/reviews.ns1.svc.cluster.local
portLevelSettings:
- port: 8080
trafficType: HTTP
subsets:
- name: v1
labels:
version: v1
weight: 80
- name: v2
labels:
version: v2
weight: 20
httpRoutes:
- name: http-route-match-reviews-endpoint
match:
- name: match-reviews-endpoint
uri:
prefix: /reviews
headers:
end-user:
exact: jason-chaos
port: 8080
destination:
- subset: v1
port: 8080
fault:
delay:
percentage: 2
fixedDelay: 5s
abort:
percentage: 0.1
httpStatus: 400
mirrors:
- host: reviews.ns1.svc.cluster.local
subset: v2
port: 8080
percentage: 0.5

FlaggerDestination

FlaggerDestination will route traffic based on a Flagger Canary resource. The Canary resource must exist in the control plane cluster and have service delegation set to true.

FieldDescriptionValidation Rule

canary

string
REQUIRED
Name of the Canary resource that will manage the deployment.

string = {
  min_len: 1
}

namespace

string
REQUIRED
Namespace of the Canary resource that will manage the deployment.

string = {
  min_len: 1
}

HTTPFaultInjection

HTTPFaultInjection can be used to specify one or more faults to inject while forwarding HTTP requests to the destination specified in a route. Faults include aborting the HTTP request from downstream service, and/or delaying proxying of requests. A fault rule MUST HAVE delay or abort or both. Note that delay and abort faults are independent of one another, even if both are specified simultaneously.

FieldDescriptionValidation Rule

delay

tetrateio.api.tsb.traffic.v2.HTTPFaultInjection.Delay
Delay requests before forwarding, emulating various failures such as network issues, overloaded upstream service, etc.

abort

tetrateio.api.tsb.traffic.v2.HTTPFaultInjection.Abort
Abort HTTP request attempts and return error codes back to downstream service, giving the impression that the upstream service is faulty.

Abort

Abort specification is used to prematurely abort a request with a pre-specified error code. The httpStatus field is used to indicate the HTTP status code to return to the caller. The optional percentage field can be used to only abort a certain percentage of requests. If not specified, no request will be aborted.

FieldDescriptionValidation Rule

percentage

double
Percentage of requests to be aborted with the error code provided. If not specified, no request will be aborted.

double = {
  lte: 100
  gte: 0
}

httpStatus

int32 oneof _error_type
HTTP status code to use to abort the HTTP request.

grpcStatus

string oneof _error_type
GRPC status code to use to abort the request. The supported codes are documented in https://github.com/grpc/grpc/blob/master/doc/statuscodes.md

Delay

Delay specification is used to inject latency into the request forwarding path.

The fixedDelay field is used to indicate the amount of delay in seconds. The optional percentage field can be used to only delay a certain percentage of requests. If left unspecified, no request will be delayed.

FieldDescriptionValidation Rule

percentage

double
Percentage of requests on which the delay will be injected. If left unspecified, no request will be delayed.

double = {
  lte: 100
  gte: 0
}

fixedDelay

google.protobuf.Duration oneof _http_delay_type
Add a fixed delay before forwarding the request. Format: 1h/1m/1s/1ms. MUST be >=1ms.

duration = {
  gte: {nanos:1000000}
}

HTTPMatchCondition

HTTPMatchCondition is the set of conditions to match incoming HTTP traffic and route accordingly. We could have used HttpMatchCondition from ingress_gateway.proto but it doesn't have a port field, so it's better to create one natively.

FieldDescriptionValidation Rule

name

string
REQUIRED
Name of the match condition

string = {
  min_len: 1
}

uri

tetrateio.api.tsb.gateway.v2.StringMatch
Incoming URI to match in incoming traffic for routing forward

headers

map<string, tetrateio.api.tsb.gateway.v2.StringMatch>
Headers to match in incoming traffic for routing forward

port

uint32
Port to match in incoming traffic

uint32 = {
  lte: 65535
}

HTTPMirror

HTTPMirror can be used to specify the destinations to mirror HTTP traffic in addition to the original destination. Mirrored traffic is on a best effort basis where the sidecar/gateway will not wait for the mirrored destinations to respond before returning the response from the original destination.

FieldDescriptionValidation Rule

host

string
The host where traffic should be routed to. This should either be a FQDN or a short name for the k8s service. For example, "reviews" as destination_host will be interpreted as "reviews.ns1.cluster.local" If empty, the host will be inferred from the Service Route service field.

subset

string
Subset is the version of the service where traffic should be routed to

port

uint32
REQUIRED
The port corresponding to the service host where traffic should be routed

uint32 = {
  lte: 65535
  gte: 1
}

percentage

double
Percentage of the traffic to be mirrored. If this field is absent, the max value 100% will be mirrored.

double = {
  lte: 100
  gte: 0
}

HTTPRoute

HTTPRoute describes match conditions and actions for HTTP traffic routing to service destinations.

FieldDescriptionValidation Rule

name

string
REQUIRED
Name of the route.

string = {
  min_len: 1
}

match

List of tetrateio.api.tsb.traffic.v2.HTTPMatchCondition
Match conditions for incoming HTTP traffic

destination

List of tetrateio.api.tsb.traffic.v2.ServiceDestination
Destination host:port and subset where HTTP traffic should be directed. Note: Only one of destination and flagger must be configured per route.

flagger

tetrateio.api.tsb.traffic.v2.FlaggerDestination
FlaggerDestination will route traffic based on a Flagger Canary resource. Note: Only one of destination and flagger must be configured per route.

fault

tetrateio.api.tsb.traffic.v2.HTTPFaultInjection
Fault injection policy to apply on HTTP traffic at the client side. Note that timeouts or retries will not be enabled when faults are enabled on the client side.

mirrors

List of tetrateio.api.tsb.traffic.v2.HTTPMirror
Mirror HTTP traffic to multiple destinations in addition to forwarding the requests to the intended destination. Mirrored traffic is on a best effort basis, so it won't wait for the mirrored destinations response to respond to the intended destination.

ServiceDestination

ServiceDestination is the destination service, port and subset where traffic should be routed

FieldDescriptionValidation Rule

subset

string
Subset is the version of the service where traffic should be routed to

weight

uint32
Weight defines the amount of traffic that needs to be routed to this specific version

port

uint32
REQUIRED
The port corresponding to the service host where traffic should be routed

uint32 = {
  lte: 65535
  gte: 1
}

destinationHost

string
Service host where traffic should be routed to. This should either be a FQDN or a short name for the k8s service. For example, "reviews" as destination_host will be interpreted as "reviews.ns1.cluster.local" If empty, the host will be inferred from the Service Route service field.

ServiceRoute

A service route controls routing configurations for traffic to a service in a traffic group.

FieldDescriptionValidation Rule

service

string
REQUIRED
The service on which the configuration is being applied. Must be in namespace/FQDN format.

string = {
  pattern: ^[^/]+/[^/]+$
}

subsets

List of tetrateio.api.tsb.traffic.v2.ServiceRoute.Subset
The set of versions of a service and the percentage of traffic to send to each version.

stickySession

tetrateio.api.tsb.traffic.v2.ServiceRoute.StickySession
StickySession specifies how to forward traffic from a client to the same backend

portLevelSettings

List of tetrateio.api.tsb.traffic.v2.ServiceRoute.PortLevelTrafficSettings
In order to support multi-protocol routing, a list of all port/protocol combinations is needed. These port settings are applied to all the subsets

httpRoutes

List of tetrateio.api.tsb.traffic.v2.HTTPRoute
HTTPRoutes are used when HTTP traffic needs to be matched on uri, headers and port and destination routes need to be set using subset-weight combinations specified within the route. Note: If a route is specified, then the global subset-weight combinations (specified under subsets) will be ignored for the matched port, as subsets within route will take effect.

tcpRoutes

List of tetrateio.api.tsb.traffic.v2.TCPRoute
TCPRoutes match TCP traffic based on port number. The subset-weight configuration and priority have the same behaviour as HTTPRoutes.

configGenerationMetadata

tetrateio.api.tsb.types.v2.ConfigGenerationMetadata
Metadata values that will be add into the Istio generated configurations. When using YAML APIs like tctl or gitops, put them into the metadata.labels or metadata.annotations instead. This field is only necessary when using gRPC APIs directly.

PortLevelTrafficSettings

PortLevelTrafficSettings explicitly defines the type of traffic for all of the ports exposed by a service for which routing rules need to be set. Depending on whether HTTPRoutes or TCTRoutes are specified or not, the main subset weights are applied or not based on the following scenarios:

  1. If HTTPRoutes or TCPRoutes are specified: a. Since Port is mandatory in MatchConditions, whenever a port is used in (HTTP/TCP) MatchCondition, it needs to be present in the global PortLevelTrafficSettings. b. When MatchConditions are present in the routes, then subset-weight combinations within routes will take effect instead of the global ones.

  2. If the routes are not specified, then the traffic will be matched on ports specified in PortLevelTrafficSettings, and the routes will be set according to global subset-weight combinations.

FieldDescriptionValidation Rule

port

uint32
REQUIRED
Port number to which traffic must be routed

uint32 = {
  lte: 65535
  gte: 1
}

trafficType

tetrateio.api.tsb.traffic.v2.ServiceRoute.TrafficType
REQUIRED
Type of traffic for which a route has to be generated

enum = {
  defined_only: true
}

stickySession

tetrateio.api.tsb.traffic.v2.ServiceRoute.StickySession
Since we are supporting multiple types of protocols, so we expect to have separate sticky sessions for each route (i.e. for a specific port/protocol combination)

StickySession

If set, all requests from a client will be forward to the same backend.

FieldDescriptionValidation Rule

header

string oneof _hash_key
Hash based on a specific HTTP header.

string = {
  min_len: 1
}

cookie

tetrateio.api.tsb.traffic.v2.ServiceRoute.StickySession.HTTPCookie oneof _hash_key
Hash based on HTTP cookie.

useSourceIp

bool oneof _hash_key
Hash based on the source IP address.

HTTPCookie

Describes a HTTP cookie that will be used for sticky sessions. If the cookie is not present, it will be generated.

FieldDescriptionValidation Rule

name

string
REQUIRED
Name of the cookie.

string = {
  min_len: 1
}

path

string
REQUIRED
Path to set for the cookie.

string = {
  min_len: 1
}

ttl

google.protobuf.Duration
REQUIRED
Lifetime of the cookie.

timestamp = {
  required: true
}

Subset

Subset denotes a specific version of a service. The pods/VMs of a subset should be uniquely identifiable using their labels.

FieldDescriptionValidation Rule

name

string
REQUIRED
Name used to refer to the subset.

string = {
  min_len: 1
}

labels

map<string, string>
Labels apply a filter over the endpoints of a service in the service registry.

weight

uint32
Percentage of traffic to be sent to this subset. Weight if not specified will be assumed to be 0 if there are multiple subsets. If there is only one subset, the weight will be assumed to be 1.

portLevelSettings

List of tetrateio.api.tsb.traffic.v2.ServiceRoute.PortLevelTrafficSettings
Port/Protocol/StickySession combination for which routes need to be generated specifically for a subset. These settings are meant to override the global PortLevelTrafficSettings, i.e. first, global PortLevelTrafficSettings are used to generate routes and then we use non-conflicting subset level PortLevelTrafficSettings to modify existing routes. If provided, PortLevelTrafficSettings should be provided for all subsets for proper load balancing.

TCPMatchCondition

TCPMatchCondition is the set of conditions to match incoming TCP traffic and route accordingly

FieldDescriptionValidation Rule

name

string
REQUIRED
Name of the match condition

string = {
  min_len: 1
}

port

uint32
REQUIRED
TCP match conditions only have port in match conditions

uint32 = {
  lte: 65535
  gte: 1
}

TCPRoute

TCPRoute is used to set TCP routes to service destinations on the basis of match conditions.

FieldDescriptionValidation Rule

name

string
REQUIRED
Name of TCPRoute

string = {
  min_len: 1
}

match

List of tetrateio.api.tsb.traffic.v2.TCPMatchCondition
Match conditions for incoming TCP traffic

destination

List of tetrateio.api.tsb.traffic.v2.ServiceDestination
Destination host:port and subset where TCP traffic should be directed

TrafficType

TrafficType is the list of allowed traffic types for generating routes

FieldNumberDescription

HTTP

0

If trafficType is HTTP, then a HTTP route is generated for that port

TCP

1

If trafficType is TCP, then a TCP route is generated for that port

TLS_PASSTHROUGH

2

This mode generates TLS routes for HTTPS traffic. TLS is not terminated at the gateway and is passed through to the server