Kubernetes Ingress controllers provide HTTP and HTTPS routing to services within a cluster. While Services expose pods internally, Ingress exposes them externally with features like host-based routing, path-based routing, TLS termination, and load balancing. Understanding Ingress controllers helps you design effective traffic management for your applications.
The Ingress resource defines routing rules. The Ingress controller implements those rules by configuring a load balancer or reverse proxy. Multiple Ingress controller implementations exist, each with different features and tradeoffs.
Ingress Basics
An Ingress resource maps external HTTP(S) requests to internal services based on hostnames and paths.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
tls:
- hosts:
- api.example.com
secretName: api-tls-secret
rules:
- host: api.example.com
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
- host: admin.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: admin-dashboard
port:
number: 80
Path types control matching behavior. Exact matches the path exactly. Prefix matches path prefixes. ImplementationSpecific delegates to the controller.
NGINX Ingress Controller
NGINX Ingress is the most widely deployed controller. It uses NGINX as a reverse proxy and supports extensive customization through annotations.
# NGINX Ingress with common configurations
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
annotations:
# Rate limiting
nginx.ingress.kubernetes.io/limit-rps: "100"
nginx.ingress.kubernetes.io/limit-connections: "10"
# Timeouts
nginx.ingress.kubernetes.io/proxy-connect-timeout: "10"
nginx.ingress.kubernetes.io/proxy-read-timeout: "60"
nginx.ingress.kubernetes.io/proxy-send-timeout: "60"
# Body size
nginx.ingress.kubernetes.io/proxy-body-size: "50m"
# SSL redirect
nginx.ingress.kubernetes.io/ssl-redirect: "true"
# CORS
nginx.ingress.kubernetes.io/enable-cors: "true"
nginx.ingress.kubernetes.io/cors-allow-origin: "https://app.example.com"
spec:
ingressClassName: nginx
rules:
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api
port:
number: 80
Custom NGINX configuration can be injected through ConfigMaps or snippets:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
annotations:
nginx.ingress.kubernetes.io/configuration-snippet: |
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
nginx.ingress.kubernetes.io/server-snippet: |
location /health {
return 200 'OK';
add_header Content-Type text/plain;
}
spec:
# ...
TLS Configuration
Ingress controllers terminate TLS, decrypting HTTPS traffic before forwarding to backend services. This centralizes certificate management.
# TLS secret containing certificate and key
apiVersion: v1
kind: Secret
metadata:
name: api-tls-secret
type: kubernetes.io/tls
data:
tls.crt: <base64-encoded-cert>
tls.key: <base64-encoded-key>
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: api-ingress
spec:
tls:
- hosts:
- api.example.com
- www.api.example.com
secretName: api-tls-secret
rules:
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api
port:
number: 80
Cert-manager automates certificate provisioning and renewal:
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: api-certificate
spec:
secretName: api-tls-secret
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer
dnsNames:
- api.example.com
---
# Or use annotations for automatic certificate creation
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: api-ingress
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
tls:
- hosts:
- api.example.com
secretName: api-tls-auto
# ...
Traffic Splitting and Canary Deployments
Ingress controllers can split traffic between services for canary deployments or A/B testing.
# NGINX canary deployment
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: api-stable
spec:
ingressClassName: nginx
rules:
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-stable
port:
number: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: api-canary
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "10" # 10% to canary
spec:
ingressClassName: nginx
rules:
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-canary
port:
number: 80
Header-based routing enables testing specific versions:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: api-canary
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-by-header: "X-Canary"
nginx.ingress.kubernetes.io/canary-by-header-value: "true"
spec:
# Requests with X-Canary: true header go to canary
Authentication and Authorization
Ingress controllers can handle authentication before requests reach your application.
# Basic authentication
apiVersion: v1
kind: Secret
metadata:
name: basic-auth
type: Opaque
data:
auth: <htpasswd-encoded-credentials>
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: protected-ingress
annotations:
nginx.ingress.kubernetes.io/auth-type: basic
nginx.ingress.kubernetes.io/auth-secret: basic-auth
nginx.ingress.kubernetes.io/auth-realm: "Authentication Required"
spec:
# ...
External authentication delegates to an auth service:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: protected-ingress
annotations:
nginx.ingress.kubernetes.io/auth-url: "https://auth.example.com/verify"
nginx.ingress.kubernetes.io/auth-signin: "https://auth.example.com/login"
nginx.ingress.kubernetes.io/auth-response-headers: "X-User-Id,X-User-Email"
spec:
# ...
Comparing Ingress Controllers
Different controllers suit different needs.
NGINX Ingress is mature, widely used, and well-documented. It handles most use cases and has extensive annotation support. It's a safe default choice.
Traefik provides automatic service discovery and Let's Encrypt integration. Its configuration through labels and annotations feels more native to Kubernetes.
# Traefik IngressRoute (custom resource)
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: api-route
spec:
entryPoints:
- websecure
routes:
- match: Host(`api.example.com`) && PathPrefix(`/v1`)
kind: Rule
services:
- name: api-v1
port: 80
middlewares:
- name: rate-limit
tls:
certResolver: letsencrypt
Kong provides API gateway features including rate limiting, authentication, and plugins. It's appropriate when you need advanced API management.
AWS ALB Ingress integrates with AWS Application Load Balancers, leveraging AWS's infrastructure directly. It's efficient for AWS deployments.
# AWS ALB Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:...
spec:
# ...
High Availability
Production Ingress controllers need redundancy. Run multiple replicas and configure appropriate pod disruption budgets.
apiVersion: apps/v1
kind: Deployment
metadata:
name: ingress-nginx-controller
spec:
replicas: 3
selector:
matchLabels:
app: ingress-nginx
template:
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app: ingress-nginx
topologyKey: kubernetes.io/hostname
containers:
- name: controller
image: k8s.gcr.io/ingress-nginx/controller:v1.9.0
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: ingress-nginx-pdb
spec:
minAvailable: 2
selector:
matchLabels:
app: ingress-nginx
Monitoring
Monitor Ingress controllers for request rates, error rates, and latency. NGINX Ingress exposes Prometheus metrics:
# Enable metrics
apiVersion: v1
kind: ConfigMap
metadata:
name: ingress-nginx-controller
data:
enable-prometheus-metrics: "true"
---
# ServiceMonitor for Prometheus Operator
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: ingress-nginx
spec:
selector:
matchLabels:
app: ingress-nginx
endpoints:
- port: metrics
interval: 30s
Key metrics to monitor include request rate by status code, request latency percentiles, connection counts, and configuration reload success.
Conclusion
Ingress controllers provide essential HTTP routing for Kubernetes applications. They handle TLS termination, path-based routing, and load balancing. Choose a controller based on your requirements: NGINX for general use, Traefik for automatic discovery, Kong for API management, or cloud-specific controllers for infrastructure integration.
Configure properly for production: multiple replicas, TLS with automatic renewal, rate limiting, and monitoring. The Ingress controller is a critical component; its failure affects all external traffic to your cluster.