In this blog, you will learn about the Kubernetes Ingress Gateway, the Gateway API, and the emerging Gateway API trend, which enables the convergence of Kubernetes and service mesh.
When Kubernetes was launched in June 2014, only NodePort and LoadBalancer-type Service objects were available to expose services within the cluster to the outside world. Later, Ingress was introduced to offer more control over incoming traffic.. To preserve its portability and lightweight design, the Ingress API matured more slowly than other Kubernetes APIs; it was not upgraded to GA until Kubernetes 1.19.
Ingress’ primary objective is to expose HTTP applications using a straightforward declarative syntax. When creating an Ingress or setting a default IngressClass in Kubernetes, you can deploy several Ingress Controllers and define the controller the gateway uses via IngressClass. Kubernetes currently supports only AWS, GCE, and Nginx Ingress controllers by default; many third-party ingress controllers are also supported.
The following diagram illustrates the workflow of Kubernetes Ingress.
The detailed process is as follows:
Istio supports both the Ingress and Gateway APIs. Below is an example configuration using the Istio Ingress Gateway, which will be created later using the Gateway API:
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
name: istio
spec:
controller: istio.io/ingress-controller
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress
spec:
ingressClassName: istio
rules:
- host: httpbin.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: httpbin
port: 8000
Note: You must specify the IngressClass in the ingressClassName field in the Ingress spec. Otherwise, the ingress gateway will not be created.
Although IngressClass decouples the ingress gateway from the back-end implementation, it still has significant limitations.
The Gateway API is a collection of API resources: GatewayClass, Gateway, HTTPRoute, TCPRoute, ReferenceGrant, etc. The Gateway API exposes a more generic proxy API that can be used for more protocols than HTTP and models more infrastructure components, providing better deployment and management options for cluster operations.
In addition, the Gateway API achieves configuration decoupling by separating resource objects that people can manage in different roles. The following diagram shows the roles and objects in the Gateway API.
The following is an example of using the Gateway API in Istio.
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: Gateway
metadata:
name: gateway
namespace: istio-ingress
spec:
gatewayClassName: istio
listeners:
- name: default
hostname: "*.example.com"
port: 80
protocol: HTTP
allowedRoutes:
namespaces:
from: All
---
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: HTTPRoute
metadata:
name: http
namespace: default
spec:
parentRefs:
- name: gateway
namespace: istio-ingress
hostnames: ["httpbin.example.com"]
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: httpbin
port: 8000
Similar to Ingress, Gateway uses gatewayClassName to declare the controller it uses, which needs to be created by the platform administrator and allows client requests for the *.example.com domain. Application developers can create routing rules in the namespace where their service resides, in this case, default, and bind to the Gateway via parentRefs, but only if the Gateway explicitly allows them to do so (via the rules set in the allowRoutes field).
When you apply the above configuration, Istio will automatically create a load-balancing gateway for you. The following diagram shows the workflow of the Gateway API.
The detailed process is as follows:
From the above steps, we can see that the Gateway API has a clear division of roles compared to Ingress and that routing rules can be decoupled from the gateway configuration, significantly increasing management flexibility.
The following diagram shows the route flow after it is accessed at the gateway and processed.
From this figure, we can see that the route is bound to the gateway. The route is generally deployed in the same namespace as its backend services. Suppose the route is in a different namespace, and you need to explicitly give the route cross-namespace reference rights in ReferenceGrant
, for example. In that case, the following HTTPRoute foo in the foo namespace can refer to the bar namespace bar service in the bar namespace.
kind: HTTPRoute
metadata:
name: foo
namespace: foo
spec:
rules:
- matches:
- path: /bar
forwardTo:
backend:
- name: bar
namespace: bar
---
kind: ReferenceGrant
metadata:
name: bar
namespace: bar
spec:
from:
- group: networking.gateway.k8s.io
kind: HTTPRoute
namespace: foo
to:
- group: ""
kind: Service
Currently, the Gateway API only supports HTTPRoute, and the TCPRoute, UDPRoute, TLSRoute and GRCPRoute are still in the experimental stage. The Gateway API is already supported by a large number of gateway and service mesh projects, and please check the support status in the official Gateway documentation.
The service mesh focuses on east-west traffic, i.e., traffic within a Kubernetes cluster, but most service meshes, including Istio, also provide ingress gateway functionality. But, since Istio’s ingress functionality and API are more advanced than we need for this example, we’ll use Service Mesh Interface (SMI) to illustrate the relationship between the ingress gateway and the service mesh.
SMI is a CNCF incubation project, open-sourced in 2019, that defines a common standard for vendor-independent service mesh running in Kubernetes.
The following diagram illustrates the overlap between the Gateway API and the SMI.
From the diagram, we can see a clear overlap between the Gateway API and SMI in the traffic specification section. These overlaps result in the same functionality that needs to be implemented repeatedly in both the Gateway API and the service mesh.
Of course, not all service meshes are fully SMI-compliant. Istio, the most popular service mesh implementation, provides rich traffic management features but does not have a separate policy API for these features, instead coupling them in VirtualService and DestinationRule, as shown below.
Load balancing: setting up load balancing policies, such as simple load balancing, locality-aware load balancing, and area-weighted load balancing. Circuit Breaking: Outlier detection and connection pool settings to remove anomalous nodes from the load balancing pool.
VirtualService mainly handles routing-related functions, while DestinationRule is responsible for adding and ejecting nodes from the cluster and load balancing.
Gateway API Converging the Ingress Gateway from Kubernetes and Service Mesh
As mentioned above, there is a partial functional intersection between the Gateway API and the service mesh. To reduce duplication of development and enable the modeling of common concerns between the Gateway API and the service mesh, the Gateway API Working Group has proposed the Gateway API Mesh Management and Administration (GAMMA) initiative.
Under this initiative, advanced traffic management features that vary in detail across gateway implementations, such as timeouts, retries, health checks, etc., will all be implemented by individual providers through policy attachment. You can specify the resource object to which the policy attachment is attached via the targetRef field, as shown below.
apiVersion: networking.acme.io/v1alpha1
kind: RetryPolicy
metadata:
name: foo
spec:
override:
maxRetries: 10
default:
maxRetries: 5
targetRef:
group: gateway.networking.k8s.io/v1alpha2
kind: HTTPRoute
name: foo
In this example, the retry policy is attached to a resource named foo and HTTPRoute. Policy attachments are connected to different resource objects with varying priorities for effectiveness. For instance, GatewayClass is a cluster-level resource and will take precedence if the policy attachment is overlaid on it.
You can assign override and default values to additional policies whose priority in the ingress and the different resources in the mesh hierarchy are shown in the figure below.
Currently, the Gateway API is being explored to handle mesh traffic, and several design options have been proposed.
The first open-source version of Envoy Gateway, v0.2, was released in October 2022. It was created based on the Envoy proxy’s compliance with the Gateway API, of which Tetrate is a core sponsor. Its expressive, scalable, role-oriented API design through ingress and L4/L7 traffic routing makes it the foundation for vendors to build value-added API gateway products.
Long before Envoy Gateway was released, Envoy was massively adopted as one of the most popular cloud-native proxies, with several Gateway software builds based on Envoy, and the Istio service mesh used it as the default sidecar proxy and configured these distributed proxies via the xDS protocol. Envoy Gateway also uses xDS to configure the Envoy fleet. The following diagram illustrates the architecture of Envoy Gateway.
The infrastructure provider will provide you with GatewayGlass. You can create an Envoy Gateway by creating a Gateway declaration. Your routing and policy attachments in the Gateway will be sent to the Envoy fleet via the xDS protocol.
For further information about Envoy Gateway, please read
The Gateway API, as the next-generation Kubernetes Ingress API, provides a better degree of API specification for Kubernetes gateway providers as opposed to the Ingress API before, enriching the functionality of the ingress gateway while ensuring its portability and facilitating the management of gateways by different stakeholders through the separation of concerns. Finally, the GAMMA initiative is promoting the integration of the Ingress Gateway with the Gateway API for service mesh, and policy attachments may further extend the functionality of the Gateway API to east-west gateways.
This blog was originally published at tetrate.io.
Last updated on Nov 7, 2024