Skip to main content

NGINX Ingress

NGINX Ingress Controllers provide high-performance HTTP/HTTPS load balancing and routing for the Anton cluster, with separate controllers for external and internal traffic patterns.

Architecture

Dual Controller Setup

External Ingress Controller

  • Purpose: Handle traffic from Cloudflare tunnel
  • IngressClass: external
  • Load Balancer: ClusterIP (internal routing)
  • TLS: Let's Encrypt certificates
  • Access: Public internet via Cloudflare

Internal Ingress Controller

  • Purpose: Handle local network traffic
  • IngressClass: internal
  • Load Balancer: NodePort or LoadBalancer
  • TLS: Internal CA certificates
  • Access: Local network only

Controller Configuration

External Controller

# NGINX External Ingress Controller
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-ingress-external
namespace: network
spec:
replicas: 2
selector:
matchLabels:
app: nginx-ingress-external
template:
spec:
containers:
- name: controller
image: registry.k8s.io/ingress-nginx/controller:v1.8.1
args:
- /nginx-ingress-controller
- --ingress-class=external
- --configmap=network/nginx-external-config
- --default-ssl-certificate=network/external-tls-secret
- --enable-ssl-passthrough
- --metrics-bind-address=0.0.0.0:10254
ports:
- name: http
containerPort: 80
- name: https
containerPort: 443
- name: metrics
containerPort: 10254

Internal Controller

# NGINX Internal Ingress Controller
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-ingress-internal
namespace: network
spec:
replicas: 2
template:
spec:
containers:
- name: controller
image: registry.k8s.io/ingress-nginx/controller:v1.8.1
args:
- /nginx-ingress-controller
- --ingress-class=internal
- --configmap=network/nginx-internal-config
- --default-backend-service=network/default-backend
- --publish-service=network/nginx-internal-lb

Ingress Resource Examples

External Service Ingress

# Public service accessible via Cloudflare
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: grafana-external
namespace: monitoring
annotations:
kubernetes.io/ingress.class: external
cert-manager.io/cluster-issuer: letsencrypt-prod
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
spec:
tls:
- hosts:
- grafana.example.com
secretName: grafana-tls
rules:
- host: grafana.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: kube-prometheus-stack-grafana
port:
number: 80

Internal Service Ingress

# Internal service for local network access
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: grafana-internal
namespace: monitoring
annotations:
kubernetes.io/ingress.class: internal
cert-manager.io/cluster-issuer: ca-issuer
nginx.ingress.kubernetes.io/auth-type: basic
nginx.ingress.kubernetes.io/auth-secret: basic-auth
spec:
tls:
- hosts:
- grafana.local
secretName: grafana-internal-tls
rules:
- host: grafana.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: kube-prometheus-stack-grafana
port:
number: 80

Performance Tuning

Global Configuration

# NGINX performance configuration
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-external-config
namespace: network
data:
# Worker processes and connections
worker-processes: "auto"
worker-connections: "1024"
worker-rlimit-nofile: "65535"

# Performance tuning
keepalive-timeout: "65"
keepalive-requests: "100"
client-body-buffer-size: "128k"
client-max-body-size: "50m"
proxy-buffer-size: "4k"
proxy-buffers: "8 4k"

# Compression
enable-gzip: "true"
gzip-level: "6"
gzip-types: "text/plain application/json application/javascript text/css application/xml text/xml application/xml+rss text/javascript"

# SSL optimization
ssl-protocols: "TLSv1.2 TLSv1.3"
ssl-ciphers: "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384"
ssl-session-cache: "shared:SSL:10m"
ssl-session-timeout: "10m"

Per-Service Optimization

# Service-specific NGINX annotations
metadata:
annotations:
# Rate limiting
nginx.ingress.kubernetes.io/rate-limit: "100"
nginx.ingress.kubernetes.io/rate-limit-window: "1m"

# Connection limits
nginx.ingress.kubernetes.io/limit-connections: "20"

# Proxy timeouts
nginx.ingress.kubernetes.io/proxy-connect-timeout: "5"
nginx.ingress.kubernetes.io/proxy-send-timeout: "60"
nginx.ingress.kubernetes.io/proxy-read-timeout: "60"

# Buffer sizes
nginx.ingress.kubernetes.io/proxy-buffer-size: "16k"
nginx.ingress.kubernetes.io/proxy-buffers-number: "8"

# Enable caching
nginx.ingress.kubernetes.io/proxy-cache-valid: "200 302 10m"
nginx.ingress.kubernetes.io/proxy-cache-valid: "404 1m"

Load Balancing

Backend Selection

# Load balancing algorithm configuration
metadata:
annotations:
# Round-robin (default)
nginx.ingress.kubernetes.io/upstream-hash-by: ""

# IP hash for session persistence
nginx.ingress.kubernetes.io/upstream-hash-by: "$remote_addr"

# Cookie-based persistence
nginx.ingress.kubernetes.io/affinity: "cookie"
nginx.ingress.kubernetes.io/session-cookie-name: "nginx-ingress"
nginx.ingress.kubernetes.io/session-cookie-expires: "86400"
nginx.ingress.kubernetes.io/session-cookie-max-age: "86400"
nginx.ingress.kubernetes.io/session-cookie-path: "/"

Health Checks

# Backend health monitoring
metadata:
annotations:
# Health check path
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
nginx.ingress.kubernetes.io/upstream-vhost: "$service_name.$namespace.svc.cluster.local"

# Custom health check
nginx.ingress.kubernetes.io/custom-http-errors: "404,503"
nginx.ingress.kubernetes.io/default-backend: "network/custom-default-backend"

Security Features

Authentication

# Basic authentication
metadata:
annotations:
nginx.ingress.kubernetes.io/auth-type: basic
nginx.ingress.kubernetes.io/auth-secret: basic-auth-secret
nginx.ingress.kubernetes.io/auth-realm: "Restricted Area"

---
# OAuth2 authentication with external provider
metadata:
annotations:
nginx.ingress.kubernetes.io/auth-url: "https://auth.example.com/oauth2/auth"
nginx.ingress.kubernetes.io/auth-signin: "https://auth.example.com/oauth2/start"
nginx.ingress.kubernetes.io/auth-response-headers: "X-Auth-Request-User,X-Auth-Request-Email"

SSL/TLS Configuration

# SSL/TLS security headers
metadata:
annotations:
# HSTS
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"

# Security headers
nginx.ingress.kubernetes.io/configuration-snippet: |
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;

Access Control

# IP-based access control
metadata:
annotations:
nginx.ingress.kubernetes.io/whitelist-source-range: "192.168.1.0/24,10.0.0.0/8"
nginx.ingress.kubernetes.io/deny-source-range: "192.168.100.0/24"

# Geographic restrictions (requires GeoIP module)
metadata:
annotations:
nginx.ingress.kubernetes.io/server-snippet: |
if ($geoip_country_code != US) {
return 403;
}

Monitoring and Observability

Prometheus Metrics

# ServiceMonitor for NGINX metrics
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: nginx-ingress-metrics
spec:
selector:
matchLabels:
app: nginx-ingress
endpoints:
- port: metrics
path: /metrics
interval: 30s

Key Metrics to Monitor

# Request rate per ingress
sum(rate(nginx_ingress_controller_requests_total[5m])) by (ingress)

# Response time percentiles
histogram_quantile(0.95,
sum(rate(nginx_ingress_controller_request_duration_seconds_bucket[5m])) by (le, ingress)
)

# Error rate
sum(rate(nginx_ingress_controller_requests_total{status!~"2.."}[5m])) by (ingress)

# Active connections
nginx_ingress_controller_nginx_process_connections

Log Analysis

# View NGINX access logs
kubectl logs -n network -l app=nginx-ingress-external | grep access

# Monitor error logs
kubectl logs -n network -l app=nginx-ingress-external | grep error

# Real-time log streaming
kubectl logs -n network -f deployment/nginx-ingress-external

Management Commands

Controller Management

# Check controller status
kubectl get pods -n network -l app=nginx-ingress

# View controller configuration
kubectl get configmap -n network nginx-external-config -o yaml

# Restart controllers
kubectl rollout restart deployment/nginx-ingress-external -n network
kubectl rollout restart deployment/nginx-ingress-internal -n network

# Check ingress resources
kubectl get ingress -A

SSL Certificate Management

# View TLS certificates
kubectl get certificates -A

# Check certificate status
kubectl describe certificate grafana-tls -n monitoring

# Manual certificate renewal (if needed)
kubectl delete secret grafana-tls -n monitoring
# cert-manager will automatically recreate

Debugging

# Test ingress connectivity
kubectl run test-client --image=curlimages/curl --rm -it -- \
curl -H "Host: grafana.example.com" http://nginx-external/

# Check backend service connectivity
kubectl exec -n network deployment/nginx-ingress-external -- \
curl -I http://kube-prometheus-stack-grafana.monitoring:80

# Validate NGINX configuration
kubectl exec -n network deployment/nginx-ingress-external -- \
nginx -t

Troubleshooting

Common Issues

# Check ingress controller logs for errors
kubectl logs -n network -l app=nginx-ingress-external | grep -i error

# Verify ingress resource configuration
kubectl describe ingress grafana-external -n monitoring

# Test DNS resolution
kubectl run dns-test --image=busybox --rm -it -- \
nslookup kube-prometheus-stack-grafana.monitoring.svc.cluster.local

# Check service endpoints
kubectl get endpoints -n monitoring kube-prometheus-stack-grafana

Performance Issues

# Monitor controller resource usage
kubectl top pods -n network -l app=nginx-ingress

# Check connection statistics
kubectl exec -n network deployment/nginx-ingress-external -- \
curl -s http://localhost:18080/nginx_status

# Analyze request patterns
kubectl logs -n network -l app=nginx-ingress-external | \
grep "GET\|POST" | head -20

SSL/TLS Issues

# Test SSL certificate
openssl s_client -connect grafana.example.com:443 -servername grafana.example.com

# Check certificate expiration
kubectl get certificates -A -o wide

# Verify cert-manager status
kubectl get issuers,clusterissuers -A

NGINX Ingress Controllers provide robust, high-performance HTTP/HTTPS load balancing with extensive customization options, security features, and comprehensive monitoring capabilities for the Anton cluster's ingress traffic management.