Kubernetes Ingress provides a way to expose HTTP and HTTPS applications outside the cluster. However, as traffic-routing requirements become more complex, its design starts to show limitations.
For example:
- Different teams need to manage their own application routes.
- Infrastructure teams need control over shared gateways.
- Applications require more advanced traffic-routing rules.
- Multiple teams need to share external entry points without managing the same infrastructure.
This is where Kubernetes Gateway API comes in.
Gateway API provides a more expressive and role-oriented approach to managing traffic entering a Kubernetes cluster.
Instead of relying on a single Ingress resource to describe everything, it separates infrastructure configuration from application-level routing.
Let's understand how it works.
1. Why Kubernetes Introduced Gateway API
Ingress provides a relatively simple way to define host-based and path-based HTTP routing.
However, more advanced features often depend on controller-specific annotations and configurations.
For example, two different Ingress controllers may use different annotations to configure similar functionality.
This creates some challenges:
- Configuration portability becomes difficult.
- Infrastructure and application responsibilities are not clearly separated.
- Advanced traffic-management capabilities are not consistently supported across implementations.
- Large environments with multiple teams can become harder to manage.
Gateway API addresses these limitations through a collection of Kubernetes resources with clearly defined responsibilities.
It is not simply a replacement for every existing Ingress deployment. It provides a more flexible model for environments that need richer traffic-management capabilities.
2. Understanding the Core Gateway API Resources
Gateway API uses three important resources to establish its basic architecture.
GatewayClass
GatewayClass defines the type of gateway implementation that manages a Gateway.
It is generally created and managed by the infrastructure team.
Think of it as the definition of which gateway implementation will handle the traffic.
Gateway
Gateway represents an actual traffic entry point.
It defines listeners, such as:
- HTTP
- HTTPS
- Ports
- Hostname restrictions
- TLS configuration
A Gateway is associated with a GatewayClass.
HTTPRoute
HTTPRoute defines how HTTP requests should be routed.
It allows application teams to specify:
- Hostnames
- URL paths
- Backend Services
- Routing rules
The HTTPRoute attaches to a Gateway and directs matching requests to the appropriate backend.
The important distinction:
- GatewayClass defines the implementation.
- Gateway defines the entry point.
- HTTPRoute defines where matching requests should go.
3. How These Resources Work Together
Let's consider an application running inside a Kubernetes cluster.
We want external users to access two applications:
-
shop.example.com→ shop-service -
api.example.com→ api-service
Before creating these resources, make sure:
- Gateway API CRDs are installed in the cluster.
- A compatible Gateway API controller is installed.
- The required backend Services already exist.
Understanding the architecture
The following diagram shows how the resources fit together:
External User | v Gateway | v HTTPRoute / \ / \ v v shop-service api-service | | v v Shop Pods API Pods Step 1: GatewayClass
The infrastructure team creates a GatewayClass that references the controller responsible for managing gateways.
apiVersion: gateway.networking.k8s.io/v1 kind: GatewayClass metadata: name: example-gateway-class spec: controllerName: gateway.envoyproxy.io/gatewayclass-controller Here, controllerName identifies the Gateway API implementation.
The example uses the controller name associated with Envoy Gateway. It is not a universal value; other implementations use their own controller names.
Step 2: Gateway
Now create a Gateway using the GatewayClass.
apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: application-gateway namespace: default spec: gatewayClassName: example-gateway-class listeners: - name: http protocol: HTTP port: 80 allowedRoutes: namespaces: from: Same This Gateway creates an HTTP listener on port 80.
The allowedRoutes setting controls which namespaces can attach routes to this Gateway.
Here, Same means routes can attach only from the Gateway's own namespace.
Step 3: HTTPRoute
Next, define the routing rules for the shop application.
apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: shop-route namespace: default spec: parentRefs: - name: application-gateway hostnames: - shop.example.com rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: shop-service port: 80 This route directs requests for shop.example.com to shop-service.
We can create another HTTPRoute for the API application.
apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: api-route namespace: default spec: parentRefs: - name: application-gateway hostnames: - api.example.com rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: api-service port: 80 Now both applications use the same Gateway but have separate routing configurations.
Each backend Service must exist, and the specified port must be valid.
Notice that HTTPRoute does not configure the external listener itself. It defines application routing rules and attaches to the Gateway through parentRefs.
4. What Happens When External Traffic Arrives?
Let's follow a request to shop.example.com.
- A user accesses
https://shop.example.com. - DNS resolves the hostname to the external address associated with the Gateway.
- The external load balancer or network entry point forwards traffic to the Gateway implementation.
- The Gateway implementation evaluates the attached HTTPRoute and matches the hostname and path.
- The request is forwarded to
shop-service. - The Service directs traffic to an available application Pod.
The Gateway API defines the desired routing configuration. The actual data-plane implementation and packet-processing details depend on the Gateway controller.
For example, an implementation may use Envoy or another proxy to process requests.
Important: Gateway API does not prescribe one universal packet-processing path. Different implementations can handle backend traffic differently.
5. How Does HTTPS Work with Gateway API?
Gateway API supports TLS configuration through Gateway listeners.
For example:
apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: secure-gateway namespace: default spec: gatewayClassName: example-gateway-class listeners: - name: https protocol: HTTPS port: 443 hostname: shop.example.com tls: mode: Terminate certificateRefs: - kind: Secret name: shop-tls-secret allowedRoutes: namespaces: from: Same Here:
- The Gateway listens on port 443.
-
mode: Terminatemeans TLS is terminated at the Gateway. -
certificateRefsidentifies the Kubernetes Secret containing the TLS certificate and private key.
The referenced Secret must be available in the appropriate namespace and meet the implementation's requirements.
After TLS termination, the Gateway implementation routes the HTTP request according to the attached HTTPRoute.
This is a separate HTTPS listener example; it illustrates how TLS configuration is added to a Gateway.
6. Gateway API vs Ingress
Both provide ways to expose applications outside Kubernetes, but their configuration models differ.
| Feature | Ingress | Gateway API |
|---|---|---|
| Main resource | Ingress | Gateway, HTTPRoute |
| Configuration model | More centralized | Role-oriented |
| Advanced routing | Often controller-specific | Richer standardized resources |
| Infrastructure separation | Limited | Clearer separation |
| TLS configuration | Ingress resource | Gateway listener |
| Extensibility | More limited | Designed for extensibility |
Gateway API also supports additional route types, including GRPCRoute and TCPRoute, depending on the installed API version and implementation.
Ingress remains supported, but its API is frozen. Kubernetes recommends Gateway API for new functionality.
7. How to Troubleshoot Gateway API
If traffic is not reaching the application, don't immediately assume the backend Pod is the problem.
Check the configuration layer by layer.
Check GatewayClass:
kubectl get gatewayclass Verify that the expected GatewayClass exists and is accepted.
Check Gateway:
kubectl get gateway kubectl describe gateway application-gateway Look at its listeners and status conditions.
Check HTTPRoute:
kubectl get httproute kubectl describe httproute shop-route Check whether the route is accepted and attached to the intended Gateway.
Check backend Services:
kubectl get svc kubectl get endpointslices Verify that the Service exists and has available endpoints.
Check Gateway implementation logs:
Inspect the controller and data-plane logs for configuration errors, rejected routes, or connectivity problems.
Gateway API status conditions are particularly useful:
-
Accepted: Whether the resource or route configuration was accepted. -
Programmed: Whether the Gateway configuration has been programmed. -
ResolvedRefs: Whether referenced resources, such as Services and Secrets, were resolved.
These conditions help narrow down where the configuration is failing.
8. What Comes Next?
Kubernetes networking has evolved from basic application exposure to more flexible traffic-management architectures.
Ingress provides a simple HTTP routing model. Gateway API builds on that foundation with clearer responsibilities, richer routing resources, and better extensibility.
However, Gateway API is not a networking implementation by itself. A compatible controller must be installed to process the resources and implement the desired traffic behavior.
For new Kubernetes environments that require advanced traffic management, Gateway API is an important technology to understand.
The next step is to explore how Gateway API implementations handle real traffic, including proxy configuration, route matching, load balancing, and traffic splitting.
Discussion: Have you started using Gateway API in your Kubernetes clusters, or are you still using Ingress?
