Skip to content

NGINX Ingress Controller Practice Questions

Question 1: Simple Host-Based Routing with NGINX Ingress

Objective: Create an Ingress resource that routes traffic to different backend services based on the hostname in the request.

Prerequisites:

  • NGINX Ingress Controller is installed and running
  • frontend-service exists in namespace nginx-practice-apps (listening on port 8080)
  • backend-service exists in namespace nginx-practice-apps (listening on port 3000)

Task:

  1. Create an Ingress resource named host-based-ingress in the nginx-practice-apps namespace with the following routing rules:

    • Requests to hostname app.example.com should route to frontend-service:8080
    • Requests to hostname api.example.com should route to backend-service:3000
    • Both routes should serve traffic on port 80
    • Use the nginx IngressClass
  2. Configure your local environment to test the Ingress:

    • Add entries to /etc/hosts for app.example.com and api.example.com
    • Port-forward the NGINX Ingress Controller to localhost
  3. Verify the configuration by sending HTTP requests:

    • Test that curl -H "Host: app.example.com" http://localhost returns the frontend response
    • Test that curl -H "Host: api.example.com" http://localhost returns the backend API response

Verify:

bash
kubectl get ingress -n nginx-practice-apps
kubectl describe ingress host-based-ingress -n nginx-practice-apps
curl -H "Host: app.example.com" http://localhost
curl -H "Host: api.example.com" http://localhost

Question 2: Path Rewriting with NGINX Annotations

Objective: Configure path-based routing with URL rewriting using NGINX Ingress annotations. The backend services should receive rewritten paths, not the original request paths.

Prerequisites:

  • NGINX Ingress Controller is installed
  • product-service (port 8080), cart-service (port 9090), and auth-service (port 7070) are running in nginx-practice-apps namespace

Task:

  1. Create an Ingress resource named path-rewrite-ingress for domain services.company.com with path rewriting:

    • Request path /shop/products → backend receives /products (route to product-service:8080)
    • Request path /shop/cart → backend receives /cart (route to cart-service:9090)
    • Request path /auth/login → backend receives /login (route to auth-service:7070)
  2. Use NGINX Ingress annotations to implement the rewriting:

    • Use nginx.ingress.kubernetes.io/rewrite-target annotation
    • Use nginx.ingress.kubernetes.io/use-regex: "true" annotation
    • Configure path patterns with regex capture groups
  3. Configure the Ingress to use pathType: ImplementationSpecific for regex-based matching

  4. Update /etc/hosts with services.company.com and test:

    • Verify /shop/products is rewritten to /products on the backend
    • Verify /shop/cart is rewritten to /cart on the backend
    • Verify /auth/login is rewritten to /login on the backend

Verify:

bash
kubectl get ingress -n nginx-practice-apps
kubectl describe ingress path-rewrite-ingress -n nginx-practice-apps
curl -H "Host: services.company.com" http://localhost/shop/products
curl -H "Host: services.company.com" http://localhost/shop/cart
curl -H "Host: services.company.com" http://localhost/auth/login

Question 3: HTTP Redirects - Permanent & Temporary

Objective:

Master HTTP redirects (301 permanent and 302 temporary) for service migration, maintenance mode, and URL restructuring using NGINX Ingress annotations.

Prerequisites:

  • NGINX Ingress Controller is installed
  • user-service (port 4000), admin-service (port 9000), frontend-service (port 8080), product-service (port 8080), and cart-service (port 9090) exist in nginx-practice-apps namespace

Task:

  1. Create 7 separate Ingress resources for domain company.example.com:

    Three 301 Permanent Redirect Ingress Resources:

    • Ingress redirect-301-users: Path /users → 301 redirect to https://newapi.company.com/users
    • Ingress redirect-301-admin: Path /admin → 301 redirect to https://company.example.com/dashboard/admin
    • Ingress redirect-301-products: Path /old/products → 301 redirect to https://company.example.com/catalog

    Three 302 Temporary Redirect Ingress Resources:

    • Ingress redirect-302-maintenance: Path /maintenance → 302 redirect to https://status.company.com
    • Ingress redirect-302-beta: Path /beta → 302 redirect to https://company.example.com/experimental/features
    • Ingress redirect-302-checkout: Path /temp/checkout → 302 redirect to https://company.example.com/cart/process

    One Service Routes Ingress Resource:

    • Ingress service-routes: Contains all actual working routes:
      • /dashboard/admin → routes to admin-service:9000, backend receives /admin
      • /api/users → routes to user-service:4000, backend receives /users
      • /catalog → routes to product-service:8080, backend receives /products
      • /experimental/features → routes to frontend-service:8080, backend receives /beta
      • /cart/process → routes to cart-service:9090, backend receives /checkout
      • / → routes to frontend-service:8080
  2. Use the following NGINX Ingress annotations:

    • For 301 redirects: nginx.ingress.kubernetes.io/permanent-redirect: <URL>
    • For 302 redirects: nginx.ingress.kubernetes.io/temporal-redirect: <URL>
    • For path rewriting: nginx.ingress.kubernetes.io/use-regex: "true" and nginx.ingress.kubernetes.io/rewrite-target: /$1
    • All Ingress resources must use ingressClassName: nginx
  3. Test all scenarios:

    • Verify 301 redirects return HTTP/1.1 301 Moved Permanently with correct Location header
    • Verify 302 redirects return HTTP/1.1 302 Found with correct Location header
    • Verify actual service routes return expected responses (not redirects)

Verify:

bash
kubectl get ingress -n nginx-practice-apps
kubectl describe ingress -n nginx-practice-apps

# Test 301 Permanent Redirects
curl -I -H "Host: company.example.com" http://localhost/users
curl -I -H "Host: company.example.com" http://localhost/admin
curl -I -H "Host: company.example.com" http://localhost/old/products

# Test 302 Temporary Redirects
curl -I -H "Host: company.example.com" http://localhost/maintenance
curl -I -H "Host: company.example.com" http://localhost/beta
curl -I -H "Host: company.example.com" http://localhost/temp/checkout

# Test Actual Service Routes (post-redirect destinations)
curl -H "Host: company.example.com" http://localhost/dashboard/admin
curl -H "Host: company.example.com" http://localhost/api/users
curl -H "Host: company.example.com" http://localhost/catalog
curl -H "Host: company.example.com" http://localhost/experimental/features
curl -H "Host: company.example.com" http://localhost/cart/process

Question 4: TLS Configuration with NGINX Ingress

Objective: Configure HTTPS/TLS termination at the Ingress layer with automatic HTTP-to-HTTPS redirection using NGINX Ingress.

Prerequisites:

  • NGINX Ingress Controller is installed
  • frontend-service (port 8080) and backend-service (port 3000) exist in nginx-practice-apps namespace

Task:

  1. Generate a self-signed TLS certificate for *.company.com:

    • Use openssl to create a private key and certificate
    • Include SANs (Subject Alternative Names) for app.company.com and api.company.com
    • Create a Kubernetes Secret named wildcard-tls in the nginx-practice-apps namespace with the certificate and key
  2. Create an Ingress resource named tls-ingress with TLS configuration:

    • Configure TLS for hosts app.company.com and api.company.com
    • Reference the wildcard-tls secret
    • Route app.company.com traffic to frontend-service:8080
    • Route api.company.com traffic to backend-service:3000
  3. Add NGINX annotations for TLS security:

    • Force SSL redirect: nginx.ingress.kubernetes.io/ssl-redirect: "true"
    • SSL protocols: nginx.ingress.kubernetes.io/ssl-protocols: "TLSv1.2 TLSv1.3"
    • SSL ciphers: Configure strong cipher suites
  4. Test the configuration:

    • Port-forward NGINX Controller on port 443
    • Verify HTTP requests are redirected to HTTPS (307/308 status)
    • Verify HTTPS requests succeed with curl -k (ignore self-signed cert warnings)

Verify:

bash
kubectl get secret wildcard-tls -n nginx-practice-apps
kubectl get ingress -n nginx-practice-apps
kubectl describe ingress tls-ingress -n nginx-practice-apps
curl -I -H "Host: app.company.com" http://localhost  # Should redirect
curl -k -H "Host: app.company.com" https://localhost  # Should succeed
curl -k -H "Host: api.company.com" https://localhost  # Should succeed

Question 5: Exact vs Prefix Path Matching with NGINX

Objective: Understand and implement the difference between Exact and Prefix path matching types in NGINX Ingress. Demonstrate how path matching order and specificity affect routing decisions.

Prerequisites:

  • NGINX Ingress Controller is installed
  • Services exist: health-check:8080, user-service:3000, admin-panel:9000, config-service:4000 in nginx-practice-apps namespace

Task:

  1. Create an Ingress resource named path-matching-ingress for domain mixed.example.com with multiple path types:

    Exact Match Paths (must match the path exactly, no trailing characters):

    • Path /api/health → route to health-check:8080
    • Path /admin → route to admin-panel:9000
    • Path /admin/config → route to config-service:4000

    Prefix Match Paths (matches the path and any sub-paths):

    • Path /api/users → route to user-service:3000 (matches /api/users, /api/users/123, /api/users/123/profile, etc.)

    Default Catch-All:

    • Path / with pathType: Prefix → route to frontend-service:8080 (catches all unmatched paths)
  2. Configure path types correctly:

    • Use pathType: Exact for exact match requirements
    • Use pathType: Prefix for prefix match requirements
    • Understand NGINX path matching precedence (Exact matches take priority over Prefix matches)
  3. Order paths appropriately in the Ingress spec:

    • Place more specific paths (like /admin/config) before less specific ones (like /admin)
    • Place the catch-all / path last
  4. Test all path matching scenarios:

    • Exact matches: /api/health, /admin, /admin/config should route to their specific services
    • Prefix matches: /api/users/123 should route to user-service:3000
    • Non-matches: /api/health/check should NOT match the exact /api/health (should fall through to default)
    • Default: Any unmatched path like /random should route to frontend-service:8080

Expected Behavior:

  • /api/health → health-check:8080 (Exact)
  • /api/health/deep → frontend-service:8080 (no match, falls to default)
  • /api/users → user-service:3000 (Prefix)
  • /api/users/123 → user-service:3000 (Prefix match)
  • /admin → admin-panel:9000 (Exact)
  • /admin/config → config-service:4000 (Exact, more specific than /admin)
  • /admin/other → frontend-service:8080 (no exact match for /admin/other, falls to default)
  • /anything-else → frontend-service:8080 (default catch-all)

Verify:

bash
kubectl get ingress -n nginx-practice-apps
kubectl describe ingress path-matching-ingress -n nginx-practice-apps

# Test exact matches
curl -H "Host: mixed.example.com" http://localhost/api/health
curl -H "Host: mixed.example.com" http://localhost/admin
curl -H "Host: mixed.example.com" http://localhost/admin/config

# Test prefix match
curl -H "Host: mixed.example.com" http://localhost/api/users
curl -H "Host: mixed.example.com" http://localhost/api/users/123

# Test non-matches (should go to default)
curl -H "Host: mixed.example.com" http://localhost/api/health/check
curl -H "Host: mixed.example.com" http://localhost/admin/other
curl -H "Host: mixed.example.com" http://localhost/random

Question 6: Unified API Gateway with Multiple Backend Services

Objective: Build a unified API gateway that aggregates multiple microservices under a single domain using path-based routing. Demonstrate how to create a cohesive API surface that routes to different backend services while maintaining clean URL structure.

Prerequisites:

  • NGINX Ingress Controller is installed
  • Services are running in nginx-practice-apps namespace:
    • product-service:8080 (GET /products, GET /product/{id})
    • cart-service:9090 (GET /cart, POST /checkout, DELETE /clear)
    • user-service:3000 (GET /users, GET /user/{id})
    • config-service:4000 (GET /config, GET /features, GET /services)
    • health-check:8080 (GET /health)

Task:

  1. Create an Ingress resource named api-gateway-ingress for domain gateway.api.io that creates a unified REST API:

    • /api/v1/products → routes to product-service:8080 (strips /api/v1 prefix)
    • /api/v1/cart → routes to cart-service:9090 (strips /api/v1 prefix)
    • /api/v1/users → routes to user-service:3000 (strips /api/v1 prefix)
    • /api/v1/config → routes to config-service:4000 (strips /api/v1 prefix)
    • /health → routes to health-check:8080 (no rewrite)
  2. Use NGINX annotations to implement path rewriting:

    • All /api/v1/* requests should have the /api/v1 prefix stripped before forwarding
    • The /health endpoint should be accessible without modification
    • Use regex patterns to handle sub-paths properly
  3. Add NGINX annotations for API gateway features:

    • nginx.ingress.kubernetes.io/rewrite-target for path stripping
    • nginx.ingress.kubernetes.io/use-regex: "true" for regex matching
    • nginx.ingress.kubernetes.io/cors-allow-origin: "*" to enable CORS
    • nginx.ingress.kubernetes.io/enable-cors: "true"
  4. Test the unified API gateway:

    • Verify product catalog: curl http://localhost/api/v1/products
    • Verify specific product: curl http://localhost/api/v1/products/1 (should call product-service with path /product/1)
    • Verify cart operations: curl http://localhost/api/v1/cart, curl http://localhost/api/v1/cart/checkout
    • Verify user list: curl http://localhost/api/v1/users
    • Verify configuration: curl http://localhost/api/v1/config/features
    • Verify health endpoint: curl http://localhost/health

Expected Routing:

Client Request                    →  Backend Service Receives
-----------------------------------------------------------
GET /api/v1/products              →  product-service: GET /
GET /api/v1/products/1            →  product-service: GET /product/1
GET /api/v1/cart                  →  cart-service: GET /
GET /api/v1/cart/checkout         →  cart-service: GET /checkout
GET /api/v1/users                 →  user-service: GET /
GET /api/v1/users/5               →  user-service: GET /user/5
GET /api/v1/config                →  config-service: GET /
GET /api/v1/config/features       →  config-service: GET /features
GET /health                       →  health-check: GET /

Verify:

bash
kubectl get ingress -n nginx-practice-apps
kubectl describe ingress api-gateway-ingress -n nginx-practice-apps

# Add DNS
echo "127.0.0.1 gateway.api.io" | sudo tee -a /etc/hosts

# Port-forward
kubectl port-forward -n ingress-nginx svc/ingress-nginx-controller 80:80

# Test product endpoints
curl -H "Host: gateway.api.io" http://localhost/api/v1/products
curl -H "Host: gateway.api.io" http://localhost/api/v1/products/1
curl -H "Host: gateway.api.io" http://localhost/api/v1/products/4

# Test cart endpoints
curl -H "Host: gateway.api.io" http://localhost/api/v1/cart
curl -H "Host: gateway.api.io" http://localhost/api/v1/cart/checkout
curl -H "Host: gateway.api.io" http://localhost/api/v1/cart/clear

# Test user endpoints
curl -H "Host: gateway.api.io" http://localhost/api/v1/users
curl -H "Host: gateway.api.io" http://localhost/api/v1/users/1
curl -H "Host: gateway.api.io" http://localhost/api/v1/users/2

# Test config endpoints
curl -H "Host: gateway.api.io" http://localhost/api/v1/config
curl -H "Host: gateway.api.io" http://localhost/api/v1/config/features
curl -H "Host: gateway.api.io" http://localhost/api/v1/config/services

# Test health endpoint
curl -H "Host: gateway.api.io" http://localhost/health

# Verify CORS headers
curl -I -H "Host: gateway.api.io" -H "Origin: http://example.com" http://localhost/api/v1/products

Question 7: Session Affinity and Custom Request Headers

Objective: Configure session affinity (sticky sessions) and custom request headers to build a realistic authentication flow. Demonstrate how to route authenticated requests through an auth service while maintaining session persistence and adding custom headers for downstream services.

Prerequisites:

  • NGINX Ingress Controller is installed
  • Services are running in nginx-practice-apps namespace:
    • auth-service:7070 (GET /login, GET /validate, GET /logout)
    • admin-panel:9000 (HTML dashboard with /api/stats endpoint)
    • backend-service:3000 (JSON API with /stats, /health)
    • frontend-service:8080 (HTML UI)

Task:

  1. Create an Ingress resource named session-ingress for domain secure.app.io with multiple routing scenarios:

    • /auth/* → routes to auth-service:7070 with session affinity enabled
    • /admin/* → routes to admin-panel:9000 with custom headers
    • /api/* → routes to backend-service:3000 with custom headers
    • / → routes to frontend-service:8080 (default)
  2. Configure session affinity for authentication service:

    • Use nginx.ingress.kubernetes.io/affinity: "cookie" annotation
    • Set nginx.ingress.kubernetes.io/session-cookie-name: "auth-session"
    • Set nginx.ingress.kubernetes.io/session-cookie-max-age: "3600" (1 hour)
    • Use nginx.ingress.kubernetes.io/affinity-mode: "persistent"
  3. Add custom headers for all backend requests:

    • nginx.ingress.kubernetes.io/configuration-snippet to add headers:
      • X-Forwarded-User: authenticated
      • X-Request-ID: $request_id (NGINX variable)
      • X-Real-IP: $remote_addr (NGINX variable)
    • Use proxy_set_header directives in configuration snippet
  4. Configure path rewriting for admin and API routes:

    • /admin/* should forward with path intact (no rewrite)
    • /api/* should strip /api prefix using rewrite-target
    • /auth/* should strip /auth prefix
  5. Test session affinity and headers:

    • Make multiple requests to /auth/login and verify session cookie is set
    • Verify subsequent requests use the same backend pod (check pod logs)
    • Test that /admin/ returns admin dashboard HTML
    • Test that /admin/api/stats returns JSON stats from admin-panel
    • Verify custom headers are added to requests (check backend service logs or responses)
    • Test that /api/stats routes to backend-service (not admin-panel)

Expected Routing with Headers:

Request: GET /auth/login
→ auth-service:7070 GET /login
→ Response includes: Set-Cookie: auth-session=<hash>

Request: GET /auth/validate (with auth-session cookie)
→ Same auth-service pod: GET /validate
→ Sticky session maintained

Request: GET /admin/
→ admin-panel:9000 GET /
→ Headers added: X-Forwarded-User, X-Request-ID, X-Real-IP

Request: GET /api/stats
→ backend-service:3000 GET /stats
→ Headers added: X-Forwarded-User, X-Request-ID, X-Real-IP

Verify:

bash
kubectl get ingress -n nginx-practice-apps
kubectl describe ingress session-ingress -n nginx-practice-apps

# Add DNS
echo "127.0.0.1 secure.app.io" | sudo tee -a /etc/hosts

# Port-forward
kubectl port-forward -n ingress-nginx svc/ingress-nginx-controller 80:80

# Test authentication with session cookies
curl -c cookies.txt -H "Host: secure.app.io" http://localhost/auth/login
curl -b cookies.txt -H "Host: secure.app.io" http://localhost/auth/validate
curl -b cookies.txt -H "Host: secure.app.io" http://localhost/auth/validate
# Verify multiple validate requests go to same pod (check pod name in logs)

# Test admin panel
curl -H "Host: secure.app.io" http://localhost/admin/
curl -H "Host: secure.app.io" http://localhost/admin/api/stats

# Test API endpoints
curl -H "Host: secure.app.io" http://localhost/api/stats
curl -H "Host: secure.app.io" http://localhost/api/health

# Test default route
curl -H "Host: secure.app.io" http://localhost/

# Verify session cookie details
curl -v -H "Host: secure.app.io" http://localhost/auth/login 2>&1 | grep -i "set-cookie"

# Check backend logs to verify custom headers (X-Request-ID, X-Real-IP)
kubectl logs -n nginx-practice-apps -l app=backend --tail=10
kubectl logs -n nginx-practice-apps -l app=admin-panel --tail=10

# Test session persistence (make 5 requests, check pod names)
for i in {1..5}; do
  curl -b cookies.txt -s -H "Host: secure.app.io" http://localhost/auth/validate
  sleep 1
done

Challenge Questions:

  1. What happens if you don't include the session cookie in subsequent requests?
  2. How can you verify that requests to /auth/login are going to different pods when no cookie is present?
  3. What is the difference between affinity-mode: "balanced" and affinity-mode: "persistent"?
  4. How would you configure different session cookie settings for different paths within the same Ingress?

Question 8: Advanced Redirects for API Versioning and Migration

Objective: Implement complex redirect scenarios for API versioning, domain migrations, and URL consolidation. Use NGINX Ingress annotations to handle permanent (301) and temporary (302) redirects, regex-based redirects, and redirect chaining for real-world migration scenarios.

Prerequisites:

  • NGINX Ingress Controller is installed
  • Services running in nginx-practice-apps namespace:
    • backend-service:3000 (v2 API endpoint)
    • product-service:8080 (new products API)
    • frontend-service:8080 (new website)

Task:

  1. Create an Ingress resource named migration-redirects-ingress for domain legacy.shop.io with multiple redirect patterns:

    API Version Migration (301 Permanent):

    • /api/v1/* → redirect to /api/v2/* (permanent migration)
    • Old v1 endpoints should redirect to v2 equivalents
    • Example: /api/v1/products → redirects to /api/v2/products

    Legacy Product URLs (301 Permanent):

    • /products.php?id=* → redirect to /products/* (clean URL migration)
    • /catalog/* → redirect to /products/* (path consolidation)

    Maintenance Mode (302 Temporary):

    • /admin/* → temporary redirect to /maintenance.html
    • /checkout → temporary redirect to /maintenance.html

    Domain Migration (301 with full URL):

    • Use server-snippet to redirect specific paths to external domain
    • /blog/* → redirect to https://blog.newshop.com/*
  2. Configure redirects using NGINX annotations:

    • Use nginx.ingress.kubernetes.io/permanent-redirect for 301 redirects
    • Use nginx.ingress.kubernetes.io/temporal-redirect for 302 redirects
    • Use nginx.ingress.kubernetes.io/configuration-snippet for complex redirect logic
    • Use nginx.ingress.kubernetes.io/server-snippet for server-level redirects
  3. Set up backend routes for new API versions:

    • /api/v2/* → routes to backend-service:3000 (strip /api/v2 prefix)
    • /products/* → routes to product-service:8080 (strip /products prefix)
    • / → routes to frontend-service:8080 (default)
  4. Test all redirect scenarios:

    • Verify API v1 to v2 redirects with correct status codes
    • Test legacy product URL redirects
    • Verify temporary maintenance redirects
    • Check that redirected requests can be followed to final destination
    • Validate redirect loop prevention

Redirect Configuration Examples:

yaml
# Using configuration-snippet for regex redirects
nginx.ingress.kubernetes.io/configuration-snippet: |
  # API v1 to v2 migration (301)
  if ($request_uri ~ ^/api/v1/(.*)$) {
    return 301 /api/v2/$1;
  }
  
  # Legacy catalog to products (301)
  if ($request_uri ~ ^/catalog/(.*)$) {
    return 301 /products/$1;
  }
  
  # Maintenance mode (302)
  if ($request_uri ~ ^/(admin|checkout)) {
    return 302 /maintenance.html;
  }

# Using server-snippet for external redirects
nginx.ingress.kubernetes.io/server-snippet: |
  location ~ ^/blog/(.*)$ {
    return 301 https://blog.newshop.com/$1;
  }

Expected Redirect Behavior:

Client Request                    →  Redirect Response              →  Final Destination
----------------------------------------------------------------------------------------
GET /api/v1/products              →  301 → /api/v2/products        →  backend-service:3000 /stats
GET /api/v1/users/123             →  301 → /api/v2/users/123      →  backend-service:3000 /stats
GET /products.php?id=5            →  301 → /products/5            →  product-service:8080 /product/5
GET /catalog/items                →  301 → /products/items        →  product-service:8080 /
GET /admin/dashboard              →  302 → /maintenance.html     →  frontend-service:8080 (temp)
GET /checkout                     →  302 → /maintenance.html     →  frontend-service:8080 (temp)
GET /blog/post-123                →  301 → https://blog.newshop.com/post-123 (external)
GET /                             →  200 (direct)                →  frontend-service:8080

Verify:

bash
kubectl get ingress -n nginx-practice-apps
kubectl describe ingress migration-redirects-ingress -n nginx-practice-apps

# Add DNS
echo "127.0.0.1 legacy.shop.io" | sudo tee -a /etc/hosts

# Port-forward
kubectl port-forward -n ingress-nginx svc/ingress-nginx-controller 80:80

# Test API v1 to v2 redirects (301 permanent)
curl -I -H "Host: legacy.shop.io" http://localhost/api/v1/products
# Expected: HTTP/1.1 301 Moved Permanently, Location: /api/v2/products

curl -I -H "Host: legacy.shop.io" http://localhost/api/v1/users/123
# Expected: HTTP/1.1 301 Moved Permanently, Location: /api/v2/users/123

# Follow the redirect chain to final destination
curl -L -H "Host: legacy.shop.io" http://localhost/api/v1/products
# Should get backend-service response

# Test legacy catalog redirects (301 permanent)
curl -I -H "Host: legacy.shop.io" http://localhost/catalog/items
# Expected: HTTP/1.1 301 Moved Permanently, Location: /products/items

curl -L -H "Host: legacy.shop.io" http://localhost/catalog/items
# Should get product-service response

# Test maintenance mode redirects (302 temporary)
curl -I -H "Host: legacy.shop.io" http://localhost/admin/dashboard
# Expected: HTTP/1.1 302 Found, Location: /maintenance.html

curl -I -H "Host: legacy.shop.io" http://localhost/checkout
# Expected: HTTP/1.1 302 Found, Location: /maintenance.html

# Test external blog redirect (301 permanent to external domain)
curl -I -H "Host: legacy.shop.io" http://localhost/blog/post-123
# Expected: HTTP/1.1 301 Moved Permanently, Location: https://blog.newshop.com/post-123

# Test direct routes (no redirect)
curl -H "Host: legacy.shop.io" http://localhost/api/v2/stats
# Should get backend-service response

curl -H "Host: legacy.shop.io" http://localhost/products
# Should get product-service response

curl -H "Host: legacy.shop.io" http://localhost/
# Should get frontend-service response

# Verify redirect doesn't create loops
curl -L -v -H "Host: legacy.shop.io" http://localhost/api/v1/products 2>&1 | grep -E "HTTP|Location"

# Test with browser headers
curl -I -H "Host: legacy.shop.io" -H "User-Agent: Mozilla/5.0" http://localhost/api/v1/products

Advanced Testing:

bash
# Count redirect hops
curl -s -o /dev/null -w "Redirects: %{num_redirects}\nFinal URL: %{url_effective}\n" \
  -L -H "Host: legacy.shop.io" http://localhost/api/v1/products

# Check redirect performance
time curl -L -s -H "Host: legacy.shop.io" http://localhost/api/v1/products > /dev/null

# Verify no redirect loops (should complete or timeout gracefully)
curl -L --max-redirs 10 -H "Host: legacy.shop.io" http://localhost/api/v1/products

Debugging Tips:

  1. Use curl -I to see only headers and status codes
  2. Use curl -L to follow redirects automatically
  3. Use curl -v for verbose output showing all redirect steps
  4. Check NGINX logs: kubectl logs -n ingress-nginx -l app.kubernetes.io/component=controller
  5. Verify regex patterns match expected URLs before implementing

Cleanup:

bash
kubectl delete ingress migration-redirects-ingress -n nginx-practice-apps
sudo sed -i '/legacy\.shop\.io/d' /etc/hosts

Released under the MIT License.