4.6 Ingress Architecture, Controllers & Path-Based Routing
Key Takeaways
- An Ingress resource (networking.k8s.io/v1) is a declarative routing definition, whereas an Ingress Controller (e.g., NGINX Ingress Controller) is the active reverse proxy daemon executing those rules.
- The IngressClass resource decouples Ingress manifests from specific controller implementations; an Ingress specifies its target controller using spec.ingressClassName.
- Path-based routing supports Exact, Prefix, and ImplementationSpecific pathTypes; Prefix matching operates strictly on slash-separated URL path segments.
- TLS termination is configured in the Ingress spec.tls block, referencing a Secret of type kubernetes.io/tls containing valid tls.crt and tls.key data.
- NGINX Ingress Controller bypasses kube-proxy and NodePort hops by leveraging custom Lua dynamic routing to dispatch HTTP requests directly to backend Pod IP endpoints.
4.6 Ingress Architecture, Controllers & Path-Based Routing
While NodePort and LoadBalancer Services operate at Layer 4 (TCP/UDP transport layer), modern microservices architectures require Layer 7 (HTTP/HTTPS application layer) capabilities—such as Host-based virtual hosting, Path-based URL routing, SSL/TLS termination, header-based rewriting, and rate limiting.
In Kubernetes, the Ingress system provides a unified HTTP reverse-proxy gateway. It is fundamentally decoupled into two distinct entities:
- The Ingress Resource (
networking.k8s.io/v1): A declarative Kubernetes API object containing routing rules, TLS certificates, and backend mappings. - The Ingress Controller: A daemon (typically running NGINX, HAProxy, Envoy, or Traefik) deployed as a Deployment/DaemonSet that watches the Kubernetes API server, dynamically reconfigures its routing table, and proxies external HTTP traffic directly to backend Pods.
[!IMPORTANT] Ingress Requires an Ingress Controller: Creating an
Ingressresource in a cluster that lacks a running Ingress Controller has zero effect. The Ingress resource will sit in etcd with an emptyAddressfield, and no traffic will be routed.
1. IngressClass Architecture (networking.k8s.io/v1)
In clusters running multiple Ingress controllers (e.g., an external NGINX controller for public internet traffic and an internal Traefik controller for corporate VPN traffic), the IngressClass resource establishes the mapping between Ingress manifests and controller daemons.
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
name: nginx-external
annotations:
ingressclass.kubernetes.io/is-default-class: "true" # Marks as default IngressClass
spec:
controller: k8s.io/ingress-nginx # Identifies the controller implementation
Targeting an IngressClass in an Ingress Manifest:
Modern Kubernetes uses the spec.ingressClassName field:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: public-web-ingress
namespace: default
spec:
ingressClassName: nginx-external # Explicitly references the IngressClass
rules:
- host: store.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: store-frontend-svc
port:
number: 80
2. Host-Based vs. Path-Based Routing & pathType Matching Rules
+-----------------------------------------------------------------------------------------+
| INGRESS ROUTING ARCHITECTURES |
| |
| 1. HOST-BASED (Virtual Hosting) 2. PATH-BASED ROUTING |
| Client Request: Client Request: |
| +------------------------------------+ +------------------------------------+ |
| | Host: api.example.com | | Host: example.com | |
| | Path: / | | Path: /checkout | |
| +-----------------+------------------+ +-----------------+------------------+ |
| v v |
| [ Ingress Controller ] [ Ingress Controller ] |
| | | |
| +-----------+-----------+ +-----------+-----------+ |
| | (api.example) | (shop.example) | (/api) | (/checkout) | (/static) |
| v v v v v |
| [ API Service ] [ Shop Service ] [ API Svc ] [ Checkout Svc ] [ Static Svc ]|
+-----------------------------------------------------------------------------------------+
pathType Semantics (Exact vs. Prefix vs. ImplementationSpecific):
The pathType field is mandatory for every path rule in networking.k8s.io/v1:
pathType | Matching Behavior | Examples |
|---|---|---|
Exact | Matches the exact URL path string with strict case sensitivity. | Path /orders matches /orders only. Does NOT match /orders/ or /orders/123. |
Prefix | Matches URL path prefixes split by the / delimiter. | Path /app matches /app, /app/, and /app/details. Does NOT match /apple (because apple is not a /-separated child segment). |
ImplementationSpecific | Matching logic is delegated entirely to the underlying Ingress Controller (e.g., regex matching in NGINX). | Dependent on controller annotations. |
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: multi-route-ingress
namespace: production
spec:
ingressClassName: nginx
rules:
# Host 1: API Subdomain
- host: api.mycompany.com
http:
paths:
- path: /v1
pathType: Prefix
backend:
service:
name: api-v1-service
port:
number: 8080
- path: /v2
pathType: Prefix
backend:
service:
name: api-v2-service
port:
number: 8080
# Host 2: Main Website with Path-Based Routing
- host: mycompany.com
http:
paths:
- path: /orders
pathType: Prefix
backend:
service:
name: order-service
port:
number: 3000
- path: /
pathType: Prefix
backend:
service:
name: web-frontend-service
port:
number: 80
3. SSL/TLS Termination with Kubernetes Secrets
Ingress controllers provide centralized SSL/TLS termination, offloading certificate decryption overhead from backend application pods. Certificates are stored in standard Kubernetes Secrets of type kubernetes.io/tls.
Step 1: Create the TLS Secret Imperatively
# Generate self-signed certificate (or use genuine CA cert):
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout tls.key -out tls.crt -subj "/CN=secure.example.com/O=MyCompany"
# Create Kubernetes TLS Secret in target namespace:
kubectl create secret tls my-tls-secret \
--cert=tls.crt \
--key=tls.key \
-n production
Step 2: Configure spec.tls in the Ingress Manifest
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: secure-tls-ingress
namespace: production
spec:
ingressClassName: nginx
tls:
- hosts:
- secure.example.com
secretName: my-tls-secret # References the TLS Secret in same namespace
rules:
- host: secure.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: secure-app-svc
port:
number: 443
4. Advanced Ingress Annotations: URL Rewriting & SSL Redirection
Standard Ingress specs do not provide native fields for regex rewrites. Ingress controllers rely on Annotations to inject advanced reverse-proxy directives.
Common NGINX Ingress Annotations:
| Annotation | Technical Function | Example Usage |
|---|---|---|
nginx.ingress.kubernetes.io/rewrite-target | Rewrites target URI path before forwarding to backend | rewrite-target: /$2 |
nginx.ingress.kubernetes.io/ssl-redirect | Enforces HTTP to HTTPS 301 redirection | ssl-redirect: "true" |
nginx.ingress.kubernetes.io/proxy-body-size | Sets maximum allowed client request payload size | proxy-body-size: "50m" |
nginx.ingress.kubernetes.io/backend-protocol | Specifies upstream protocol (HTTP, HTTPS, GRPC) | backend-protocol: "HTTPS" |
nginx.ingress.kubernetes.io/limit-rps | Rate-limits incoming client requests per second | limit-rps: "20" |
# URL Rewriting Example: Forwarding /api/v1/users to backend as /users
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: rewrite-ingress
namespace: default
annotations:
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
ingressClassName: nginx
rules:
- host: api.example.com
http:
paths:
- path: /api/v1(/|$)(.*)
pathType: ImplementationSpecific
backend:
service:
name: user-service
port:
number: 8080
5. Ingress Controller Internals & Troubleshooting Runbook
Unlike standard Kubernetes Services (which route through kube-proxy iptables/IPVS chains), the NGINX Ingress Controller bypasses kube-proxy entirely. It directly queries EndpointSlice resources from the API server and uses embedded Lua scripting to route HTTP connections directly to backend Pod IP addresses, eliminating unnecessary network hops.
Ingress HTTP Error Troubleshooting Guide:
+-----------------------------------------------------------------------------------------+
| INGRESS HTTP ERROR DIAGNOSTIC MATRIX |
| |
| ERROR CODE ROOT CAUSE DIAGNOSTIC & FIX |
| +-----------------+------------------------------------+----------------------------+ |
| | 404 Not Found | 1. PathType mismatch | - Check 'pathType: Prefix' | |
| | | 2. Incorrect Host header | - Verify curl -H 'Host:..' | |
| | | 3. Missing root '/' path rule | - Check regex rewrite rule | |
| +-----------------+------------------------------------+----------------------------+ |
| | 502 Bad Gateway | 1. Backend Pod not ready / failing | - Check 'kubectl get pods' | |
| | | 2. Service port != Container port | - Check Service targetPort | |
| | | 3. Backend service has 0 endpoints | - Check EndpointSlices | |
| +-----------------+------------------------------------+----------------------------+ |
| | 503 Service | 1. Ingress controller unable to | - Check Ingress controller | |
| | Unavailable | reach upstream Pod IP | pod logs & CNI status | |
| +-----------------+------------------------------------+----------------------------+ |
+-----------------------------------------------------------------------------------------+
# 1. Verify Ingress resource and allocated Address
kubectl get ingress -A
kubectl describe ingress public-web-ingress
# 2. Inspect Ingress Controller pods and logs
kubectl get pods -n ingress-nginx
kubectl logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx --tail=200
# 3. Test Ingress routing from CLI simulating DNS host header
curl -k -v -H "Host: store.example.com" http://<INGRESS_CONTROLLER_IP>/
An Ingress rule is defined with 'path: /app' and 'pathType: Prefix'. According to the Kubernetes networking specification, which of the following incoming request URIs will MATCH this rule?
A developer deploys an Ingress object referencing a backend Service named 'auth-service' on port 80. External requests to the Ingress return 'HTTP 502 Bad Gateway'. Checking 'kubectl get endpoints auth-service' shows 'ENDPOINTS: <none>'. What is the root cause?
An administrator creates an Ingress resource with TLS termination in namespace 'staging'. However, the Ingress controller logs report: 'Error obtaining certificate: secret production/tls-cert does not exist'. What is the operational constraint causing this error?