Skip to main content

NGINX Ingress Controller

Purpose: HTTP/HTTPS ingress routing for Kubernetes

Version: 4.11.3

Namespace: ingress-nginx

Description

Routes external traffic to services based on ingress rules. Handles TLS termination, path-based routing, and host-based virtual hosting.

Installation

Installed via ArgoCD from Helm chart: ingress-nginx/ingress-nginx

Configuration

The ingress controller is configured with:

  • Service Type: LoadBalancer (via MetalLB)
  • Ingress Class: nginx (default)
  • TLS: Termination at ingress, HTTP backend
  • External Traffic Policy: Local (preserves client source IP)
  • IP Family Policy: SingleStack (IPv4 only)
  • Publish Service: Enabled (advertises LoadBalancer IP)

Client IP Preservation

The ingress controller is configured with externalTrafficPolicy: Local to preserve client source IP addresses. This prevents Source Network Address Translation (SNAT) by routing traffic only to pods running on the same node that received the traffic.

Benefits:

  • Client IP is visible in application logs and headers
  • Accurate rate limiting per client IP
  • Better security auditing and access control

Trade-off:

  • Traffic distribution may be less balanced (node-dependent)

Access

  • HTTP: Port 80 (redirects to HTTPS)
  • HTTPS: Port 443
  • External IP: Assigned by MetalLB from pool

Usage

Basic Ingress

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-app
namespace: default
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
ingressClassName: nginx
tls:
- hosts:
- myapp.ssdk8s.xyz
secretName: myapp-tls
rules:
- host: myapp.ssdk8s.xyz
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-service
port:
number: 80

Path-Based Routing

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: multi-service
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
ingressClassName: nginx
tls:
- hosts:
- api.ssdk8s.xyz
secretName: api-tls
rules:
- host: api.ssdk8s.xyz
http:
paths:
- path: /v1
pathType: Prefix
backend:
service:
name: api-v1
port:
number: 80
- path: /v2
pathType: Prefix
backend:
service:
name: api-v2
port:
number: 80

Annotations

AnnotationDescription
cert-manager.io/cluster-issuerCertificate issuer for TLS
nginx.ingress.kubernetes.io/ssl-redirectForce HTTPS redirect
nginx.ingress.kubernetes.io/proxy-body-sizeMax request body size
nginx.ingress.kubernetes.io/rate-limitRate limiting
nginx.ingress.kubernetes.io/whitelist-source-rangeAllow specific IP ranges

Troubleshooting

Check Ingress Status

kubectl get ingress -A
kubectl describe ingress <name> -n <namespace>

Check Controller Logs

kubectl logs -n ingress-nginx -l app.kubernetes.io/component=controller

Verify Client IP Preservation

Check that client IP is preserved in ingress controller logs:

kubectl logs -n ingress-nginx -l app.kubernetes.io/component=controller | grep -i "remote-addr"

Common Issues

  1. 404 errors - Check ingress rules and service ports
  2. TLS not working - Verify cert-manager created the secret
  3. 502 Bad Gateway - Backend service not ready or wrong port
  4. Uneven traffic distribution - Expected with externalTrafficPolicy: Local; ensure multiple replicas across nodes