The Kubernetes Gateway API
/ 4 min read
Table of Contents
For years, the Ingress
resource has been the standard way to expose HTTP services in Kubernetes. While functional, its limitations have become increasingly apparent in a world of complex microservices. Its lack of standardization across implementations, limited expressiveness for advanced traffic routing, and ambiguous, role-agnostic design created a ceiling of complexity. Enter the Kubernetes Gateway API, a powerful, role-oriented, and extensible replacement poised to unify not just ingress, but the entire landscape of Kubernetes traffic management, including service mesh.
This post is a deep dive into the Gateway API and the GAMMA (Gateway API for Mesh Management and Administration) initiative, exploring how they provide a single, consistent interface for both north-south (ingress) and east-west (service-to-service) traffic.
The Gateway API
The core strength of the Gateway API lies in its separation of concerns. It splits the monolithic Ingress
object into three distinct, role-oriented resources:
-
GatewayClass
: Managed by the Infrastructure Provider (e.g., the cloud provider or cluster operator). This cluster-scoped resource is a template that defines which controller (e.g., Istio, Contour, GKE) will implement the configuration. -
Gateway
: Deployed by the Cluster Operator. This resource requests a specific traffic entry point. It binds to aGatewayClass
and defines the listeners (ports, protocols, TLS settings) for the underlying load balancer or proxy. -
HTTPRoute
(and other*Route
kinds likeTCPRoute
,GRPCRoute
): Managed by the Application Developer. This is where the application-specific routing logic lives. It defines rules (hostnames, paths, headers) and attaches to aGateway
to direct traffic to backendServices
.
This model is revolutionary because it decouples infrastructure from application configuration. The operator manages the gateways, and developers manage how their services are routed, without needing to worry about the underlying implementation details.
Example: A Classic North-South Ingress
Here’s how you would expose a web application using the Gateway API. Notice how each persona manages their own resource.
# 1. GatewayClass (Managed by Infrastructure Provider)apiVersion: gateway.networking.k8s.io/v1kind: GatewayClassmetadata: name: my-gateway-classspec: controllerName: "example.com/gateway-controller"---# 2. Gateway (Managed by Cluster Operator)apiVersion: gateway.networking.k8s.io/v1kind: Gatewaymetadata: name: my-gateway namespace: infra-nsspec: gatewayClassName: my-gateway-class listeners: - name: http protocol: HTTP port: 80 allowedRoutes: namespaces: from: Selector selector: matchLabels: expose-via-gateway: "true"---# 3. HTTPRoute (Managed by Application Developer)apiVersion: gateway.networking.k8s.io/v1kind: HTTPRoutemetadata: name: my-app-route namespace: app-ns labels: expose-via-gateway: "true"spec: parentRefs: - name: my-gateway namespace: infra-ns hostnames: ["app.example.com"] rules: - matches: - path: type: PathPrefix value: /api backendRefs: - name: my-app-service port: 8080
The GAMMA Initiative: Extending Gateway API to the Service Mesh
The real game-changer is the GAMMA initiative. Its goal is to extend the elegant model of the Gateway API to manage east-west (service-to-service) traffic, effectively creating a unified configuration plane for both ingress controllers and service meshes.
The key technical innovation is simple but profound: an HTTPRoute
can now attach directly to a Service
instead of a Gateway
.
When an HTTPRoute
’s parentRef
points to a Service
, the service mesh (e.g., Istio, Linkerd) intercepts traffic destined for that service and applies the route’s rules. This allows developers to use the same HTTPRoute
resource to define complex routing behaviors like traffic splitting, fault injection, and header-based routing for internal traffic, just as they would for ingress.
Example: An East-West Canary Release
Imagine you want to perform a canary release, sending 10% of internal traffic to a new version of a service. With GAMMA, you can do this with a single HTTPRoute
:
apiVersion: gateway.networking.k8s.io/v1kind: HTTPRoutemetadata: name: my-service-canary namespace: my-appspec: parentRefs: - group: "" kind: Service name: my-service port: 8080 rules: - backendRefs: - name: my-service-v1 port: 8080 weight: 90 - name: my-service-v2-canary port: 8080 weight: 10
In this example, any pod in the mesh that calls my-service.my-app.svc.cluster.local:8080
will have its traffic automatically split by the mesh’s data plane according to the weights defined in the HTTPRoute
. No ingress gateway is involved. This replaces the need for mesh-specific CRDs like Istio’s VirtualService
or Linkerd’s HTTPRoute
(from the SMI spec), consolidating everything under the official Kubernetes Gateway API.
The Future of Kubernetes Networking
The combination of ingress and service mesh configuration under a single, expressive, and official Kubernetes API is a watershed moment for the ecosystem.
It promises:
- Portability: With conformance profiles, an
HTTPRoute
that works on Istio will work the same way on Linkerd or Kuma. - Simplicity: Developers only need to learn one API for all traffic management.
- Clear Roles: The separation of concerns between infrastructure and application teams is preserved and clarified.