Skip to content

Ingress and Gateway API

Ingress describes Layer-7 HTTP(S) routing rules for getting external traffic to internal Services, but those rules do nothing until an Ingress controller is actually running to implement them.

A LoadBalancer Service works well for one application, but provisioning a separate cloud load balancer per app gets expensive and does not let you route by hostname or URL path. Ingress solves this at Layer 7: one entry point that inspects the HTTP request and routes based on host and path.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: shop
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: shop.example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-svc
port:
number: 80
- path: /
pathType: Prefix
backend:
service:
name: frontend-svc
port:
number: 80

That manifest expresses two things at once: host-based routing (only requests for shop.example.com match this rule at all) and path-based routing (/api goes to one Service, everything else goes to another).

This is the part that trips people up: creating an Ingress object does not, by itself, cause any traffic to be routed anywhere. Ingress is just a declaration of intent — it requires an Ingress controller, a separate piece of software actually running in the cluster (an nginx-based controller, a cloud provider’s controller, or others), watching Ingress objects and programming a real proxy or load balancer to match. No controller running means the Ingress resource just sits there, inert.

Terminal window
# An Ingress with no controller watching it accomplishes nothing
kubectl get ingress shop
kubectl get pods -n ingress-nginx # this is what actually does the routing

When more than one controller is installed in a cluster, ingressClassName (backed by an IngressClass object) tells Kubernetes which controller should implement a given Ingress:

apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
name: nginx
spec:
controller: k8s.io/ingress-nginx

Gateway API is a newer, role-oriented model for the same problem, built from three resources instead of one:

  • GatewayClass — the implementation, analogous to IngressClass (provided by a controller vendor).
  • Gateway — a listener: an actual point of entry (protocol, port, hostname), typically owned by the platform/infrastructure team.
  • HTTPRoute (and GRPCRoute) — the routing rules attached to a Gateway, typically owned by application teams.
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: shop-gateway
spec:
gatewayClassName: example-gateway-class
listeners:
- name: http
protocol: HTTP
port: 80
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: shop-route
spec:
parentRefs:
- name: shop-gateway
hostnames:
- "shop.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /api
backendRefs:
- name: api-svc
port: 80

That split matters in practice: a platform team can own and lock down the Gateway (which ports and TLS certs are exposed) while individual application teams safely own their own HTTPRoute objects without needing access to the shared listener at all. Gateway, GatewayClass, and HTTPRoute (along with GRPCRoute) have reached General Availability at gateway.networking.k8s.io/v1, and Gateway API is the direction the ecosystem is moving for new, more advanced routing needs — but Ingress remains extremely widely deployed, fully supported, and perfectly adequate for straightforward host/path routing. Neither is going away soon.

flowchart LR
  ext["External client"] --> ctrl["Ingress controller\n(e.g. nginx)"]
  ctrl -->|"host/path rules"| ing["Ingress object"]
  ing --> svcA["Service: api-svc"] --> podA["Pods"]
  ing --> svcB["Service: frontend-svc"] --> podB["Pods"]
External traffic through an Ingress controller to internal Services and Pods
Why does creating an Ingress object alone not route any traffic
What is the difference between host-based and path-based routing in an Ingress rule
In Gateway API, what does an HTTPRoute do
How do GatewayClass, Gateway, and HTTPRoute relate to each other