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_IP with the actual IP from Task 1.

Key points in this configuration:

  • rewrite-target: /$2 — rewrites the path using the second capture group
  • use-regex: "true" — enables regex path matching
  • pathType: 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

  1. Use ImplementationSpecific pathType with regexPrefix and Exact do not support regex patterns in NGINX Ingress.
  2. Test regex patterns carefully — A mistake in capture groups can route traffic to unexpected paths. Test with curl -v to see the actual forwarded path.
  3. Document your rewrite rules — Rewrite rules can be confusing to debug. Add comments or documentation explaining the pattern and expected behavior.
  4. Prefer simple path structures — If possible, design your backend APIs to match the external path structure, reducing the need for rewrites.
  5. 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-target annotation with regex capture groups enables path transformation
  • The use-regex: "true" annotation and pathType: ImplementationSpecific are 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

results matching ""

    No results matching ""