Kubernetes Ingress Controllers: NGINX, Traefik, Istio & ALB Compared
Kubernetes Ingress Controllers#
Every request to your Kubernetes cluster enters through an ingress controller. It is the front door — handling TLS termination, routing, rate limiting, and load balancing. Choosing and configuring the right one is critical.
What an Ingress Controller Does#
Without ingress, you expose services via NodePort or LoadBalancer — one load balancer per service, no shared routing logic. Ingress consolidates external access:
Internet → Ingress Controller (single LB)
├── /api/* → api-service:8080
├── /app/* → frontend:3000
└── /docs/* → docs-service:4000
The controller watches Ingress resources (or Gateway resources in the Gateway API) and configures its underlying proxy accordingly.
NGINX Ingress Controller#
The most widely deployed ingress controller. Battle-tested and feature-rich.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/rate-limit: "100"
nginx.ingress.kubernetes.io/rate-limit-window: "1m"
nginx.ingress.kubernetes.io/proxy-body-size: "50m"
nginx.ingress.kubernetes.io/proxy-read-timeout: "60"
spec:
ingressClassName: nginx
tls:
- hosts:
- app.example.com
secretName: app-tls-secret
rules:
- host: app.example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-service
port:
number: 8080
- path: /
pathType: Prefix
backend:
service:
name: frontend
port:
number: 3000
Strengths: Mature, extensive annotations, large community, well-documented. Weaknesses: Config via annotations can become unwieldy, reload-based config updates.
Traefik#
Auto-discovery and dynamic configuration make Traefik popular for fast-moving teams.
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: app-ingress
spec:
entryPoints:
- websecure
routes:
- match: "Host(`app.example.com`) && PathPrefix(`/api`)"
kind: Rule
services:
- name: api-service
port: 8080
middlewares:
- name: rate-limit
- name: strip-prefix
- match: "Host(`app.example.com`)"
kind: Rule
services:
- name: frontend
port: 3000
tls:
certResolver: letsencrypt
---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: rate-limit
spec:
rateLimit:
average: 100
burst: 50
period: 1m
Strengths: Auto Let's Encrypt, dashboard, middleware chains, fast reloads. Weaknesses: CRD-heavy config, smaller community than NGINX.
Istio Gateway (Service Mesh Ingress)#
If you already run Istio, its gateway replaces a standalone ingress controller.
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: app-gateway
spec:
gatewayClassName: istio
listeners:
- name: https
protocol: HTTPS
port: 443
tls:
mode: Terminate
certificateRefs:
- name: app-tls-secret
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: app-routes
spec:
parentRefs:
- name: app-gateway
hostnames:
- "app.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /api
backendRefs:
- name: api-service
port: 8080
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: frontend
port: 3000
Strengths: mTLS everywhere, traffic shifting, deep observability, Gateway API support. Weaknesses: Heavy resource footprint, complex operations, overkill without a service mesh.
AWS ALB Ingress Controller#
Native integration with AWS Application Load Balancers.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
annotations:
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/certificate-arn: "arn:aws:acm:us-east-1:123456:certificate/abc-123"
alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}]'
alb.ingress.kubernetes.io/ssl-redirect: "443"
alb.ingress.kubernetes.io/group.name: "shared-alb"
spec:
ingressClassName: alb
rules:
- host: app.example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-service
port:
number: 8080
- path: /
pathType: Prefix
backend:
service:
name: frontend
port:
number: 3000
Strengths: Native AWS integration, WAF support, shared ALB across ingresses, no proxy pod to manage. Weaknesses: AWS-only, slower propagation (ALB changes take 30-60s), limited transformation.
Controller Comparison#
| Feature | NGINX | Traefik | Istio Gateway | AWS ALB |
|---|---|---|---|---|
| TLS termination | Yes | Yes + auto LE | Yes + mTLS | Yes (ACM) |
| Rate limiting | Annotations | Middleware | EnvoyFilter | WAF rules |
| Path routing | Yes | Yes | Yes | Yes |
| WebSocket | Yes | Yes | Yes | Yes |
| gRPC | Yes | Yes | Native | Yes |
| Config model | Annotations | CRDs | Gateway API | Annotations |
| Resource usage | Low-medium | Low | High | None (managed) |
TLS Termination Patterns#
Edge termination — decrypt at the ingress, plain HTTP to pods:
Client --TLS--> Ingress --HTTP--> Pod
Simplest model. Fine when the cluster network is trusted.
Re-encrypt — decrypt at ingress, re-encrypt to pods:
Client --TLS--> Ingress --TLS--> Pod
Required for compliance in some environments.
Passthrough — ingress forwards raw TLS to the pod:
Client --TLS--> Ingress --TLS--> Pod (pod terminates TLS)
Used when pods need to see the original certificate (mTLS, client certs).
Rate Limiting at Ingress#
Rate limiting at the ingress layer protects all backend services:
# NGINX - per-IP rate limiting
metadata:
annotations:
nginx.ingress.kubernetes.io/limit-rps: "50"
nginx.ingress.kubernetes.io/limit-burst-multiplier: "5"
nginx.ingress.kubernetes.io/limit-whitelist: "10.0.0.0/8"
For more granular control, combine ingress-level rate limiting with application-level limits:
Ingress rate limit: 1000 req/s per IP (DDoS protection)
└── API gateway rate limit: 100 req/s per API key (business logic)
└── Service rate limit: 50 req/s per user (resource protection)
Production Checklist#
- Health checks — configure readiness and liveness probes on the controller pods
- Pod disruption budgets — ensure at least 2 replicas survive during node drains
- Resource requests/limits — size based on connection count and throughput
- Access logs — enable structured JSON access logs for debugging
- Metrics — export to Prometheus (request rate, latency, 5xx rate)
- Timeouts — set connect, read, and send timeouts per backend
- CORS — configure allowed origins at the ingress level
- Security headers — add HSTS, X-Frame-Options, CSP via annotations or middleware
Conclusion#
Your choice of ingress controller shapes your cluster's networking capabilities. NGINX works for most teams. Traefik suits dynamic environments with auto-TLS needs. Istio Gateway makes sense if you already have a service mesh. AWS ALB Controller is ideal for AWS-native teams wanting managed infrastructure. Start simple and evolve as your routing needs grow.
Article #402 — part of the Codelit engineering blog. Explore all articles at codelit.io.
Try it on Codelit
Cost Estimator
See estimated AWS monthly costs for every component in your architecture
GitHub Integration
Paste a repo URL and generate architecture from your actual codebase
Related articles
Try these templates
Build this architecture
Generate an interactive architecture for Kubernetes Ingress Controllers in seconds.
Try it in Codelit →
Comments