A Kubernetes cluster is like a beautifully designed city—with excellent plumbing, stable buildings, and all essential services—but no roads leading in or out. No visitors, no deliveries, no exits. If you want your application or services to interact with the outside world (say, users), you’ll need to pave some highways. Kubernetes has traditionally offered a few ways to do this—some better than others. Now, there’s a new infrastructure project in town: the Gateway API—and it's here to stay.
In this post, we’ll explore Kubernetes’ latest external access mechanism and show how it integrates with Cert-Manager to handle certificates. But before diving into this new world, let’s briefly review the most common ways to expose services in Kubernetes.
Current Alternatives
NodePort: Exposing a Service on a Node’s Port
A NodePort service is the most basic way to expose a service externally. Kubernetes opens a specific port on each node, and any traffic to a node’s IP on that port is forwarded to the service inside the cluster. Simple, but with notable limitations.
LoadBalancer: External Load Balancers for Services
A LoadBalancer service goes a step further by integrating with external load balancing infrastructure. When you create a Service of type LoadBalancer, Kubernetes asks the cloud provider to provision an external load balancer (e.g., AWS ELB, GCP Load Balancer, Azure Load Balancer). The service receives an external IP or hostname that forwards traffic to the backing Pods.
This works well in managed cloud environments but scales poorly and doesn’t work out of the box for bare-metal or on-prem clusters—unless you add a software load balancer like MetalLB.
Ingress/Routes: Layer-7 Routing for HTTP/S
Ingress (or Route in OpenShift) is a separate API object used for external access at Layer 7 (HTTP/S). With Ingress, you define routing rules—for example, "send requests for api.example.com to Service A, and www.example.com to Service B."
An Ingress Controller implements these rules, typically using a proxy or cloud load balancer. However, Ingress only supports HTTP(S) and lacks native support for TCP or other protocols.
From Ingress to Gateway API: Why a New API?
The Gateway API is an evolving standard—now an official Kubernetes SIG project—designed to address the limitations of Ingress and support more advanced traffic management. If you're unfamiliar with the term “SIG” it stands for Special Interest Group: volunteer teams that manage and maintain specific areas of the Kubernetes ecosystem (see the project home here). Think of the Gateway API as a modern urban plan for our Kubernetes city — with zoning laws, dedicated roads, and clearly defined roles.
Unlike Ingress, Gateway API is more than a single traffic cop signaling HTTP cars through an intersection. It is an expressway system that speaks multiple protocols—HTTP, HTTPS, TCP, TLS, even UDP—while offering built-in traffic tricks such as path and header rewrites, query-parameter matching, and weighted routing for canary releases - all without using vendor-specific annotations. Crucially, it separates concerns: platform teams lay down GatewayClasses and Gateways (the asphalt), while application teams own their Routes (the traffic signs). Because the spec is vendor-neutral, the very same YAML can drive Istio, NGINX or Cilium, meaning your road network is portable as your underlying architecture evolves.
Three of the most important Resources introduced by GatewayAPI are:
- GatewayClass – urban planners
- Gateways – the roads and entry points
- Routes – detailed traffic control rules
These are implemented as Kubernetes Custom Resource Definitions (CRDs), providing flexibility, scalability, and separation of concerns. Let's dive into each of them.
GatewayClass
A GatewayClass defines a category of Gateways and is managed cluster-wide. It encapsulates the controller responsible for implementing the associated gateways.
This is similar in concept to StorageClass in Kubernetes: administrators define them, and users reference them.
Example:
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: istio
spec:
controllerName: istio.io/gateway-controller
In this case, any Gateway with gatewayClassName: istio will be handled by the Istio controller. It applies similar for other controllers.
Gateway
A Gateway is an instance of ingress infrastructure—an actual network entry point. It references a GatewayClass and defines one or more listeners, each specifying a protocol (HTTP, HTTPS, TCP), port, and optional hostname.
Example:
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: example-gateway
namespace: istio-ingress # Gateways are namespaced
spec:
gatewayClassName: istio # must match a GatewayClass
listeners:
- name: http # an arbitrary name for the listener
protocol: HTTP
port: 80
hostname: "*.example.com"
allowedRoutes:
namespaces:
from: All # allow Routes from any namespace to bind (could be restricted in production)
Routes: The Core of Gateway API’s Flexibility
Here’s where the Gateway API truly shines—dedicated, protocol-specific route types like HTTPRoute, TCPRoute, and TLSRoute. These give you granular control over traffic, such as:
- Matching by host, path, headers, or query parameters
- Routing to multiple services with weighted distribution (for canary or A/B testing)
Think of Routes as traffic signs guiding vehicles through the city. They keep everything flowing smoothly.
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: myapp-route
namespace: default
spec:
hostnames:
- "myapp.example.com"
parentRefs:
- name: example-gateway
namespace: istio-ingress
rules:
- matches:
- path:
type: PathPrefix
value: "/"
backendRefs:
- name: myapp-service
port: 80
Example highlights from an HTTPRoute:
- parentRefs: Attach the route to a specific Gateway and listener
- hostnames: Match specific domains (e.g., myapp.example.com)
- rules: Define matching logic and forwarding behavior
- matches: Conditions like path prefix or headers
- backendRefs: Destination services, possibly weighted
Earlier, we talked about one of the key advantages of the Gateway API over Ingress: native support for advanced traffic management—or what we called “traffic tricks.” A concrete example of this comes in the form of on-object filters. For instance, if you need to strip /v1 from all incoming URLs, here’s how you can do it using Gateway’s built-in URL rewrite filter:
spec:
rules:
- matches:
- path:
type: PathPrefix
value: /v1
filters:
- type: URLRewrite
urlRewrite:
path:
replacePrefixMatch: /
backendRefs:
- name: myapp-service
port: 80
No annotations, no sidecars—just one CRD doing the job.
Gateway Controllers and Implementations
Gateway API resources (like Gateway, HTTPRoute, and GatewayClass) are declarative. To actually route traffic, you need a Gateway Controller—a component that reads these resources and configures the data plane (Envoy, NGINX, etc.).
Supported controllers include:
- Service meshes like Istio and Linkerd (Istio is moving to Gateway API by default)
- Ingress controllers such as Contour, NGINX, Traefik, Kong (adding Gateway support)
- Cloud providers (GKE, AWS, Azure) that map Gateway resources to native load balancers
- Other projects like Cilium and Gloo offering enhanced networking
Managing TLS Certificates with Gateway API
Let’s be honest: rotating and renewing TLS certificates remains one of the most thankless tasks in day-to-day ops. Exposing HTTP apps to the internet requires HTTPS, and thus, TLS certificates. In the Ingress world, cert-manager automates this via annotations and certificate blocks. Fortunately, Gateway API is supported too.
To automate TLS certificate issuance with cert-manager and Gateway API:
- Ensure cert-manager and Gateway API CRDs are installed
- Configure a ClusterIssuer or Issuer (e.g., Let’s Encrypt)
- Annotate your Gateway to trigger cert-manager Example:
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: example-gateway
namespace: istio-ingress
annotations:
cert-manager.io/issuer: "letsencrypt-prod" # Reference to a cert-manager Issuer or ClusterIssuer
spec:
gatewayClassName: istio
listeners:
- name: https
protocol: HTTPS
port: 443
hostname: "myapp.example.com"
tls:
mode: Terminate
certificateRefs:
- kind: Secret
name: myapp-example-com-tls # Secret that will hold the TLS cert and key
allowedRoutes:
namespaces:
from: All
Cert-manager will:
- Detect the need for a certificate
- Create a Certificate resource behind the scenes
- Complete the ACME challenge (if using Let’s Encrypt)
- Store the key and cert in the referenced Secret
- Keep the certificate renewed automatically
This works much like how cert-manager integrates with Ingress—only now, it's applied to Gateway. This seamless integration with cert-manager is key to automating secrets management for external access and eliminates the need for hacky workarounds.
Conclusion
Kubernetes offers several ways to expose services—from the basic NodePort to cloud-managed LoadBalancer and flexible Ingress. The Gateway API builds on those lessons and provides a modern, scalable way to manage external access with better separation of infrastructure and application concerns.
We explored how GatewayClass, Gateway, and Routes work together, and how Gateway controllers like Istio implement them. On the secrets side, tools like cert-manager integrate seamlessly to automate HTTPS. For broader secrets management, tools like HashiCorp Vault are an excellent addition — perhaps a topic for another blog. 😊
Kubernetes has evolved from a small village into a thriving metropolis. And just like any modern city, it needs robust, scalable infrastructure to manage how traffic flows and how identities are verified at its gates. The Gateway API is that next-generation road system—built with urban planning in mind. The pavement is poured; now it’s time to open the on-ramps and let your applications cruise.
Top comments (0)
Some comments may only be visible to logged-in visitors. Sign in to view all comments.