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 g1
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: g1
workspace: w1
tenant: mycompany
organization: myorg
spec:
service: ns1/reviews.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:
- 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
. - 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: g1
workspace: w1
tenant: mycompany
organization: myorg
spec:
service: ns1/reviews.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.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.
The ServiceRoute below has two HTTP routes:
- The first route matches traffic on
reviews.svc.cluster.local:8080/productpage
endpoint andend-user: jason
header and routes 80% of traffic to subset "v1" and 20% to subset "v2". - The second route is the default HTTP route, which matches traffic on
reviews.ns1.svc.cluster.local:8080/productpage
endpoint, and routes 50% of traffic to subset "v1" and remaining 50% to subset "v2".
apiVersion: traffic.xcp.tetrate.io/v2
kind: ServiceRoute
metadata:
name: reviews
group: t1
workspace: w1
tenant: mycompany
organization: myorg
spec:
service: ns1/reviews.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-productpage-endpoint
match:
- name: match-productpage-endpoint
uri:
prefix: /productpage
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: /productpage
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 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.xcp.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
Finally, a similar example but for TCP traffic where all the traffic for port 666 will be sent to 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
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.
Field | Description | Validation Rule |
name | string | string = { |
uri | tetrateio.api.tsb.gateway.v2.StringMatch | – |
headers | map<string, tetrateio.api.tsb.gateway.v2.StringMatch> | |
port | uint32 | uint32 = { |
HTTPRoute
HTTPRoute is used to set HTTP routes to service destinations on the basis of match conditions.
Field | Description | Validation Rule |
name | string | string = { |
match | List of tetrateio.api.tsb.traffic.v2.HTTPMatchCondition | – |
destination | List of tetrateio.api.tsb.traffic.v2.ServiceDestination | – |
ServiceDestination
ServiceDestination is the destination service, port and subset where traffic should be routed
Field | Description | Validation Rule |
subset | string | – |
weight | uint32 | – |
port | uint32 | uint32 = { |
destinationHost | string | – |
ServiceRoute
A service route controls routing configurations for traffic to a service in a traffic group.
Field | Description | Validation Rule |
service | string | string = { |
subsets | List of tetrateio.api.tsb.traffic.v2.ServiceRoute.Subset | repeated = { |
stickySession | tetrateio.api.tsb.traffic.v2.ServiceRoute.StickySession | – |
portLevelSettings | List of tetrateio.api.tsb.traffic.v2.ServiceRoute.PortLevelTrafficSettings | – |
httpRoutes | List of tetrateio.api.tsb.traffic.v2.HTTPRoute | – |
tcpRoutes | List of tetrateio.api.tsb.traffic.v2.TCPRoute | – |
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:
- 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.
- 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.
Field | Description | Validation Rule |
port | uint32 | uint32 = { |
trafficType | tetrateio.api.tsb.traffic.v2.ServiceRoute.TrafficType | enum = { |
stickySession | tetrateio.api.tsb.traffic.v2.ServiceRoute.StickySession | – |
StickySession
If set, all requests from a client will be forward to the same backend.
Field | Description | Validation Rule |
header | string | string = { |
cookie | tetrateio.api.tsb.traffic.v2.ServiceRoute.StickySession.HTTPCookie | – |
useSourceIp | bool | – |
HTTPCookie
Describes a HTTP cookie that will be used for sticky sessions. If the cookie is not present, it will be generated.
Field | Description | Validation Rule |
name | string | string = { |
path | string | string = { |
ttl | google.protobuf.Duration | timestamp = { |
Subset
Subset denotes a specific version of a service. The pods/VMs of a subset should be uniquely identifiable using their labels.
Field | Description | Validation Rule |
name | string | string = { |
labels | map<string, string> | |
weight | uint32 | – |
portLevelSettings | List of tetrateio.api.tsb.traffic.v2.ServiceRoute.PortLevelTrafficSettings | – |
TrafficType
TrafficType is the list of allowed traffic types for generating routes
Name | Number | Description |
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 |
TCPMatchCondition
TCPMatchCondition is the set of conditions to match incoming TCP traffic and route accordingly
Field | Description | Validation Rule |
name | string | string = { |
port | uint32 | uint32 = { |
TCPRoute
TCPRoute is used to set TCP routes to service destinations on the basis of match conditions.
Field | Description | Validation Rule |
name | string | string = { |
match | List of tetrateio.api.tsb.traffic.v2.TCPMatchCondition | – |
destination | List of tetrateio.api.tsb.traffic.v2.ServiceDestination | – |