Introduction to request routing
By default, traffic addressed to a destination will be routed to that destination, with load balancing provided by ztunnel or the destination’s waypoint, if one is configured. Because the waypoint proxy sees the entire request as it passes, routing decisions can be made, similar to those that can be made when traffic enters the mesh through a gateway.
For example, you can:
- select a backend based on host, header or path fields (routing)
- direct a percentage of traffic to a different service as part of A/B testing or a “canary” deployment (traffic splitting)
- respond with an HTTP redirect (redirect/rewrite)
- apply a different load balancing policy to traffic for a particular set of service instances (destination rule)
You can also configure various rules relating to resilience:
- define timeouts and retries
- set limits for calls to individual hosts within a service, such as the number of concurrent connections or how many times calls to this host have failed
- mirror traffic from one destination to another
Route objects, gateways and waypoints
Routes are configured with the Gateway API.
Two main types of routes are available:
- HTTPRoute, the most commonly used route
- GRPCRoute, a version of HTTPRoute which supports matching on gRPC request service and/or method
A further two are in the Gateway API experimental channel, and require you to configure Istio to enable their use:
- TCPRoute, for managing TCP traffic
- TLSRoute, for managing TLS traffic
The same API is used to describe a route attached to a gateway, or a route for service mesh, which will be enacted by a waypoint. The primary difference is the parentRef
field, which is set to the name of the gateway in a north/south use case, is set to the name of a service in an east/west use case.
Using routes for gateways
When attaching a route to a gateway (sometimes referred to as an ingress route), set the parentRefs
field to the name of the Gateway
resource. Note that the target Gateway needs to allow HTTPRoutes from the route’s namespace to be attached for the attachment to be successful.
Here is a sample route that connects the specified paths to the productpage
service:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: bookinfo
spec:
parentRefs:
- name: bookinfo-gateway
rules:
- matches:
- path:
type: Exact
value: /productpage
- path:
type: PathPrefix
value: /static
- path:
type: Exact
value: /login
- path:
type: Exact
value: /logout
- path:
type: PathPrefix
value: /api/v1/products
backendRefs:
- name: productpage
port: 9080
Using routes for waypoints
Like with a gateway, a mesh route is attached to a service using the parentRefs
field. However:
kind
must be set toService
group
must be set to the empty string1.
Here is a sample route that takes traffic directed to the reviews
service, and directs 10% of it to reviews-v2
.
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: reviews
spec:
parentRefs:
- group: ""
kind: Service
name: reviews
port: 9080
rules:
- backendRefs:
- name: reviews-v1
port: 9080
weight: 90
- name: reviews-v2
port: 9080
weight: 10
Consideration when writing routes
Be aware of some differences in how you write a HTTPRoute for use with a gateway vs. to use within the mesh:
- As above, gateway routes are attached with a
parentRef
naming the gateway, and mesh routes are attached with aparentRef
naming the service. - The
hostname
field has no effect in a mesh route. - When one or more mesh routes are attached to a service, requests that do not match at least one rule in one of the routes will be rejected. If you wish to only act on certain traffic to a service (for example, rewriting based on matching a path prefix) you probably want to pass the rest of the traffic through as before, which you can achieve by having a second rule with a
backendRefs
field and nomatches
field.
-
This is to imply the “core” group, as opposed to the default
gateway.networking.k8s.io
group used when referencing Gateway objects. ↩︎