Kubernetes Gateway API
Learn Kubernetes Gateway API with plain-English explanations and real examples..
20+ years shipping production infrastructure and CI/CD at scale. Lessons pulled from things that broke in production.
- ✓Kubernetes cluster v1.24+, kubectl, familiarity with Kubernetes networking concepts (Services, Ingress), basic YAML, and one of the following Gateway API implementations installed: Istio 1.16+, Contour 1.24+, or NGINX Gateway Fabric 1.0+.
Think of Kubernetes Gateway API like a tool in your DevOps toolkit — once you understand what it does and when to reach for it, managing Kubernetes clusters becomes second nature.
You've been running Ingress for years. It works—until it doesn't. A misconfigured path rewrite takes down production for 45 minutes because the Ingress controller silently dropped a regex. The Kubernetes Gateway API exists precisely to eliminate these failure modes. It's not just an upgrade; it's a fundamental rethinking of how traffic enters your cluster. By introducing explicit roles (GatewayClass, Gateway, HTTPRoute), it forces clarity: infrastructure teams own the gateway, application teams own the routes. No more fighting over a single Ingress resource. No more vendor-specific annotations that break on upgrade. If you're managing more than 10 services or have multiple teams sharing a cluster, the Gateway API is not optional—it's survival.
Why Ingress Failed and Gateway API Fixed It
The Ingress API was designed for simple HTTP(S) routing, but production demands quickly outgrew it. Teams resorted to vendor-specific annotations (e.g., nginx.ingress.kubernetes.io/rewrite-target) that locked them into a single controller. Worse, Ingress had no concept of role separation: a single Ingress resource could be edited by anyone, leading to accidental overwrites. The Gateway API solves this by splitting responsibilities: a cluster operator defines a Gateway (the entry point), and application teams define HTTPRoute resources that attach to it. This prevents conflicts and enables independent lifecycle management. Additionally, the Gateway API supports L4 (TCP/UDP) routing, header-based matching, and weighted traffic splitting natively—no annotations required. The result is a portable, extensible API that works across multiple implementations (e.g., Istio, Contour, NGINX Gateway Fabric).
Core Resources: GatewayClass, Gateway, and Route
The Gateway API defines three primary resource types. GatewayClass is a cluster-scoped resource that specifies a controller (e.g., istio.io/gateway-controller) and parameters. It's analogous to StorageClass for storage. Gateway is a namespaced resource that represents a load balancer or proxy instance. It references a GatewayClass and defines listeners (ports, protocols, TLS). Routes (HTTPRoute, TCPRoute, etc.) are namespaced resources that attach to Gateways via a parentRef. This three-tier model allows infrastructure teams to provision gateways while app teams define routing rules. For example, a GatewayClass might be 'istio' with parameters for auto-scaling, a Gateway in the 'infra' namespace listens on port 443, and an HTTPRoute in 'team-a' routes /api/* to a backend service. The separation ensures that changes to routing don't affect gateway configuration and vice versa.
HTTPRoute Deep Dive: Matching, Filtering, and BackendRefs
HTTPRoute is the workhorse of the Gateway API. It supports advanced matching on path, headers, query parameters, and method. Each rule can have multiple matches (OR logic) and multiple backendRefs (with weights for canary). Filters allow request/response header modification, redirect, rewrite, and mirroring. For example, you can mirror 1% of traffic to a new service for testing without affecting users. The spec also supports timeouts and retries via policy attachments (e.g., RetryFilter). Crucially, HTTPRoute supports cross-namespace references via backendRefs with a namespace field, enabling service mesh patterns where a route in one namespace can forward to a service in another. This is a game-changer for multi-team clusters where shared services (e.g., auth) live in a different namespace.
TLS Termination and Passthrough
The Gateway API handles TLS at the listener level. You can configure TLS termination (where the gateway decrypts traffic) or TLS passthrough (where encrypted traffic is forwarded directly to the backend). For termination, you reference a Secret containing the certificate and key. For passthrough, you set mode: Passthrough and the route must be a TLSRoute (not HTTPRoute). This is critical for scenarios where the backend handles its own TLS (e.g., mTLS between services). The Gateway API also supports SNI matching, allowing multiple certificates on the same listener. Misconfiguring TLS is a common source of outages—forgetting to update a certificate before expiry, or using the wrong Secret namespace. Always use cert-manager to automate certificate provisioning and set up monitoring for certificate expiry.
Cross-Namespace Routing and Multi-Tenancy
One of the most powerful features of the Gateway API is its native support for cross-namespace references. A Gateway in the 'infra' namespace can accept routes from any namespace (or a selected set). Similarly, an HTTPRoute can reference a backend service in another namespace. This enables a multi-tenant model where a central platform team manages the gateway, and application teams manage their routes independently. To enforce isolation, use the allowedRoutes field on the Gateway listener to restrict which namespaces can attach routes. Additionally, use ReferenceGrant resources to explicitly allow cross-namespace references (e.g., a route in team-a referencing a service in shared-svcs). Without ReferenceGrant, the API server rejects the reference for security.
Policy Attachment: Extending Gateway Behavior
The Gateway API uses a policy attachment model to extend functionality without modifying the core resources. Policies are custom resources that target Gateways, HTTPRoutes, or BackendRefs. Examples include RetryPolicy, TimeoutPolicy, RateLimitPolicy, and HealthCheckPolicy. These are defined by the implementation (e.g., Istio, Contour) and are not portable across implementations. However, the Gateway API provides a standard mechanism for attaching them via the 'targetRef' field. For example, you can attach a RetryPolicy to an HTTPRoute to configure retry attempts and timeouts. This keeps the core API clean while allowing vendors to innovate. When using policies, always check the implementation's documentation for supported policies and their behavior.
Migration from Ingress to Gateway API
Migrating from Ingress to Gateway API requires careful planning. Start by identifying all Ingress resources and their annotations. Map each Ingress to a combination of Gateway and HTTPRoute. For simple cases, the mapping is straightforward: one Ingress becomes one HTTPRoute attached to a shared Gateway. For complex Ingresses with multiple rules, you may need multiple HTTPRoutes or a single route with multiple rules. Use the 'kubernetes.io/ingress.class' annotation to determine which controller handles the Ingress; the Gateway API equivalent is the gatewayClassName. During migration, run both Ingress and Gateway API in parallel by using different hostnames or paths. Gradually shift traffic by updating DNS or using weighted routing. Monitor for errors using the Gateway API status fields (e.g., .status.parents[].conditions).
Observability and Debugging
Debugging Gateway API issues requires understanding the status subresources. Each Gateway and HTTPRoute has a .status field that shows the conditions of the resource (e.g., Accepted, ResolvedRefs). For example, if an HTTPRoute references a non-existent backend, the status will show a condition with reason 'RefNotPermitted' or 'BackendNotFound'. Use 'kubectl describe' to view these conditions. Additionally, most implementations expose metrics and logs. For Istio, you can use 'istioctl proxy-status' to check the Envoy configuration. For Contour, check the contour pod logs. Common issues include: Gateway not ready (check GatewayClass exists), route not attached (check parentRef namespace and allowedRoutes), and backend not reachable (check service and endpoint existence). Always validate your YAML with 'kubectl apply --dry-run=client'.
Performance and Scaling Considerations
The Gateway API itself is a control plane API; performance depends on the underlying implementation. However, there are best practices to avoid bottlenecks. First, limit the number of routes attached to a single Gateway. Each route adds to the configuration complexity and can increase Envoy/NGINX reload times. For large clusters, consider partitioning traffic across multiple Gateways (e.g., per team or per hostname). Second, use GatewayClass parameters to tune the proxy (e.g., worker threads, connection limits). Third, monitor the Gateway's resource usage (CPU/memory) and set appropriate resource requests/limits. Fourth, be aware of the API server impact: creating many routes simultaneously can cause etcd pressure. Use a GitOps approach with batch updates. Finally, test your Gateway's performance under load before going to production.
Security Best Practices
Security in the Gateway API starts with the principle of least privilege. Use allowedRoutes on Gateway listeners to restrict which namespaces can attach routes. Use ReferenceGrant to control cross-namespace references. For TLS, always use TLS 1.2 or higher and strong cipher suites. Avoid using self-signed certificates in production; use cert-manager with a trusted CA. For authentication, consider using OIDC or JWT validation at the gateway level via policy attachments (e.g., RequestAuthentication in Istio). For network security, use NetworkPolicies to restrict traffic between pods. Additionally, audit your Gateway API resources regularly for misconfigurations. Tools like 'kube-score' or 'polaris' can check for common issues. Finally, enable audit logging on the API server to track changes to Gateway API resources.
Future of Gateway API: GAMMA and Service Mesh Integration
The Gateway API is evolving to support service mesh use cases through the GAMMA initiative (Gateway API for Mesh Management and Administration). GAMMA extends the Gateway API to configure east-west traffic within the mesh, not just north-south. This means you can use the same API to define routing between services (e.g., HTTPRoute for mesh traffic). The goal is to unify ingress and mesh configuration under one API. Currently, this is experimental, but implementations like Istio already support it. For example, you can create an HTTPRoute with a parentRef pointing to a mesh gateway (e.g., istio-ingressgateway) or to a mesh service. This reduces the learning curve and operational complexity. Keep an eye on the GAMMA status and start experimenting in non-production clusters.
| File | Command / Code | Purpose |
|---|---|---|
| gateway.yaml | apiVersion: gateway.networking.k8s.io/v1 | Why Ingress Failed and Gateway API Fixed It |
| httproute.yaml | apiVersion: gateway.networking.k8s.io/v1 | Core Resources |
| httproute-advanced.yaml | apiVersion: gateway.networking.k8s.io/v1 | HTTPRoute Deep Dive |
| gateway-tls.yaml | apiVersion: gateway.networking.k8s.io/v1 | TLS Termination and Passthrough |
| referencegrant.yaml | apiVersion: gateway.networking.k8s.io/v1beta1 | Cross-Namespace Routing and Multi-Tenancy |
| retrypolicy.yaml | apiVersion: networking.istio.io/v1beta1 | Policy Attachment |
| migrate.sh | kubectl get ingress --all-namespaces -o json | jq '.items[] | {name: .metadata.n... | Migration from Ingress to Gateway API |
| debug.sh | kubectl get gateway prod-gateway -n infra -o jsonpath='{.status.conditions}' | j... | Observability and Debugging |
| gateway-class.yaml | apiVersion: gateway.networking.k8s.io/v1 | Performance and Scaling Considerations |
| network-policy.yaml | apiVersion: networking.k8s.io/v1 | Security Best Practices |
| mesh-route.yaml | apiVersion: gateway.networking.k8s.io/v1 | Future of Gateway API |
Key takeaways
Interview Questions on This Topic
What is the difference between Ingress and Gateway API?
Frequently Asked Questions
20+ years shipping production infrastructure and CI/CD at scale. Lessons pulled from things that broke in production.
That's Kubernetes. Mark it forged?
5 min read · try the examples if you haven't