Kubernetes Ingress Explained — Routing, TLS, and Real Examples
Source: Dev.to
Ingress is the smart HTTP entry point for your cluster. It separates traffic routing from Service exposure and lets you manage TLS centrally.
Why Ingress Matters
| Problem | What Happens Without Ingress |
|---|---|
| Service exposure | Every Service needs its own NodePort or LoadBalancer. |
| Cost | 100 Services → 100 LoadBalancers → 100 public IPs → 100 separate billing items. |
| Routing logic | Handled outside Kubernetes (external LB, manual DNS). Kubernetes has no visibility or control. |
| TLS management | Each Service needs its own certificate → renewal, rotation, and configuration become error‑prone. |
Ingress solves all of the above by providing a single, Layer‑7 (HTTP/HTTPS) entry point that can:
- Route traffic by host and/or path
- Terminate TLS (HTTPS) centrally
- Forward traffic to the appropriate Service
⚠️ Ingress is just a declarative resource. It needs an Ingress Controller (NGINX, Traefik, HAProxy, cloud‑specific controllers, etc.) to actually handle traffic.
How Ingress Works (Diagram)
Client (Browser)
↓
Ingress Controller (NGINX / Traefik / …)
↓
Ingress Rules (host / path / TLS)
↓
Service (stable endpoint)
↓
Pods (managed by Deployment)
Ingress Basics – YAML Examples
1️⃣ Simple Host‑Based Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
spec:
rules:
- host: app.sharon.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app-service
port:
number: 80
What it does
- Accepts traffic for
app.sharon.com - Routes all requests to the Service
app-service - The Service load‑balances traffic to its Pods
2️⃣ Path‑Based Routing (Multiple Services)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: multi-app-ingress
spec:
rules:
- host: sharon.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80
- path: /web
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
Routing behaviour
| Request | Service |
|---|---|
sharon.com/api | api-service |
sharon.com/web | web-service |
3️⃣ Host‑Based Routing (Multiple Domains)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: host-ingress
spec:
rules:
- host: api.sharon.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80
- host: web.sharon.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
Routing behaviour
| Hostname | Service |
|---|---|
api.sharon.com | api-service |
web.sharon.com | web-service |
4️⃣ TLS Termination with a Secret
Create a TLS secret (once per domain):
kubectl create secret tls app-tls \
--cert=cert.pem \
--key=key.pem
Ingress that uses the secret:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: tls-ingress
spec:
tls:
- hosts:
- app.sharon.com
secretName: app-tls
rules:
- host: app.sharon.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app-service
port:
number: 80
What it does
- Terminates HTTPS at the Ingress Controller
- Traffic inside the cluster remains HTTP (no need to configure TLS in Pods)
- Certificates are managed centrally, not per Service
Ingress vs. LoadBalancer (Feature Comparison)
| Feature | Ingress | LoadBalancer |
|---|---|---|
| OSI Layer | L7 (HTTP/HTTPS) | L4 (TCP/UDP) |
| Routing | Host & path based | None (single Service) |
| TLS | Yes (central secret) | Limited (per LB) |
| Cost | Low – single external load balancer | High – one LB per Service |
| Scalability | High (many Services behind one entry) | Limited (one LB per Service) |
| Typical Use‑case | HTTP/HTTPS applications | Non‑HTTP workloads or simple exposure |
Common Pitfalls (What NOT to Do)
- Creating Ingress without an Ingress Controller – the resource will never become active.
- Using a LoadBalancer for every Service – unnecessary cost and complexity.
- Forgetting DNS configuration – the hostnames in Ingress rules must resolve to the Ingress Controller’s external IP.
- Mixing Service exposure and routing logic – keep Service type (
ClusterIP) separate from Ingress routing. - Managing TLS separately for each Service – defeats the purpose of central TLS termination.
When to Use Ingress
Use Ingress when you:
- Run HTTP/HTTPS applications.
- Need routing by domain or path (multi‑tenant or micro‑service architectures).
- Want centralized TLS management (single secret per domain).
- Want to reduce cloud load‑balancer costs by sharing a single external IP.
End‑to‑End Flow (Full Picture)
Internet
|
v
DNS (domain → external IP of Ingress Controller)
|
v
Ingress Controller (NGINX / Traefik / …)
|
v
Ingress Rules (host / path / TLS)
|
v
Service (ClusterIP – stable endpoint)
|
v
Pods (managed by Deployment / ReplicaSet)
Quick Checklist for a Healthy Ingress Setup
- Deploy an Ingress Controller (NGINX, Traefik, HAProxy, cloud‑specific, etc.).
- Create DNS records that point your domain(s) to the controller’s external IP.
- Define Ingress resources with the required host/path rules.
- Create TLS secrets (if you need HTTPS) and reference them in the Ingress spec.
- Set Services to
ClusterIP(they don’t need external exposure). - Verify that traffic reaches the correct Pods via
curl/browser and that TLS termination works (openssl s_client -connect …).
TL;DR
- Ingress = single, smart HTTP entry point for many Services.
- Ingress Controller = the engine that makes Ingress rules work.
- Benefits: cost‑effective, centralized routing, and TLS management.
Happy clustering! 🚀
Each service needs its own TLS certificate.
Certificates must be renewed, rotated, and configured per service.
Managing HTTPS for dozens of services becomes error‑prone and hard to scale.
Ingress is not optional in production — it is the control plane for HTTP traffic in Kubernetes.