Ingress and the Gateway API
What This Concept Is
Services give you L4 routing inside the cluster. For L7 (HTTP/HTTPS) routing from the outside -- host-based virtual hosts, path rewrites, TLS termination -- Kubernetes has two APIs:
- Ingress (
networking.k8s.io/v1): the original L7 API. A single resource describes rules that map(host, path)pairs to backend Services. The Ingress API has been frozen since Kubernetes v1.19; no new features are being added. Implementation is by a separately-installed Ingress controller (NGINX, Traefik, HAProxy, a cloud ALB, etc.). - Gateway API (
gateway.networking.k8s.io): the successor. Splits responsibilities acrossGatewayClass,Gateway, and route kinds (HTTPRoute,GRPCRoute,TLSRoute,TCPRoute). Supports richer routing, cross-namespace references, and more expressive TLS handling. Still the newer of the two; many clusters run both.
Both depend on an external load balancer or node port to actually receive traffic from outside.
Why It Matters Here
Exposing a single API service behind a hostname is the most common real need when deploying to Kubernetes. If you try to use a LoadBalancer Service per microservice, you end up with dozens of cloud LBs, no shared TLS termination, and no way to route by path. Ingress/Gateway collapses all of that to one external entry point.
The common failure modes:
- Ingress created but no controller installed -> no traffic ever flows; the
status.loadBalancerstays empty. ingressClassNamemissing and multiple controllers installed -> a random one (or none) will reconcile.- TLS secret in the wrong namespace -> 404 or TLS handshake failure.
- Path rules using
pathType: Exactwhen the app needsPrefix.
Concrete Example
Ingress for two services, one host:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
ingressClassName: nginx
tls:
- hosts: ["app.example.com"]
secretName: app-tls
rules:
- host: app.example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api
port:
number: 80
- path: /
pathType: Prefix
backend:
service:
name: web
port:
number: 80
Equivalent Gateway API:
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: public
spec:
gatewayClassName: nginx
listeners:
- name: https
protocol: HTTPS
port: 443
tls:
certificateRefs:
- name: app-tls
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: app
spec:
parentRefs:
- name: public
hostnames: ["app.example.com"]
rules:
- matches: [{ path: { type: PathPrefix, value: /api } }]
backendRefs: [{ name: api, port: 80 }]
- matches: [{ path: { type: PathPrefix, value: / } }]
backendRefs: [{ name: web, port: 80 }]
Common Confusion / Misconception
"Installing Ingress means installing a cluster feature."
It means installing a controller. The Ingress API type is built in; nothing routes traffic until a controller Deployment exists and is reconciling Ingress resources. On a fresh cluster, an Ingress object sits with empty status.loadBalancer forever.
A second confusion: "Gateway API replaces Services." It does not. An HTTPRoute's backendRefs still point at Services. Gateway replaces Ingress; the Service/Pod layer is unchanged.
A third confusion: "Ingress does rate limiting / auth / WAF." The core Ingress API does not. Controllers add those features via annotations (NGINX annotations, Traefik middlewares). When you rely on those, you have taken a dependency on a specific controller, not on Kubernetes. Gateway API addresses this with typed filters, but the ecosystem is still stabilizing.
How To Use It
The full external path:
- Pick one Ingress controller or Gateway implementation per cluster.
- Set
ingressClassNameorgatewayClassNameexplicitly on every resource. - Keep TLS Secrets in the same namespace as the Ingress/HTTPRoute unless you deliberately share.
- For new work, prefer Gateway API; for existing clusters with stable Ingress, migrate only when you hit the Ingress API's limits.
Check Yourself
- What does an Ingress resource do if no Ingress controller is installed?
- What is the relationship between
Gateway,GatewayClass, andHTTPRoute? - Why is Ingress' API "frozen," and what are you expected to use for new features?
Mini Drill or Application
On a kind cluster, install the NGINX Ingress controller. Deploy two Services (web and api). Write one Ingress that routes / to web and /api to api. Port-forward the controller and verify both paths work. Then convert the same configuration to an HTTPRoute backed by a Gateway and compare the fields.
Picking an Implementation
Ingress and Gateway API are specifications; behavior comes from the controller. Choosing is a Cluster 3 architectural decision:
| Controller | Strengths | Watch out for |
|---|---|---|
| NGINX Ingress | ubiquitous, huge annotation set, battle-tested | config reloads can disrupt long-lived connections; annotations are not portable |
| Traefik | native Gateway API support, simple config | smaller community than NGINX |
| HAProxy Ingress | strong performance, rich load-balancing | fewer L7 features out of the box |
| Istio / Envoy Gateway | first-class Gateway API, mesh integration | more moving parts; only worth it if you want the mesh |
| Cloud LB (ALB, GKE Gateway, AKS AGIC) | managed, integrates with cloud IAM | cloud-specific; migrating clusters gets painful |
If in doubt for a greenfield cluster, start with an NGINX or Traefik controller exposing Gateway API; migrate Ingress resources to HTTPRoutes as you touch them.
Read This Only If Stuck
- Linux Command Line:
netstatand remote hosts -- L7 proxies still speak TCP; knowing the sockets helps when a listener is missing. - Kubernetes: Ingress -- reference for the (now frozen) Ingress API.
- Kubernetes: Gateway API -- the successor API and its role-split model.
- Gateway API specification (
gateway.networking.k8s.io) -- the SIG-maintained, versioned specification with conformance. - Ingress-NGINX documentation -- annotations, TLS, rate-limiting, and deployment patterns.
- Traefik documentation -- IngressRoute CRD and native Gateway API implementation.
- Istio: Traffic Management -- when you want a service mesh behind the Gateway API.
- cert-manager documentation -- automated TLS for Ingress/Gateway via Let's Encrypt, private CAs, or cloud KMS.
- Kubernetes blog: Gateway API graduation to GA -- background on why the API exists and what it replaces.