What is an Ingress, and how does it differ from a Service of type LoadBalancer?
Quick Answer
An Ingress is a set of routing rules — based on hostname and URL path — that routes external HTTP/HTTPS traffic to different internal Services, all through a single entry point, rather than requiring a separate cloud load balancer per Service. It requires an Ingress controller (a piece of software, like NGINX Ingress or Traefik, running in the cluster) to actually implement the routing — the Ingress object itself is just the desired routing configuration, similarly to how a Deployment spec is just configuration until a controller acts on it.
Detailed Answer
The problem with one LoadBalancer Service per application
A LoadBalancer Service provisions a dedicated external cloud load balancer for that one Service — fine for a single application, but a cluster hosting dozens of services, each needing external HTTP access, would need dozens of expensive cloud load balancers, each with its own IP, and no shared logic for routing by hostname or path.
What Ingress solves: one entry point, many backends, routed by rules
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: main-ingress
spec:
rules:
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: backend-api
port:
number: 80
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frontend
port:
number: 80
One Ingress (typically fronted by exactly one LoadBalancer Service, pointing at the Ingress controller itself) can route api.example.com to the backend-api Service and app.example.com to the frontend Service — host-based and path-based routing, TLS termination, and often other HTTP-layer features (URL rewriting, request/response header manipulation) that a plain L4 LoadBalancer Service knows nothing about, since a LoadBalancer Service just forwards raw TCP/UDP traffic without any awareness of HTTP semantics.
The Ingress controller — the piece that actually does the work
Critically, creating an Ingress object by itself does nothing unless an Ingress controller is running in the cluster to watch for Ingress objects and implement their rules — much like how a Deployment spec sitting in etcd does nothing until the Deployment controller acts on it. Common Ingress controllers: NGINX Ingress Controller, Traefik, cloud-specific ones (AWS Load Balancer Controller, GCE Ingress). Different controllers support different annotations/features beyond the Ingress spec's baseline (rate limiting, custom load-balancing algorithms, WAF integration), so the choice of controller genuinely matters, not just the Ingress YAML itself.
LoadBalancer Service vs. Ingress — where each fits
| LoadBalancer Service | Ingress | |
|---|---|---|
| Layer | L4 (TCP/UDP) | L7 (HTTP/HTTPS) |
| Routing granularity | Whole Service, one external LB each | Host/path-based routing to many Services through one entry point |
| Cost at scale (cloud) | One cloud LB per Service — expensive with many services | Typically one cloud LB total, fronting the Ingress controller |
| TLS termination | Possible, but more manual | Commonly built in via tls config referencing a Secret |
| Non-HTTP protocols (raw TCP, gRPC without HTTP/1.1 semantics, etc.) | Works fine — it's protocol-agnostic at L4 | HTTP-focused; some controllers support gRPC/TCP passthrough with extensions, but it's not the core design target |
The typical real-world setup
Most production clusters run exactly one (or a small number of) LoadBalancer Service, pointed at an Ingress controller Deployment, and expose every other internal application Service purely as ClusterIP, routed to externally only via Ingress rules — this minimizes external cloud load balancer cost and centralizes TLS/routing configuration in one place rather than scattering it across many individually-exposed Services.
Gateway API — the newer alternative
Kubernetes's newer Gateway API is a more expressive, role-oriented successor to Ingress (separating cluster-operator-owned infrastructure config from application-team-owned routing rules, and supporting more protocols/features natively) — increasingly adopted alongside or instead of Ingress, though Ingress remains extremely widely deployed and is not being removed.