skip to content
Smadi0x86 Blog
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:

  1. 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.

  2. Gateway: Deployed by the Cluster Operator. This resource requests a specific traffic entry point. It binds to a GatewayClass and defines the listeners (ports, protocols, TLS settings) for the underlying load balancer or proxy.

  3. HTTPRoute (and other *Route kinds like TCPRoute, GRPCRoute): Managed by the Application Developer. This is where the application-specific routing logic lives. It defines rules (hostnames, paths, headers) and attaches to a Gateway to direct traffic to backend Services.

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/v1
kind: GatewayClass
metadata:
name: my-gateway-class
spec:
controllerName: "example.com/gateway-controller"
---
# 2. Gateway (Managed by Cluster Operator)
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: my-gateway
namespace: infra-ns
spec:
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/v1
kind: HTTPRoute
metadata:
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/v1
kind: HTTPRoute
metadata:
name: my-service-canary
namespace: my-app
spec:
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.