Why the Original Ingress Object Falls Short
The Ingress resource was designed for a simple use case: route HTTP traffic by hostname and path. As Kubernetes adoption grew, teams needed more: traffic splitting for canary deployments, header-based routing, TCP/UDP routing, and multi-team management of routing rules. The Ingress spec could not express these natively, so every Ingress controller invented its own annotations — non-standard, controller-specific hacks bolted onto the metadata.
The result: Ingress YAML written for Nginx does not work with Traefik. Migrating controllers means rewriting all your routing configuration.
The Gateway API Design
The Gateway API is the official Kubernetes successor to Ingress, designed from the ground up to be expressive, extensible, and role-oriented. It splits configuration across three objects that map to three organizational roles:
| Object | Managed By | Purpose |
|---|---|---|
GatewayClass |
Infrastructure Provider | Defines the type of load balancer (e.g., "AWS ALB", "Nginx") |
Gateway |
Cluster Administrator | Defines listeners (ports, protocols, TLS config) |
HTTPRoute |
Application Developer | Defines routing rules for their specific service |
This separation is the key insight. A developer can deploy and update their own HTTPRoute without needing cluster-admin access to modify the shared Gateway. In a large organization with many teams, this is a significant operational improvement.
Advanced Routing Example
Traffic splitting for a canary release — something that requires messy annotations in classic Ingress — is first-class in Gateway API: an HTTPRoute can list multiple backend services with explicit weights (say, 90% to the stable version and 10% to the canary), directly in the standard spec rather than a controller-specific annotation. This is clean, portable, and works with any Gateway API-compatible controller (Envoy Gateway, Nginx Gateway Fabric, Istio, etc.).