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:
- 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: 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:
- The first route matches traffic on
reviews.ns1.svc.cluster.local:8080/reviews
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/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.
Field | Description | Validation Rule |
---|---|---|
canary | string | string = { |
namespace | string | string = { |
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.
Field | Description | Validation Rule |
---|---|---|
delay | tetrateio.api.tsb.traffic.v2.HTTPFaultInjection.Delay | – |
abort | tetrateio.api.tsb.traffic.v2.HTTPFaultInjection.Abort | – |
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.
Field | Description | Validation Rule |
---|---|---|
percentage | double | double = { |
httpStatus | int32 oneof _error_type | – |
grpcStatus | string oneof _error_type | – |
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.
Field | Description | Validation Rule |
---|---|---|
percentage | double | double = { |
fixedDelay | google.protobuf.Duration oneof _http_delay_type | duration = { |
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 = { |
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.
Field | Description | Validation Rule |
---|---|---|
host | string | – |
subset | string | – |
port | uint32 | uint32 = { |
percentage | double | double = { |
HTTPRoute
HTTPRoute describes match conditions and actions for HTTP traffic routing to service destinations.
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 | – |
flagger | tetrateio.api.tsb.traffic.v2.FlaggerDestination | – |
fault | tetrateio.api.tsb.traffic.v2.HTTPFaultInjection | – |
mirrors | List of tetrateio.api.tsb.traffic.v2.HTTPMirror | – |
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 | – |
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 | – |
configGenerationMetadata | tetrateio.api.tsb.types.v2.ConfigGenerationMetadata | – |
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 oneof _hash_key | string = { |
cookie | tetrateio.api.tsb.traffic.v2.ServiceRoute.StickySession.HTTPCookie oneof _hash_key | – |
useSourceIp | – |
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 | – |
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 | – |
TrafficType
TrafficType is the list of allowed traffic types for generating routes
Field | 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 |