Skip to main content

Gateway API: The Evolution of Cluster Ingress

The Kubernetes Gateway API is a SIG-Network project designed to evolve the networking capabilities of Kubernetes beyond the limitations of the legacy Ingress resource. It provides a more expressive, extensible, and role-oriented model for managing Layer 4 and Layer 7 traffic.


1. WHY EVOLVE? THE LIMITATIONS OF INGRESS

Traditional Ingress served the community for years, but its architectural flaws became bottlenecks in production:

  • Annotation Sprawl: Features like Rate Limiting, Retries, and Canary splits were never part of the Ingress spec. This led to "Annotation Hell," where every vendor (Nginx, Istio, AWS) implemented features via proprietary, unvalidated strings.
  • Monolithic Structure: A single Ingress object handled both infrastructure (LB config) and application logic (routing), making it impossible to separate duties between Cluster Admins and Developers.
  • Namespace Isolation: Ingress is strictly namespaced. Sharing a single Load Balancer across multiple namespaces required complex "Merge" logic or non-standard controller behavior.

2. ARCHITECTURE: THE ROLE-ORIENTED MODEL

The Gateway API introduces a resource hierarchy that aligns with organizational roles. This allows for Separation of Concerns.

2.1 The Object Hierarchy

2.2 The Three Pillars

  1. GatewayClass (The Blueprint): Cluster-scoped. Defines the "type" of infrastructure (e.g., AWS ALB, Nginx, Cilium). Analogous to a StorageClass.
  2. Gateway (The Entry Point): Namespaced. Defines where the Load Balancer should listen (IP, Port, Protocol) and which TLS certificates to use.
  3. Route Objects (The Logic): Namespaced (HTTPRoute, GRPCRoute, TCPRoute). Defines how traffic is directed to backends.

3. BIBLE-GRADE MANIFESTS: PRODUCTION SETUP

3.1 The Gateway (Operations Layer)

This defines the physical Load Balancer and allows Routes from any namespace to attach to it.

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: enterprise-gateway
namespace: infra-ns
spec:
gatewayClassName: nginx # Refers to the GatewayClass installed by the vendor
listeners:
- name: https
protocol: HTTPS
port: 443
hostname: "*.company.com"
tls:
mode: Terminate
certificateRefs:
- name: wildcard-tls-cert
allowedRoutes:
namespaces:
from: All # Allows Cross-Namespace attachment

3.2 The HTTPRoute (Developer Layer)

A developer in the payments namespace can now "attach" their routing logic to the infrastructure gateway.

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: payment-api-route
namespace: payments
spec:
parentRefs:
- name: enterprise-gateway
namespace: infra-ns # Attach to the central Gateway
hostnames: ["api.company.com"]
rules:
- matches:
- path:
type: PathPrefix
value: /v1/pay
filters:
- type: RequestHeaderModifier
requestHeaderModifier:
add:
- name: X-Gateway-Managed
value: "true"
backendRefs:
- name: payment-svc
port: 8080

4. NATIVE TRAFFIC ENGINEERING: CANARY RELEASES

One of the greatest strengths of the Gateway API is native support for weighted traffic splitting without annotations.

spec:
rules:
- backendRefs:
- name: payment-svc-v1
port: 8080
weight: 90 # 90% of traffic
- name: payment-svc-v2-canary
port: 8080
weight: 10 # 10% of traffic

5. SECURITY: REFERENCEGRANT

In a multi-tenant cluster, cross-namespace references are dangerous. What stops a malicious user from routing traffic to a Service in your namespace? ReferenceGrant.

  • Mechanism: If an HTTPRoute in Namespace A wants to point to a Service in Namespace B, the owner of Namespace B must create a ReferenceGrant to permit it.
apiVersion: gateway.networking.k8s.io/v1beta1
kind: ReferenceGrant
metadata:
name: allow-infra-to-app
namespace: payments # Located where the target resource is
spec:
from:
- group: gateway.networking.k8s.io
kind: HTTPRoute
namespace: infra-ns # Trust traffic coming from this namespace
to:
- group: ""
kind: Service # Allow access to Services here

6. PRODUCTION COMPARISON

FeatureLegacy IngressGateway API
API ExpressivenessLow (Needs annotations)High (Native support for filters/weights)
RBAC IntegrationMonolithic (Hard to delegate)Built-in (GC vs GW vs Route)
Multi-tenancyDifficult / HackyNative (Cross-namespace parentRefs)
ValidationWeak (Strings in annotations)Strong (Custom Resource validation)
Protocol SupportHTTP/HTTPS onlyHTTP, gRPC, TCP, UDP, TLS

7. TROUBLESHOOTING & NINJA COMMANDS

7.1 The "Status" is the Truth

The Gateway API relies heavily on the status block for feedback. If a route isn't working, check the Accepted and Programmed conditions.

# Check if the Gateway was successfully provisioned by the controller
kubectl get gateway -n infra-ns -o jsonpath='{.status.conditions}'

# Check if the HTTPRoute successfully attached to the parent Gateway
kubectl describe httproute payment-api-route -n payments

7.2 Common Attachment Failures

If Accepted is False, check:

  1. Hostname Conflict: Two routes claiming the same hostname on the same Gateway.
  2. Namespace Policy: The Gateway's allowedRoutes may be restricting your namespace.
  3. Invalid Backend: The backendRef points to a Service that doesn't exist or hasn't been granted access via ReferenceGrant.

7.3 Viewing the "Data Plane" Realization

For in-cluster controllers like Nginx Gateway Fabric, you can inspect the generated Nginx configuration:

# Exec into the Nginx Gateway Fabric pod
kubectl exec -it <ngf-pod> -n ngf-gatewayapi-ns -- cat /etc/nginx/conf.d/enterprise-gateway.conf

8. ARCHITECT'S FINAL VERDICT

  1. Adopt Early for New Projects: The Gateway API is the future. Avoid building new infrastructure on legacy Ingress.
  2. Use ReferenceGrant for Zero-Trust: Never allow cross-namespace routing without an explicit ReferenceGrant.
  3. Centralize Infrastructure: Let the SRE team manage the Gateway (Infra), and allow developers to own the HTTPRoute (Logic). This minimizes the "blast radius" of human error.