24: Ingress Advanced
24: Ingress Advanced
Objective
Learn how to use NGINX Ingress annotations for URL rewriting, understand the rewrite-target annotation with regex capture groups, and get an overview of advanced Ingress features available with the managed NGINX Ingress Controller.
Theory
The URL Rewriting Problem
In the previous exercise, path-based routing sent requests to backend Services with the original path intact. For example, a request to /api/users was forwarded to the backend as /api/users.
However, many backend applications expect requests at the root path (/). If your API service expects /users but receives /api/users, it returns 404. URL rewriting solves this by stripping or transforming the path prefix before forwarding the request to the backend.
The rewrite-target Annotation
The managed NGINX Ingress Controller supports the standard NGINX annotation for URL rewriting:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
This annotation is used together with regex capture groups in the path:
path: /api(/|$)(.*)
How it works:
| Capture Group | Matches | Example |
|---|---|---|
(/\|$) |
A trailing slash or end of string | /api or /api/ |
(.*) |
Everything after the prefix | users, users/123, empty string |
The rewrite-target: /$2 replaces the request path with the content of the second capture group:
| Original Request | Capture Group 2 | Rewritten Path |
|---|---|---|
/api |
(empty) | / |
/api/ |
(empty) | / |
/api/users |
users |
/users |
/api/users/123 |
users/123 |
/users/123 |
Rewrite Flow
graph LR
Client["Client"]
IC["NGINX Ingress Controller"]
SVC["Backend Service"]
Client -->|"GET /api/users"| IC
IC -->|"rewrite-target: /$2<br/>GET /users"| SVC
subgraph Rewrite["Rewrite Logic"]
direction TB
Original["/api/users"]
Match["path: /api(/|$)(.*)"]
Cap1["$1 = /"]
Cap2["$2 = users"]
Result["rewrite-target: /$2<br/>→ /users"]
Original --> Match
Match --> Cap1
Match --> Cap2
Cap2 --> Result
end
style Rewrite fill:#e1f5fe,stroke:#0288d1,stroke-width:1px
Important: use-regex Annotation
When using regex in the path, you must also add:
annotations:
nginx.ingress.kubernetes.io/use-regex: "true"
This tells the NGINX Ingress Controller to interpret the path as a regular expression.
Practical Tasks
Task 1: Get the Ingress Controller IP
INGRESS_IP=$(kubectl get svc -n app-routing-system nginx -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo "Ingress IP: $INGRESS_IP"
Task 2: Create a Backend Application
Create a file called rewrite-app.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: echo-api-XX
namespace: student-XX
labels:
app: echo-api-XX
spec:
replicas: 2
selector:
matchLabels:
app: echo-api-XX
template:
metadata:
labels:
app: echo-api-XX
spec:
containers:
- name: echo
image: hashicorp/http-echo
args:
- "-text=API response from student-XX"
ports:
- containerPort: 5678
resources:
requests:
cpu: "50m"
memory: "32Mi"
limits:
cpu: "100m"
memory: "64Mi"
---
apiVersion: v1
kind: Service
metadata:
name: echo-api-XX
namespace: student-XX
spec:
selector:
app: echo-api-XX
ports:
- port: 80
targetPort: 5678
Deploy:
kubectl apply -f rewrite-app.yaml
kubectl get pods -n student-XX -l app=echo-api-XX
Task 3: Create an Ingress with URL Rewriting
Create a file called rewrite-ingress.yaml:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: rewrite-ingress-XX
namespace: student-XX
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
nginx.ingress.kubernetes.io/use-regex: "true"
spec:
ingressClassName: webapprouting.kubernetes.azure.com
rules:
- host: rewrite-XX.INGRESS_IP.nip.io # Replace INGRESS_IP with actual IP
http:
paths:
- path: /api(/|$)(.*)
pathType: ImplementationSpecific
backend:
service:
name: echo-api-XX
port:
number: 80
Important: Replace
INGRESS_IPwith the actual IP from Task 1.
Key points in this configuration:
rewrite-target: /$2— rewrites the path using the second capture groupuse-regex: "true"— enables regex path matchingpathType: ImplementationSpecific— required when using regex paths with NGINX
Apply the Ingress:
kubectl apply -f rewrite-ingress.yaml
Task 4: Test URL Rewriting
Wait for the Ingress to get an address:
kubectl get ingress rewrite-ingress-XX -n student-XX
Test various paths:
# /api should be rewritten to /
curl http://rewrite-XX.$INGRESS_IP.nip.io/api
# /api/ should also be rewritten to /
curl http://rewrite-XX.$INGRESS_IP.nip.io/api/
# /api/anything should be rewritten to /anything
curl http://rewrite-XX.$INGRESS_IP.nip.io/api/anything
# A path without /api prefix should return 404
curl http://rewrite-XX.$INGRESS_IP.nip.io/other
All /api* requests should return the echo response because they are rewritten and forwarded to the backend. The /other path should return 404 because it does not match the Ingress rule.
Clean Up
kubectl delete -f rewrite-ingress.yaml
kubectl delete -f rewrite-app.yaml
Advanced Topics (Overview)
The managed NGINX Ingress Controller supports many additional annotations. These are mentioned here for reference — no hands-on tasks are required.
Rate Limiting
annotations:
nginx.ingress.kubernetes.io/limit-rps: "10"
nginx.ingress.kubernetes.io/limit-burst-multiplier: "5"
Limits requests per second to prevent abuse.
SSL Redirect
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
Automatically redirects HTTP traffic to HTTPS.
Custom Headers
annotations:
nginx.ingress.kubernetes.io/configuration-snippet: |
more_set_headers "X-Custom-Header: my-value";
Adds custom response headers.
CORS (Cross-Origin Resource Sharing)
annotations:
nginx.ingress.kubernetes.io/enable-cors: "true"
nginx.ingress.kubernetes.io/cors-allow-origin: "https://example.com"
Enables and configures CORS headers for API backends.
The Future: Gateway API
The Kubernetes Gateway API is the emerging standard that will eventually replace Ingress:
- More expressive and extensible than Ingress
- Role-oriented design (infrastructure provider, cluster operator, application developer)
- In Azure, Application Gateway for Containers implements the Gateway API
- Supports advanced traffic management: traffic splitting, header-based routing, URL rewrites natively
- Consider Gateway API for new projects; Ingress remains fully supported
Common Problems
| Problem | Possible Cause | Solution |
|---|---|---|
| Rewrite not working | Missing use-regex: "true" annotation |
Add the annotation and reapply |
| 404 on all paths | Regex pattern does not match | Test the regex pattern; ensure capture groups are correct |
pathType error |
Using Prefix or Exact with regex paths |
Use pathType: ImplementationSpecific for regex paths |
| Backend receives wrong path | Incorrect capture group reference in rewrite-target |
Verify which capture group ($1, $2) contains the desired path segment |
| Annotations ignored | Wrong annotation prefix | Must use nginx.ingress.kubernetes.io/ prefix for the managed NGINX controller |
Best Practices
- Use
ImplementationSpecificpathType with regex —PrefixandExactdo not support regex patterns in NGINX Ingress. - Test regex patterns carefully — A mistake in capture groups can route traffic to unexpected paths. Test with
curl -vto see the actual forwarded path. - Document your rewrite rules — Rewrite rules can be confusing to debug. Add comments or documentation explaining the pattern and expected behavior.
- Prefer simple path structures — If possible, design your backend APIs to match the external path structure, reducing the need for rewrites.
- Evaluate Gateway API for new projects — The Gateway API provides more powerful and standardized traffic management capabilities than Ingress annotations.
Summary
In this exercise you learned:
- URL rewriting solves the mismatch between external paths (e.g.,
/api/users) and backend expected paths (e.g.,/users) - The
nginx.ingress.kubernetes.io/rewrite-targetannotation with regex capture groups enables path transformation - The
use-regex: "true"annotation andpathType: ImplementationSpecificare required for regex-based paths - Advanced NGINX annotations provide rate limiting, SSL redirect, custom headers, and CORS support
- The Gateway API (with Application Gateway for Containers in Azure) is the emerging standard for traffic management