LFCE 141 ๐ง Kubernetes โ Ingress Basics
An Ingress is a Kubernetes resource that defines HTTP and HTTPS routing rules for services inside the cluster. It is not a load balancer and it does not expose anything by itself. The Ingress resource is a declaration of intent: requests for api.example.com/v1 should go to the api-v1 Service, and requests for api.example.com/v2 should go to the api-v2 Service. The component that reads that declaration and configures the actual routing is the Ingress Controller.
This chapter covers the Ingress resource, the rules that define host and path routing, the IngressClass that selects the controller, and the critical distinction between Ingress (the rule) and Ingress Controller (the implementation). It also covers the difference between an Ingress and a Service of type LoadBalancer, because the two are often confused.
Key point: An Ingress does nothing without an Ingress Controller. The resource is just a rule set. The controller is the running software that watches for Ingress resources, provisions the underlying load balancer, and routes the traffic. A cluster with Ingress resources but no Ingress Controller silently accepts the manifests and routes nothing.
Why Ingress exists alongside Services
The LoadBalancer cost problem. A Service of type LoadBalancer provisions one cloud load balancer per Service. Ten HTTP services mean ten load balancers and ten public IP addresses. An Ingress consolidates those ten services behind one load balancer and one IP address, using host and path rules to route each request to the correct Service . The cost reduction is the primary motivation, but the operational simplification is equally important: one IP to manage, one TLS certificate to rotate, one set of DNS records.
The layer-7 problem. A Service of type LoadBalancer operates at layer 4. It forwards TCP or UDP traffic to a Pod without inspecting the HTTP request. It cannot route based on the Host header or the URL path. An Ingress operates at layer 7. It reads the HTTP request, matches the host and path against the rules, and forwards the request to the appropriate Service . This is what makes name-based virtual hosting and path-based fanout possible.
The rule abstraction problem. The Ingress resource is a stable API for routing rules. The same Ingress manifest works with an NGINX Ingress Controller on a self-hosted cluster, with the GKE Ingress controller on Google Cloud, and with Application Gateway on Azure . The controller translates the rules into the cloud provider’s load balancer configuration. The application team writes the routing rules once; the platform team chooses the controller.
a. The Ingress resource and its rules
The Ingress resource is defined in the networking.k8s.io/v1 API group. The spec contains an optional tls block, an optional defaultBackend, and a rules list. Each rule has an optional host and a http.paths list. Each path has a path, a pathType, and a backend that references a Service and port .
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: api-ingress
spec:
ingressClassName: nginx
rules:
- host: api.example.com
http:
paths:
- path: /v1
pathType: Prefix
backend:
service:
name: api-v1
port:
number: 80
- path: /v2
pathType: Prefix
backend:
service:
name: api-v2
port:
number: 80
The host field is a fully qualified domain name. It can be an exact match (api.example.com) or a wildcard (*.example.com), but the wildcard must be the first DNS label and matches only one label . If host is omitted, the rule matches all hosts.
The pathType field determines how the path is matched. Exact requires an exact match and is case-sensitive. Prefix matches on path elements separated by /, so /v1 matches /v1/users but not /v1beta. ImplementationSpecific leaves the interpretation to the controller . When multiple paths match, the longest path wins.
The backend references a Service by name and port. The Service must exist in the same namespace as the Ingress. If the Service does not exist, the Ingress controller returns a 503 for requests routed to that backend.
b. The IngressClass and the controller
The ingressClassName field references an IngressClass resource, which in turn names the controller that should implement the Ingress. The IngressClass is a cluster-scoped resource with a spec.controller field that identifies the controller implementation.
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
name: nginx
spec:
controller: k8s.io/ingress-nginx
The ingressClassName field replaced the older kubernetes.io/ingress.class annotation. The annotation is deprecated but still supported by most controllers for backward compatibility . A cluster can have a default IngressClass marked with the ingressclass.kubernetes.io/is-default-class: "true" annotation. An Ingress without an ingressClassName uses the default class if one exists.
The distinction between the resource and the controller is the most common source of confusion. The Ingress resource is a manifest that describes routing rules. The IngressClass is a manifest that names the controller. The controller is a running Deployment in the cluster that watches for Ingress resources with a matching class, reads their rules, and configures the underlying proxy. Without the controller, the Ingress resource is inert.
c. Ingress versus Service of type LoadBalancer
A Service of type LoadBalancer exposes a single Service on a cloud load balancer. It operates at layer 4, does not inspect HTTP, and requires one load balancer per Service. An Ingress consolidates multiple HTTP Services behind one load balancer and routes by host and path.
The Azure documentation states the distinction clearly: for non-HTTP traffic, use a LoadBalancer Service with layer-4 load balancing; for HTTP-like traffic, use an Ingress controller with layer-7 load balancing to share a single public IP across multiple applications . A cluster can use both: a LoadBalancer Service for a database that accepts TCP connections on a specific port, and an Ingress for the web front-end that routes by hostname.
Complete Example Session
# ============================================
# PART 1: THE BACKEND SERVICES
# ============================================
apiVersion: v1
kind: Service
metadata:
name: api-v1
spec:
selector:
app: api
version: v1
ports:
- port: 80
targetPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: api-v2
spec:
selector:
app: api
version: v2
ports:
- port: 80
targetPort: 8080
# ============================================
# PART 2: THE INGRESS RESOURCE
# ============================================
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: api-ingress
spec:
ingressClassName: nginx
rules:
- host: api.example.com
http:
paths:
- path: /v1
pathType: Prefix
backend:
service:
name: api-v1
port:
number: 80
- path: /v2
pathType: Prefix
backend:
service:
name: api-v2
port:
number: 80
# ============================================
# PART 3: THE INGRESSCLASS
# ============================================
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
name: nginx
spec:
controller: k8s.io/ingress-nginx
# ============================================
# PART 4: APPLY THE MANIFESTS
# ============================================
kubectl apply -f services.yaml
kubectl apply -f ingressclass.yaml
kubectl apply -f ingress.yaml
# ============================================
# PART 5: VERIFY THE INGRESS
# ============================================
kubectl get ingress api-ingress
# NAME CLASS HOSTS ADDRESS PORTS
# api-ingress nginx api.example.com 203.0.113.10 80
# ============================================
# PART 6: DESCRIBE THE INGRESS
# ============================================
kubectl describe ingress api-ingress
# Rules:
# Host Path Backends
# api.example.com
# /v1 api-v1:80 (10.244.1.5:8080)
# /v2 api-v2:80 (10.244.2.3:8080)
# ============================================
# PART 7: TEST THE ROUTING
# ============================================
curl http://api.example.com/v1/users
# Routed to api-v1
curl http://api.example.com/v2/users
# Routed to api-v2
# ============================================
# PART 8: WILDCARD HOST
# ============================================
spec:
rules:
- host: "*.example.com"
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: wildcard-svc
port:
number: 80
# ============================================
# PART 9: DEFAULT BACKEND
# ============================================
spec:
defaultBackend:
service:
name: fallback
port:
number: 80
rules:
- host: api.example.com
# ...
# ============================================
# PART 10: TLS
# ============================================
spec:
tls:
- hosts:
- api.example.com
secretName: api-tls
rules:
- host: api.example.com
# ...
The ten parts covered the backend Services, the Ingress resource, the IngressClass, applying the manifests, verification, description, testing, wildcard hosts, the default backend, and TLS.
Quick Reference
Ingress fields
| Field | Purpose |
|---|---|
ingressClassName | References the IngressClass |
rules[].host | Hostname match (exact or wildcard) |
rules[].http.paths[].path | URL path |
rules[].http.paths[].pathType | Exact, Prefix, ImplementationSpecific |
rules[].http.paths[].backend | Service name and port |
defaultBackend | Fallback when no rule matches |
tls | TLS hosts and Secret |
Path types
| Type | Behavior |
|---|---|
Exact | Case-sensitive exact match |
Prefix | Element-wise prefix match |
ImplementationSpecific | Controller-defined |
Controller comparison
| Feature | Ingress | LoadBalancer Service |
|---|---|---|
| Layer | 7 (HTTP/HTTPS) | 4 (TCP/UDP) |
| Routing | Host and path | Port only |
| Load balancers | One for many Services | One per Service |
| Cost | Lower | Higher |
IngressClass
| Field | Purpose |
|---|---|
spec.controller | Identifies the controller implementation |
| Default annotation | ingressclass.kubernetes.io/is-default-class: "true" |
Best Practices
โ Do This:
# Specify ingressClassName explicitly
spec:
ingressClassName: nginx # โ
# Use Prefix for path routing
pathType: Prefix # โ
# Use a defaultBackend for unmatched requests
defaultBackend:
service:
name: fallback # โ
โ Don’t Do This:
# Omit ingressClassName and rely on a default
# If no default class exists, the Ingress is inert # โ
# Use Exact for a path that should match subpaths
pathType: Exact # โ
# Assume Ingress works without a controller
# The manifest is accepted, but nothing is routed # โ
Common Pitfalls
| Pitfall | Why It Happens | Fix |
|---|---|---|
| Ingress has no effect | No Ingress Controller installed | Install a controller and create the IngressClass |
| 503 from the controller | Backend Service does not exist or has no endpoints | Check kubectl get endpoints |
| Path does not match | pathType is Exact but subpath is requested | Use Prefix |
| Wildcard host does not match | The wildcard is not the first label | Use *.example.com, not foo.*.com |
| TLS certificate not used | The Secret is missing or in the wrong namespace | Create the TLS Secret in the same namespace |
Real-World Examples
1. Host-based routing
rules:
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api
port:
number: 80
2. Path-based routing
paths:
- path: /v1
pathType: Prefix
backend:
service:
name: api-v1
- path: /v2
pathType: Prefix
backend:
service:
name: api-v2
3. IngressClass
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
name: nginx
spec:
controller: k8s.io/ingress-nginx
4. Default backend
spec:
defaultBackend:
service:
name: fallback
5. TLS
spec:
tls:
- hosts: [api.example.com]
secretName: api-tls
6. Wildcard host
host: "*.example.com"
7. Imperative creation
kubectl create ingress simple --rule="foo.com/bar=svc1:8080"
8. Check the controller
kubectl get pods -n ingress-nginx
9. Check the Ingress
kubectl get ingress
10. Describe the Ingress
kubectl describe ingress api-ingress
Visual
Ingress and the controller
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ INGRESS RESOURCE โ
โ rules: โ
โ host: api.example.com โ
โ /v1 โ api-v1 Service โ
โ /v2 โ api-v2 Service โ
โ โ
โ INGRESS CONTROLLER (running Pod) โ
โ watches for Ingress resources โ
โ reads the rules โ
โ configures the proxy โ
โ โ
โ Without the controller, the rules are inert. โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Host and path routing
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ api.example.com/v1/users โ
โ โ โ
โ โผ โ
โ Ingress Controller โ
โ โ โ
โ โโโ host match: api.example.com โ
โ โโโ path match: /v1 โ
โ โผ โ
โ api-v1 Service โโโบ api-v1 Pod โ
โ โ
โ api.example.com/v2/users โ
โ โ โ
โ โผ โ
โ api-v2 Service โโโบ api-v2 Pod โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Ingress vs LoadBalancer Service
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ LOADBALANCER SERVICE INGRESS โ
โ โ
โ One LB per Service One LB for many Services โ
โ Layer 4 Layer 7 โ
โ TCP/UDP HTTP/HTTPS โ
โ No host/path routing Host and path routing โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
IngressClass
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Ingress โ
โ ingressClassName: nginx โ
โ โ โ
โ โผ โ
โ IngressClass (nginx) โ
โ spec.controller: k8s.io/ingress-nginx โ
โ โ โ
โ โผ โ
โ NGINX Ingress Controller โ
โ watches Ingress resources with class "nginx" โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Summary
| Item | Value |
|---|---|
| API group | networking.k8s.io/v1 |
| Routing layer | Layer 7 (HTTP/HTTPS) |
| Required component | Ingress Controller |
| Class selection | ingressClassName or annotation |
| Host matching | Exact or wildcard (*.example.com) |
| Path types | Exact, Prefix, ImplementationSpecific |
| Backend | Service name and port |
| TLS | tls block with hosts and Secret |
| Default fallback | defaultBackend |
Key takeaways:
- An Ingress is a rule set; an Ingress Controller is the implementation. The Ingress resource declares routing rules. The controller watches for Ingress resources, reads the rules, and configures the underlying proxy. Without a controller, the Ingress is inert .
- Ingress operates at layer 7; a LoadBalancer Service operates at layer 4. Ingress can route by host and path because it inspects the HTTP request. A LoadBalancer Service forwards TCP or UDP without inspecting the request, so it cannot route by hostname or URL .
- The
ingressClassNamefield references an IngressClass, which names the controller. The class is a cluster-scoped resource. A default class can be marked with an annotation, and Ingress resources without a class use the default if one exists . - The
pathTypedetermines how paths are matched.Exactrequires an exact match.Prefixmatches on path elements, so/v1matches/v1/usersbut not/v1beta. When multiple paths match, the longest path wins . - A wildcard host must be the first DNS label.
*.example.comis valid and matchesapi.example.combut notfoo.api.example.com. The wildcard cannot be used alone as*. - TLS is configured with a
tlsblock and a Secret. The Secret must exist in the same namespace as the Ingress. The controller uses it to terminate TLS for the listed hosts.
Remember: An Ingress is the layer-7 routing rule, and the Ingress Controller is the software that makes the rule real. The resource declares host and path matches and points to backend Services. The class selects the controller. The controller provisions the load balancer and routes the traffic. Without the controller, the manifest is a comment. Use Ingress for HTTP services that need host-based or path-based routing behind a single IP address. Use a LoadBalancer Service for non-HTTP traffic that needs a dedicated layer-4 endpoint. And when an Ingress is not working, check the controller first: if it is not running, nothing else matters.
Stop using slow, ad-bloated tool sites! ๐คฎ
๐ Search “KandZ Tools” on Google to use many professional utilities for free.
KandZ.me is the ultimate minimalist hub for:
โ
Finance (Mortgage, Interest, Inflation)
โ
Tech (Base64, JSON, Dev Suite, IP)
โ
Health (BMI, BMR, TDEE)
โ
Productivity (Timer, Workspace, QR)
โก๏ธ Fast & Private
๐ No data leaves your device
๐ 100% Free
๐ Use it now: https://tools.kandz.me
๐ Bookmark itโyouโll need it later!