Skip to main content

Overview

NGINX Ingress Controller manages external access to services in your Kubernetes cluster, providing HTTP and HTTPS routing, load balancing, and TLS termination.

Installation

Install the NGINX Ingress Controller using the official manifest:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.12.2/deploy/static/provider/cloud/deploy.yaml
This deploys the ingress controller along with the necessary resources (namespace, service account, roles, and service) to the ingress-nginx namespace.

Basic Ingress Configuration

Multiple Host Routing

Route traffic to different services based on the hostname:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-nginx
spec:
  ingressClassName: nginx
  rules:
    - host: exchange-backend.jogeshwar.xyz
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: exchange-router-service
                port:
                  number: 80
    - host: exchange-ws.jogeshwar.xyz
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: exchange-ws-stream-service
                port:
                  number: 80

Path-Based Routing

Path Types

Kubernetes Ingress supports three path matching types:
  • Exact: Matches the URL path exactly as specified
  • Prefix: Matches based on a URL path prefix split by /
  • ImplementationSpecific: Delegates path matching to the ingress controller (enables regex for NGINX)

Single Host with Multiple Paths

Route different paths to different backend services:
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

URL Rewriting

Understanding Rewrite Rules

The nginx.ingress.kubernetes.io/rewrite-target annotation rewrites the request path before forwarding to the backend.

Regex Capture Groups

For a path like /backend(/|$)(.*):
  • /backend - Literal prefix to match
  • (/|$) - First capture group $1: matches either / or end of string
  • (.*) - Second capture group $2: captures everything after the prefix

Example

With the annotation nginx.ingress.kubernetes.io/rewrite-target: /$2: Request: https://exchange.jogeshwar.xyz/backend/api/orders Rewritten path: /api/orders (the /backend prefix is removed) Backend receives: GET /api/orders This is useful when your backend service expects paths without the ingress prefix.

TLS Configuration

Automatic Certificate Management

Integrate with cert-manager for automatic TLS certificate provisioning:
metadata:
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  tls:
    - hosts:
        - exchange.jogeshwar.xyz
      secretName: exchange-tls
The cert-manager.io/cluster-issuer annotation tells cert-manager to automatically create and renew certificates using the specified ClusterIssuer.
The secretName specified in the TLS configuration will be automatically created by cert-manager. The certificate will be stored in this Secret and used by the Ingress Controller for TLS termination.

Common Annotations

SSL/TLS

metadata:
  annotations:
    # Force redirect HTTP to HTTPS
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
    
    # Custom SSL redirect code
    nginx.ingress.kubernetes.io/ssl-redirect: "true"

CORS Configuration

metadata:
  annotations:
    nginx.ingress.kubernetes.io/enable-cors: "true"
    nginx.ingress.kubernetes.io/cors-allow-origin: "https://example.com"
    nginx.ingress.kubernetes.io/cors-allow-methods: "GET, POST, PUT, DELETE, OPTIONS"

Request Size Limits

metadata:
  annotations:
    # Allow larger file uploads
    nginx.ingress.kubernetes.io/proxy-body-size: "50m"

Custom Timeouts

metadata:
  annotations:
    nginx.ingress.kubernetes.io/proxy-connect-timeout: "60"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "60"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "60"

Verification

Check ingress resources:
# List all ingress resources
kubectl get ingress

# Describe specific ingress
kubectl describe ingress ingress-nginx

# View ingress controller logs
kubectl logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx

# Check ingress controller service
kubectl get svc -n ingress-nginx

Best Practices

Use IngressClass

Always specify ingressClassName: nginx to ensure your Ingress uses the correct controller

TLS Everywhere

Enable TLS for all production endpoints using cert-manager integration

Rate Limiting

Protect your services with rate limiting annotations to prevent abuse

Monitoring

Monitor ingress controller metrics and logs for traffic patterns and errors

Troubleshooting

Ingress Not Working

# Check if ingress controller is running
kubectl get pods -n ingress-nginx

# Check ingress events
kubectl describe ingress <ingress-name>

# Verify service endpoints
kubectl get endpoints <service-name>

404 Errors

  • Verify the pathType matches your routing requirements
  • Check if rewrite rules are stripping necessary path components
  • Ensure backend service is running and accessible

TLS Certificate Issues

# Check certificate status
kubectl get certificate

# Verify TLS secret exists
kubectl get secret exchange-tls

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

Build docs developers (and LLMs) love