Setting up a robust Kubernetes ingress controller in production isn't just about routing traffic—it's about creating a resilient, secure, and scalable entry point that can handle the complexities of modern application architectures. Whether you're managing microservices for a PropTech [platform](/saas-platform) or deploying enterprise applications, the ingress controller becomes your critical traffic orchestrator.
The difference between a development ingress setup and a production-ready configuration lies in the details: SSL termination strategies, load balancing algorithms, monitoring integration, and failover mechanisms. This comprehensive guide walks through every aspect of deploying NGINX ingress controllers that can withstand real-world production demands.
Understanding Kubernetes Ingress Architecture
The Role of Ingress Controllers in Production
Kubernetes ingress controllers serve as the bridge between external traffic and your internal services. Unlike simple load balancers, ingress controllers operate at Layer 7, providing intelligent routing based on hostnames, paths, headers, and other HTTP attributes.
In production environments, the ingress controller handles multiple critical functions:
- Traffic routing and load balancing across multiple service replicas
- SSL/TLS termination with certificate management
- Rate limiting and security policies to protect backend services
- Request/response transformation including header manipulation
- Health checking and failover for high availability scenarios
NGINX vs Alternative Controllers
While Kubernetes supports multiple ingress implementations, NGINX Ingress Controller remains the most widely adopted for production deployments. The choice comes down to several factors:
NGINX Ingress Controller advantages:
- Mature ecosystem with extensive documentation
- High performance and proven scalability
- Rich annotation system for fine-tuned control
- Strong community support and regular updates
- Comprehensive metrics and monitoring integration
Alternative considerations:
- Traefik offers automatic service discovery and simpler configuration
- HAProxy Ingress provides advanced load balancing algorithms
- Istio Gateway integrates with service mesh architectures
- Cloud-native options like AWS ALB or GCP Load Balancer for cloud-specific features
Production Architecture Patterns
Production ingress setups typically follow one of several architectural patterns:
Single Ingress Controller: Suitable for smaller applications or development environments, but creates a single point of failure.
Multi-Zone Deployment: Deploys ingress controllers across multiple availability zones with proper anti-affinity rules.
Dedicated Ingress Nodes: Uses node selectors to run ingress controllers on dedicated infrastructure, isolating traffic handling from application workloads.
Core Components and Configuration
Essential NGINX Controller Components
A production NGINX ingress setup involves several interconnected components that must work in harmony:
apiVersion: v1
kind: Namespace
metadata:
name: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: ingress-nginx
namespace: ingress-nginx
automountServiceAccountToken: true
---
apiVersion: v1
kind: ConfigMap
metadata:
name: ingress-nginx-controller
namespace: ingress-nginx
data:
# Production-optimized settings
use-forwarded-headers: "true"
compute-full-forwarded-for: "true"
use-proxy-protocol: "true"
worker-processes: "auto"
max-worker-connections: "16384"
upstream-keepalive-connections: "320"
upstream-keepalive-requests: "10000"
keep-alive: "75"
# Security headers
hide-headers: "Server,X-Powered-By"
server-tokens: "false"
Service and Deployment Configuration
The ingress controller deployment requires careful resource allocation and networking configuration:
apiVersion: apps/v1
kind: Deployment
metadata:
name: ingress-nginx-controller
namespace: ingress-nginx
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
selector:
matchLabels:
app.kubernetes.io/name: ingress-nginx
template:
metadata:
labels:
app.kubernetes.io/name: ingress-nginx
spec:
serviceAccountName: ingress-nginx
nodeSelector:
kubernetes.io/os: linux
node-role: ingress # Dedicated ingress nodes
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app.kubernetes.io/name
operator: In
values:
- ingress-nginx
topologyKey: kubernetes.io/hostname
containers:
- name: controller
image: registry.k8s.io/ingress-nginx/controller:v1.8.2
args:
- /nginx-ingress-controller
- --election-id=ingress-controller-leader
- --controller-class=k8s.io/ingress-nginx
- --configmap=$(POD_NAMESPACE)/ingress-nginx-controller
- --validating-webhook=:8443
- --validating-webhook-certificate=/usr/local/certificates/cert
- --validating-webhook-key=/usr/local/certificates/key
resources:
requests:
cpu: 500m
memory: 512Mi
limits:
cpu: 2000m
memory: 2Gi
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
ports:
- name: http
containerPort: 80
protocol: TCP
- name: https
containerPort: 443
protocol: TCP
- name: webhook
containerPort: 8443
protocol: TCP
livenessProbe:
httpGet:
path: /healthz
port: 10254
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
timeoutSeconds: 1
successThreshold: 1
failureThreshold: 5
readinessProbe:
httpGet:
path: /healthz
port: 10254
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
timeoutSeconds: 1
successThreshold: 1
failureThreshold: 3
LoadBalancer Service Configuration
The service configuration determines how external traffic reaches your ingress controllers:
apiVersion: v1
kind: Service
metadata:
name: ingress-nginx-controller
namespace: ingress-nginx
annotations:
# Cloud-specific annotations for production
service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true"
service.beta.kubernetes.io/aws-load-balancer-backend-protocol: "tcp"
service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout: "60"
spec:
type: LoadBalancer
externalTrafficPolicy: Local # Preserves source IP
selector:
app.kubernetes.io/name: ingress-nginx
ports:
- name: http
port: 80
targetPort: http
protocol: TCP
- name: https
port: 443
targetPort: https
protocol: TCP
Production Implementation Strategies
SSL/TLS Certificate Management
Production environments require robust certificate management. Integration with cert-manager provides automated certificate provisioning and renewal:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.[api](/workers).letsencrypt.org/directory
email: devops@proptechusa.ai
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- http01:
ingress:
class: nginx
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: production-app-ingress
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt-prod
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
nginx.ingress.kubernetes.io/ssl-protocols: "TLSv1.2 TLSv1.3"
nginx.ingress.kubernetes.io/ssl-ciphers: "ECDHE-ECDSA-AES128-GCM-SHA256,ECDHE-RSA-AES128-GCM-SHA256"
spec:
tls:
- hosts:
- api.proptechusa.ai
- app.proptechusa.ai
secretName: production-tls
rules:
- host: api.proptechusa.ai
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80
- host: app.proptechusa.ai
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frontend-service
port:
number: 80
Advanced Routing and Traffic Management
Production applications often require sophisticated routing logic:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: advanced-routing
annotations:
kubernetes.io/ingress.class: nginx
# Rate limiting for API endpoints
nginx.ingress.kubernetes.io/rate-limit: "100"
nginx.ingress.kubernetes.io/rate-limit-window: "1m"
# Custom upstream configuration
nginx.ingress.kubernetes.io/upstream-max-fails: "3"
nginx.ingress.kubernetes.io/upstream-fail-timeout: "30s"
# Request/response transformation
nginx.ingress.kubernetes.io/rewrite-target: /$2
nginx.ingress.kubernetes.io/configuration-snippet: |
more_set_headers "X-Frame-Options: DENY";
more_set_headers "X-Content-Type-Options: nosniff";
more_set_headers "X-XSS-Protection: 1; mode=block";
spec:
rules:
- host: api.example.com
http:
paths:
- path: /v1/users(/|$)(.*)
pathType: Prefix
backend:
service:
name: user-service
port:
number: 8080
- path: /v1/properties(/|$)(.*)
pathType: Prefix
backend:
service:
name: property-service
port:
number: 8080
Monitoring and Observability Integration
Production ingress controllers must provide comprehensive monitoring capabilities:
apiVersion: v1
kind: ServiceMonitor
metadata:
name: ingress-nginx-controller
namespace: ingress-nginx
spec:
selector:
matchLabels:
app.kubernetes.io/name: ingress-nginx
endpoints:
- port: prometheus
interval: 30s
path: /metrics
---
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-prometheus-config
namespace: ingress-nginx
data:
nginx.conf: |
# Enable detailed metrics
log_format json_analytics escape=json '
{
"time": "$time_iso8601",
"remote_addr": "$remote_addr",
"request_method": "$request_method",
"request_uri": "$request_uri",
"status": "$status",
"request_time": "$request_time",
"upstream_response_time": "$upstream_response_time",
"upstream_addr": "$upstream_addr",
"user_agent": "$http_user_agent"
}';
access_log /var/log/nginx/access.log json_analytics;
Security and Performance Best Practices
Security Hardening Strategies
Production ingress controllers require multiple layers of security:
apiVersion: v1
kind: ConfigMap
metadata:
name: ingress-security-config
namespace: ingress-nginx
data:
# Security-focused configuration
hide-headers: "Server,X-Powered-By,X-AspNet-Version"
server-tokens: "false"
# DDoS protection
limit-req-status-code: "429"
limit-conn-status-code: "429"
# SSL security
ssl-protocols: "TLSv1.2 TLSv1.3"
ssl-ciphers: "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384"
ssl-prefer-server-ciphers: "true"
# Request size limits
client-max-body-size: "10m"
client-body-buffer-size: "128k"
# Timeout configurations
client-body-timeout: "60"
client-header-timeout: "60"
proxy-connect-timeout: "5"
proxy-read-timeout: "60"
proxy-send-timeout: "60"
Performance Optimization
Optimizing ingress controller performance requires attention to multiple configuration areas:
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-performance-config
namespace: ingress-nginx
data:
# Worker process optimization
worker-processes: "auto"
max-worker-connections: "16384"
worker-rlimit-nofile: "65535"
# Connection pooling
upstream-keepalive-connections: "320"
upstream-keepalive-requests: "10000"
upstream-keepalive-timeout: "60"
# Buffer optimization
proxy-buffering: "on"
proxy-buffer-size: "128k"
proxy-buffers-number: "4"
# Compression
use-gzip: "true"
gzip-level: "6"
gzip-min-length: "1000"
gzip-types: "text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript"
# Cache configuration
proxy-cache-path: "/var/cache/nginx levels=1:2 keys_zone=static-cache:10m max_size=100m inactive=60m use_temp_path=off"
High Availability Configuration
Ensuring ingress controller availability requires careful planning:
apiVersion: apps/v1
kind: Deployment
metadata:
name: ingress-nginx-controller
spec:
replicas: 3 # Minimum for HA
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0 # Zero downtime updates
template:
spec:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app.kubernetes.io/name
operator: In
values:
- ingress-nginx
topologyKey: topology.kubernetes.io/zone
topologySpreadConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
app.kubernetes.io/name: ingress-nginx
Resource Management and Scaling
Production workloads require precise resource allocation and horizontal pod autoscaling:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: ingress-nginx-controller
namespace: ingress-nginx
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: ingress-nginx-controller
minReplicas: 3
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
behavior:
scaleUp:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 100
periodSeconds: 15
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 10
periodSeconds: 60
Deployment Automation and Maintenance
Infrastructure as Code Implementation
Production ingress deployments should be fully automated and version-controlled:
// Terraform configuration for AWS infrastructure
resource "aws_eks_node_group" "ingress_nodes" {
cluster_name = var.cluster_name
node_group_name = "ingress-nodes"
node_role_arn = aws_iam_role.node_group.arn
subnet_ids = var.private_subnet_ids
instance_types = ["c5.xlarge"]
capacity_type = "ON_DEMAND"
scaling_config {
desired_size = 3
max_size = 6
min_size = 3
}
labels = {
"node-role" = "ingress"
}
taint {
key = "node-role"
value = "ingress"
effect = "NO_SCHEDULE"
}
depends_on = [
aws_iam_role_policy_attachment.node_group_policy,
aws_iam_role_policy_attachment.cni_policy,
aws_iam_role_policy_attachment.registry_policy,
]
}
GitOps Deployment [Pipeline](/custom-crm)
Implementing GitOps practices ensures reliable and auditable deployments:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: ingress-nginx
namespace: argocd
spec:
project: infrastructure
source:
repoURL: https://github.com/proptechusa/k8s-infrastructure
targetRevision: HEAD
path: ingress-nginx
destination:
server: https://kubernetes.default.svc
namespace: ingress-nginx
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
retry:
limit: 3
backoff:
duration: 5s
factor: 2
maxDuration: 3m
Monitoring and Alerting Setup
Comprehensive monitoring ensures early detection of issues:
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: ingress-nginx-alerts
namespace: ingress-nginx
spec:
groups:
- name: ingress-nginx.rules
rules:
- alert: NginxIngressDown
expr: up{job="ingress-nginx-controller"} == 0
for: 1m
labels:
severity: critical
annotations:
summary: "NGINX Ingress Controller is down"
description: "NGINX Ingress Controller has been down for more than 1 minute"
- alert: NginxIngressHighErrorRate
expr: rate(nginx_ingress_controller_requests{status=~"5.."}[5m]) > 0.1
for: 5m
labels:
severity: warning
annotations:
summary: "High error rate in NGINX Ingress"
description: "Error rate is {{ $value }} errors per second"
- alert: NginxIngressHighLatency
expr: histogram_quantile(0.95, rate(nginx_ingress_controller_request_duration_seconds_bucket[5m])) > 1
for: 10m
labels:
severity: warning
annotations:
summary: "High latency in NGINX Ingress"
description: "95th percentile latency is {{ $value }}s"
Mastering Kubernetes ingress controllers in production requires balancing performance, security, and reliability while maintaining operational simplicity. The configurations and strategies outlined in this guide provide a solid foundation for enterprise-grade deployments.
The key to successful ingress management lies in treating it as critical infrastructure—with proper monitoring, automated deployment pipelines, and comprehensive testing. Whether you're scaling a PropTech platform or managing complex microservices architectures, these production-tested approaches will help ensure your ingress layer can handle whatever traffic patterns your applications encounter.
Ready to implement these ingress controller strategies in your environment? PropTechUSA.ai's DevOps automation platform includes pre-configured ingress templates, monitoring dashboards, and deployment pipelines that can accelerate your production setup. Explore our infrastructure automation capabilities and see how we can help streamline your Kubernetes operations.