Explore the mechanics of the Gateway API within the Service Mesh
A few days ago, the Gateway API announced support for service mesh in version 0.8.0, signifying fresh developments in the GAMMA (Gateway API for Mesh Management and Administration) initiative, albeit currently at an experimental stage. Last June, when Gateway API released version 0.5.0, I penned an article exploring What does the GAMMA Initiative mean for SMI and the Gateway API?(in Chinese). As it stands, several months have elapsed since the annual review of SMI as a sandbox project without a submission, which is rather poignant.
Without further ado, let us delve into how the Gateway API operates within the Service Mesh in version 0.8.0.
TL;DR
The Gateway API’s support for the service mesh remains experimental, yet vendors are already making advancements (albeit still in the experimental phase).
Compared to the Gateway API handling north-south traffic by binding the route to the Gateway resource, routing within the mesh instead binds with the Service, essentially acting as a proxy for the Gateway, albeit with the targeted Service.
Service Mesh in the Gateway API
To discuss the service mesh, we must first examine the concept of Service
.
Abstract Service
In Kubernetes, Service
is an autonomous resource. Here, the abstraction refers to a logical division into two separate entities: the frontend and the backend.
The frontend generally encompasses the DNS name or ClusterIP
of the Service
, while the backend is constituted by Endpoint
or EndpointSlice
selected through label selectors.
Routing and Service
Directly binding the route to the Service is considered the optimal choice at present. Despite the high degree of coupling between the Service
and other resources, such as IP allocation, DNS, endpoint collection, load balancing, etc., it remains the solitary optimal choice in the current mesh design. Future endeavors will seek superior options, like ServiceBinding
(discussed later).
This approach bears the advantage of associating the service’s frontend and backend with the existing xRoute
API's parentRef
and backendRef
respectively, negating the necessity for introducing additional APIs.
At different instances, the backendRef
in the xRoute
API can also represent a Service
, but ultimately, when routing requests, the target remains Endpoint
or EndpointSlice
, albeit not strongly associated with the Service
in parentRef
.
kind: HTTPRoute
metadata:
name: smiley-route
namespace: faces
spec:
parentRefs:
- name: smiley
kind: Service
group: core
port: 80
rules:
...
If multiple routes are configured on a single Service, requests that match multiple routes will be rejected.
Request Process
- The client initiates a request.
- The mesh data plane proxy intercepts the request:
- If the
Service
has not configured a route, it forwards the request to the original destination. - Identifies and forwards the request to the highest priority matching route (consumer routes take precedence over producer routes, discussed below).
- If routes have been configured but none can be matched, the request is rejected.
Namespace of the Route
The need to discuss namespaces arises because the implications represented by routes and services vary under the same or different namespaces.
Same Namespace
The smiley-route
and the Service smiley
reside within the same namespace faces
, with a request timeout setting of 100ms
configured on the route. This signifies that all requests accessing the smiley
Service (from any workload in any namespace) that match the smiley-route
routing rules will be affected by this timeout configuration.
This type of route is referred to as a Producer Route, influencing all requests targeting this service.
kind: HTTPRoute
metadata:
name: smiley-route
namespace: faces
spec:
parentRefs:
- name: smiley
namespace: faces
kind: Service
group: core
port: 80
rules:
...
timeouts:
request: 100ms
Different Namespace
The route smiley-route
and the Service smiley
exist in separate namespaces. Differing from the aforementioned scenario, all requests accessing the smiley
Service (from any workload within the fast-clients
namespace) that adhere to the smiley-route
routing rules are influenced by this timeout setting.
This route is known as a Consumer Route, affecting all requests accessing the carved services within the same namespace.
kind: HTTPRoute
metadata:
name: smiley-route
namespace: fast-clients
spec:
parentRefs:
- name: smiley
namespace: faces
kind: Service
group: core
port: 80
rules:
...
timeouts:
request: 100ms
Multiple Routes on a Single Service
The precondition here is that these routes all reside within the same namespace, namely, either all as producer routes or all as consumer routes. This scenario will adhere to the route merging rules, merging multiple routes. Currently, it’s unfeasible to configure distinct consumer routes for multiple workloads within the same namespace. The only
For instance, the following defines two consumer routes, smiley-route-50
and smiley-route-100
.
kind: HTTPRoute
metadata:
name: smiley-route-50
namespace: fast-clients
spec:
parentRefs:
- name: smiley
namespace: faces
kind: Service
group: core
port: 80
rules:
...
timeouts:
request: 50ms
---
kind: HTTPRoute
metadata:
name: smiley-route-100
namespace: fast-clients
spec:
parentRefs:
- name: smiley
namespace: faces
kind: Service
group: core
port: 80
rules:
...
timeouts:
request: 100ms
Routes and Policies
I had previously written an article introducing policies in the Gateway API. If interested, you can read Understand Kubernetes Gateway API Policy Attachment in One Article.
Attaching policies within the mesh can be quite straightforward. Policies can be applied to any resource in any namespace. However, if the target resides in a different namespace, it can only apply to requests coming from the same namespace (following the logic of consumer routes).
Mesh Conformance Testing
First, let’s look at what a conformance profile is:
The Gateway API will provide profiles for conformance testing, and one can choose these profiles while running the conformance tests. Subsequently, the conformance results are reported back to the Gateway API project for certification, such as badges. In addition to testing core functionalities, one can also voluntarily add extensions from vendor-specific implementations for testing.
These implementations of the Gateway API will submit the test reports to the official repository’s conformance test report directory, which can serve as one of the references when people are choosing which one to use.
Currently, there are HTTP
, TLS
, TLSPassthrough
(mostly organized according to xRoute, so there will also be GRPC
, TCP
, UDP
in the future). Regarding service meshes, a mesh
profile has also been proposed.
The official blog mentioned that the Gateway API implementations in Kuma 2.3+, Linkerd 2.14+, and Istio 1.16+ have all passed the mesh
conformance tests. However, as of now, the test reports have not been seen, presumably, they are still being uploaded.