Kubernetes Ingress has been around for a while. It helps to expose services in the cluster to the external world and provides basic traffic routing functionalities. But for advanced networking features, DevOps and architects have to rely on vendors and their CRDs and custom annotations.
If you have ever written custom annotations on NGINX Ingress, you know how tedious the process is. Luckily, Kubernetes Gateway API is here to solve it and some other drawbacks with native Ingress.
What is Kubernetes Gateway API
Kubernetes Gateway API is a collection of resources that helps to standardize the specifications for implementing Gateway/Ingress rules in Kubernetes. Gateway API provides resources, such as GatewayClass, Gateway, and *Route, which are also role-delineated (see Fig. A).
Fig.A – Kubernetes Gateway API resources
Note that Gateway API only standardizes the specifications; for implementation, DevOps and architects will need an Ingress controller or a service mesh, like Envoy Gateway or Istio.
The resources help DevOps and architects to configure basic to advanced networking rules in Kubernetes without relying on vendor-specific CRDs and annotations. There are various implementors and integrators of K8s Gateway API.
Challenges of native Kubernetes Ingress
Kubernetes Gateway API is introduced to solve some pressing challenges with native Kubernetes Ingress:
- Limited functionality: Native K8s Ingress only provides basic load-balancing functionality. Advanced traffic routing capabilities, such as path-based routing, require DevOps folks to configure tedious custom annotations provided by their respective Ingress controller.
- Lack of standardization: Vendors providing Ingress controllers have their own annotation specifications. If DevOps has to switch Ingress controllers, they have a learning curve regarding vendor-specific CRDs and annotations. Besides, they will have to rewrite the current vendor’s specifications using the new ones. It takes a reasonable amount of time to write and test annotations before they can be implemented.
- Single Ingress resource: Usually, in an enterprise, there will be a single Ingress resource, and multiple teams will work on it. An admin will create multiple Ingress objects for various app teams at max, but it is still hard to implement role-based access controls on any object. If proper RBAC policies are not in place, teams may mess up the route configuration.
Gateway API not only solves the challenges at the Gateway/Ingress-level, it could also evolve to manage service-to-service/east-west traffic within the same cluster.
(We have compared Gateway API and Kubernetes Ingress based on 4 dimensions. Check it out here: Kubernetes Gateway API vs Kubernetes Ingress.)
Kubernetes Gateway API resources and the request flow
Kubernetes Gateway API provides the following resources that give freedom for IT teams to work on resources that fall under their respective roles:
GatewayClass (infra provider)
The resource specifies the controller that implements the Gateway API CRDs associated with the class in the cluster. The Gateway API implementation controller is specified using controllerName, which then manages the GatewayClass.
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: istio
spec:
controllerName: istio.io/gateway-controller
In the above sample configuration, GatewayClass(es) with the controllerName: istio.io/gateway-controller will be managed by the Istio service mesh.
Gateway (Cluster admin/Architect)
A Gateway resource acts as a network endpoint that gets the traffic inside the cluster, like a cloud load balancer. DevOps or Infra team can add multiple listeners to the external traffic and apply filters, TLS, and traffic forwarding rules. Gateway is attached to a GatewayClass and is implemented using the respective controller defined in GatewayClass.
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: k8s-gateway
namespace: k8s-gw
spec:
gatewayClassName: istio
listeners:
- name: default
port: 80
protocol: HTTP
allowedRoutes:
namespaces:
from: All
In the above Gateway resource, gatewayClassName refers to the respective GatewayClass the resource is attached to, and listeners specify that the Gateway listens to HTTP traffic on port 80.
*Route (Devs/DevOps)
Route resources manage the traffic from the Gateway to the back-end services. Multiple Route resources, such as HTTPRoute, TCPRoute, GRPCRoute, etc., are used to configure the routing rules of the respective traffic from a Gateway listener to a backend service. The app team can configure different path names and Header filters (under the rules section in the YAML) in the Route resources to handle the traffic to the backend. Each Route can be attached to a single or multiple Gateways as per the requirements, which can be specified under parentRefs.
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: k8s-http-route-with-istio
namespace: with-istio
spec:
parentRefs:
- name: k8s-gateway
namespace: k8s-gw
rules:
- matches:
- path:
type: PathPrefix
value: /with-istio
backendRefs:
- name: echoserver-service-with-istio
port: 80
The rules field allows the set of advanced routing behaviors, such as header-based matching, traffic splitting, balancing, etc. The above configuration routes HTTP traffic with the request path /with-istio from the k8s-gateway — to echoserver-service-with-istio service on port 80, which is the destination.
Combining the above resources, the request flow in Gateway API would look like this: a request would first come to the Gateway, from which *Route applies the routing rules before the request finally ends up on the respective backend service (see Fig. B).
Fig. B – Request flow in Kubernetes Gateway API
Benefits of K8s Gateway API
By now, I hope you must be convinced of the role delineation benefits of Kubernetes Gateway API. Let us explore it and some other crucial benefits and features of Gateway API.
Proper role delineation and RBAC
The cluster admin no longer needs to worry about developers accidentally introducing any wrong configuration to the Ingress resource, as they do not need to share the Gateway resource with anyone. Devs/DevOps can create *Routes and attach them to particular Gateways without distracting other teams’ routes.
No vendor lock-in
The standardization brought by Gateway API makes it seamless to switch between vendors providing controllers. DevOps and architects can use the same API to configure networking with the new vendor by changing the gatewayClassName in the Gateway resource. Almost all popular Gateway controllers and service meshes support integration with K8s Gateway API.
Increased developer experience
Advanced traffic routing rules can now be configured in *Routes in Gateway API, which spares developers/DevOps from writing and rigorously testing vendor-specific CRDs and annotations. Besides, K8s Gateway API allows users to extend it by creating custom resources that suit their unique needs.
How to implement Kubernetes Gateway API with Istio service mesh
In the demo below, I have a service deployed in both Istio-enabled and non-Istio namespace. I have used Gateway to let the traffic inside the cluster and HTTPRoute resource to apply path-based routing for the traffic — using Istio as the controller.
Watch the tutorial to see Gateway API implementation for north-south traffic with Istio service mesh:
Alternatively, you can refer to the blog, Kubernetes Gateway API Implementation in 3 Steps, where a sample banking application is migrated from Ingress (ingress-nginx) to Kubernetes Gateway API using Istio Ingress.
(As a side note, Istio made it clear that Gateway API will be Istio’s default API for traffic management in the future.)
Parting thoughts
Hope you have a good understanding of Gateway API by now. I deliberately left a few things to mention in this piece, like the GAMMA initiative and ReferenceGrant, to make it easier to consume. We’ll go over each concept around Kubernetes Gateway API in detail in the coming days.