Skip to main content
This page documents the Ingress configuration used in the exchange platform. The Ingress provides external access to services via HTTP/HTTPS, handles TLS termination, and routes requests based on URL paths.

Complete Ingress Manifest

Location: ingress/ingress.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-nginx
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  ingressClassName: nginx
  tls:
    - hosts:
        - exchange.jogeshwar.xyz
      secretName: exchange-tls
  rules:
    - host: exchange.jogeshwar.xyz
      http:
        paths:
          - path: /backend(/|$)(.*)
            pathType: ImplementationSpecific
            backend:
              service:
                name: exchange-router-service
                port:
                  number: 80
          - path: /ws
            pathType: ImplementationSpecific
            backend:
              service:
                name: exchange-ws-stream-service
                port:
                  number: 80

Configuration Overview

Metadata

metadata:
  name: ingress-nginx
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
    cert-manager.io/cluster-issuer: letsencrypt-prod
Annotations:
  • nginx.ingress.kubernetes.io/rewrite-target: /$2 - URL rewriting for path stripping
  • cert-manager.io/cluster-issuer: letsencrypt-prod - Automatic TLS certificate provisioning

Ingress Class

spec:
  ingressClassName: nginx
Specifies NGINX Ingress Controller to handle this Ingress resource.

TLS Configuration

TLS Settings

tls:
  - hosts:
      - exchange.jogeshwar.xyz
    secretName: exchange-tls
Configuration:
  • Hosts: TLS certificate valid for exchange.jogeshwar.xyz
  • Secret: Certificate and private key stored in exchange-tls Secret
  • Issuer: Automatically provisioned by cert-manager using Let’s Encrypt

Certificate Management

The cert-manager.io/cluster-issuer annotation triggers automatic certificate lifecycle management:
  1. Initial Provisioning:
    • cert-manager detects new Ingress
    • Requests certificate from Let’s Encrypt
    • Completes ACME challenge (HTTP-01)
    • Stores certificate in exchange-tls Secret
  2. Automatic Renewal:
    • Monitors certificate expiration
    • Renews 30 days before expiry
    • Updates Secret with new certificate
    • Zero-downtime renewal

TLS Secret Structure

apiVersion: v1
kind: Secret
metadata:
  name: exchange-tls
type: kubernetes.io/tls
data:
  tls.crt: <base64-encoded-certificate>
  tls.key: <base64-encoded-private-key>

Path Routing

Backend Router Path

- path: /backend(/|$)(.*)
  pathType: ImplementationSpecific
  backend:
    service:
      name: exchange-router-service
      port:
        number: 80
Routing Details:
  • Pattern: /backend(/|$)(.*) - Matches /backend, /backend/, and /backend/*
  • Service: Routes to exchange-router-service on port 80
  • Path Type: ImplementationSpecific - Uses NGINX-specific regex matching
  • Rewrite: Strips /backend prefix via annotation
Examples:
https://exchange.jogeshwar.xyz/backend/api/v1/orders
  → http://exchange-router-service:80/api/v1/orders

https://exchange.jogeshwar.xyz/backend/health
  → http://exchange-router-service:80/health

WebSocket Path

- path: /ws
  pathType: ImplementationSpecific
  backend:
    service:
      name: exchange-ws-stream-service
      port:
        number: 80
Routing Details:
  • Pattern: /ws - Exact match for WebSocket endpoint
  • Service: Routes to exchange-ws-stream-service on port 80
  • Path Type: ImplementationSpecific
  • Protocol: Supports WebSocket upgrade
Examples:
wss://exchange.jogeshwar.xyz/ws
  → ws://exchange-ws-stream-service:80/ws

URL Rewriting

Rewrite Target Annotation

annotations:
  nginx.ingress.kubernetes.io/rewrite-target: /$2
How It Works: The annotation uses capture groups from the path regex:
path: /backend(/|$)(.*)
        ─┬─  ─┬──  ─┬─
         │    │     │
         │    │     └─ $2 = everything after /backend/
         │    └─────── $1 = / or empty
         └──────────── literal /backend
Rewrite Examples:
Original RequestCapture $2Rewritten Path
/backend/api/ordersapi/orders/api/orders
/backend/healthhealth/health
/backend//

Why Path Rewriting?

Without Rewrite:
Request: GET /backend/api/orders
Backend receives: GET /backend/api/orders
Result: 404 (backend doesn't have /backend prefix)
With Rewrite:
Request: GET /backend/api/orders
Backend receives: GET /api/orders
Result: 200 (correct path)

Path Types

ImplementationSpecific

pathType: ImplementationSpecific
Allows NGINX-specific features:
  • Regex pattern matching
  • Capture groups for rewriting
  • Advanced routing rules

Alternative Path Types

Exact:
path: /ws
pathType: Exact
Matches only /ws exactly (no trailing slash or subpaths). Prefix:
path: /backend
pathType: Prefix
Matches /backend, /backend/, /backend/* (standard prefix matching).

Ingress Controller

NGINX Ingress Controller

The platform uses the NGINX Ingress Controller:
ingressClassName: nginx
Features:
  • High-performance L7 load balancing
  • WebSocket support
  • URL rewriting and redirects
  • Rate limiting and authentication
  • Custom error pages

Installation

# Install NGINX Ingress Controller
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.1/deploy/static/provider/cloud/deploy.yaml

# Verify installation
kubectl get pods -n ingress-nginx
kubectl get service -n ingress-nginx

Request Flow

Complete Request Path

1. Client (Browser/App)

   HTTPS Request: https://exchange.jogeshwar.xyz/backend/api/orders

2. DNS Resolution

   exchange.jogeshwar.xyz → Load Balancer IP

3. NGINX Ingress Controller (TLS Termination)

   - Decrypt HTTPS → HTTP
   - Match host: exchange.jogeshwar.xyz
   - Match path: /backend/api/orders
   - Apply rewrite: /backend/api/orders → /api/orders

4. Service (exchange-router-service:80)

   - Load balance across pods

5. Pod (exchange-router:8080)

   - Process request: GET /api/orders
   - Return response

6. Response flows back through same path

   HTTPS Response to client

WebSocket Request Flow

1. Client WebSocket Connection

   wss://exchange.jogeshwar.xyz/ws

2. NGINX Ingress Controller

   - Detect WebSocket upgrade headers
   - Match path: /ws
   - No rewrite (no capture groups)

3. Service (exchange-ws-stream-service:80)

4. Pod (exchange-ws-stream:4000)

   - Upgrade to WebSocket protocol
   - Maintain persistent connection

Advanced Annotations

Common NGINX Annotations

annotations:
  # URL Rewriting
  nginx.ingress.kubernetes.io/rewrite-target: /$2
  
  # CORS Configuration
  nginx.ingress.kubernetes.io/enable-cors: "true"
  nginx.ingress.kubernetes.io/cors-allow-origin: "https://app.example.com"
  
  # Rate Limiting
  nginx.ingress.kubernetes.io/limit-rps: "10"
  
  # WebSocket Configuration
  nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
  nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
  
  # SSL Redirect
  nginx.ingress.kubernetes.io/ssl-redirect: "true"
  
  # Client Body Size
  nginx.ingress.kubernetes.io/proxy-body-size: "8m"

cert-manager Annotations

annotations:
  # Certificate Issuer
  cert-manager.io/cluster-issuer: letsencrypt-prod
  
  # Alternative: Namespace Issuer
  cert-manager.io/issuer: letsencrypt-staging
  
  # ACME Challenge Type
  cert-manager.io/acme-challenge-type: http01

Multiple Host Example

Extend Ingress for multiple domains:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-nginx
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  ingressClassName: nginx
  tls:
    - hosts:
        - exchange.jogeshwar.xyz
        - api.jogeshwar.xyz
      secretName: exchange-tls
  rules:
    - host: exchange.jogeshwar.xyz
      http:
        paths:
          - path: /backend(/|$)(.*)
            pathType: ImplementationSpecific
            backend:
              service:
                name: exchange-router-service
                port:
                  number: 80
    - host: api.jogeshwar.xyz
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: exchange-router-service
                port:
                  number: 80

Operations

Apply Ingress

kubectl apply -f ingress.yml

Check Ingress Status

# List ingresses
kubectl get ingress

# Detailed info
kubectl describe ingress ingress-nginx

# Check certificate status
kubectl get certificate
kubectl describe certificate exchange-tls

View Ingress Logs

# NGINX Ingress Controller logs
kubectl logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx

# Follow logs
kubectl logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx -f

Test Ingress Routing

# Test HTTPS endpoint
curl -v https://exchange.jogeshwar.xyz/backend/health

# Test with custom headers
curl -H "Host: exchange.jogeshwar.xyz" http://<ingress-ip>/backend/health

# Test WebSocket
wscat -c wss://exchange.jogeshwar.xyz/ws

Troubleshooting

Certificate Issues

# Check certificate request
kubectl get certificaterequest

# Check cert-manager logs
kubectl logs -n cert-manager -l app=cert-manager

# Describe certificate for error details
kubectl describe certificate exchange-tls

Routing Issues

# Check Ingress configuration
kubectl get ingress ingress-nginx -o yaml

# Verify backend services exist
kubectl get service exchange-router-service

# Check NGINX configuration
kubectl exec -n ingress-nginx <nginx-pod> -- cat /etc/nginx/nginx.conf

Path Rewrite Issues

# Enable NGINX debug logging
kubectl annotate ingress ingress-nginx nginx.ingress.kubernetes.io/enable-access-log="true"

# Check rewrite logs
kubectl logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx | grep rewrite

Best Practices

  1. Use TLS: Always enable HTTPS for production traffic
  2. cert-manager: Automate certificate management with cert-manager
  3. Path Design: Use clear, RESTful path structures
  4. Rewrite Rules: Test rewrite rules thoroughly before production
  5. WebSocket Support: Configure appropriate timeouts for long-lived connections
  6. Rate Limiting: Protect backend services with rate limits
  7. Monitoring: Monitor Ingress controller metrics and logs
  8. Multiple Environments: Use different hosts/paths for staging and production

Security Considerations

  1. TLS Version: Ensure TLS 1.2+ is enforced
  2. Certificate Validation: Use production Let’s Encrypt issuer
  3. CORS: Configure CORS policies for API endpoints
  4. Rate Limiting: Prevent abuse with rate limits
  5. Authentication: Add authentication annotations for sensitive paths
  6. IP Whitelisting: Restrict access by source IP if needed

Build docs developers (and LLMs) love