Kubernetes Ingress Controllers
A comprehensive guide to Kubernetes Ingress Controllers covering NGINX, Traefik, HAProxy, AWS ALB, GCE Ingress, and Istio Gateway with detailed comparisons, installation instructions, and practical examples.
An Ingress Controller is a pod or set of pods that runs in a Kubernetes cluster and implements the Ingress API. It acts as a reverse proxy and load balancer, routing external HTTP/HTTPS traffic to services within the cluster. Unlike Services (which operate at L4), Ingress Controllers operate at L7 and provide advanced features like path-based routing, SSL/TLS termination, host-based routing, and name-based virtual hosting.
Key responsibilities of an Ingress Controller:
- Traffic Routing: Directs external traffic to appropriate services based on rules
- Load Balancing: Distributes traffic across multiple backend pods
- SSL/TLS Termination: Manages certificates and encrypts traffic
- Advanced Routing: Path-based, host-based, and header-based routing
- Security: Rate limiting, authentication, and security policies
Each Ingress Controller has its strengths and weaknesses. Here's a comprehensive comparison:
NGINX Ingress
Traefik
HAProxy Ingress
AWS ALB Ingress
GCE Ingress
Istio Gateway
The NGINX Ingress Controller is the most popular and feature-rich ingress controller. It uses NGINX as a reverse proxy and load balancer with a comprehensive set of features.
# Install NGINX Ingress Controller using Helm
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
helm install ingress-nginx ingress-nginx/ingress-nginx \
--namespace ingress-nginx \
--create-namespace \
--set controller.service.type=LoadBalancer \
--set controller.service.annotations."service\.beta\.kubernetes\.io/aws-load-balancer-type"="nlb"
# Install using kubectl
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.9.0/deploy/static/provider/cloud/deploy.yaml
# Verify installation
kubectl get pods -n ingress-nginx
kubectl get svc -n ingress-nginx
# Example Ingress with NGINX annotations
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
nginx.ingress.kubernetes.io/rate-limit: "10"
nginx.ingress.kubernetes.io/rate-limit-burst: "20"
nginx.ingress.kubernetes.io/proxy-body-size: "10m"
nginx.ingress.kubernetes.io/configuration-snippet: |
more_set_headers "X-Frame-Options: SAMEORIGIN";
spec:
ingressClassName: nginx
tls:
- hosts:
- app.example.com
secretName: 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: web-service
port:
number: 80
# Canary deployment with NGINX
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: canary-ingress
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "10"
nginx.ingress.kubernetes.io/canary-by-header: "X-Canary"
spec:
ingressClassName: nginx
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: canary-service
port:
number: 80
- Use IngressClass to manage multiple ingress controllers
- Configure SSL termination with cert-manager for automatic certificate management
- Implement rate limiting to protect backend services
- Use custom annotations for advanced routing (canary, A/B testing)
- Monitor NGINX metrics for performance and reliability
Traefik is a modern, cloud-native ingress controller with automatic configuration and service discovery. It's designed to work seamlessly with dynamic environments and microservices.
# Install Traefik using Helm
helm repo add traefik https://traefik.github.io/charts
helm repo update
helm install traefik traefik/traefik \
--namespace traefik \
--create-namespace \
--set service.type=LoadBalancer \
--set dashboard.enabled=true \
--set metrics.prometheus.enabled=true
# Verify installation
kubectl get pods -n traefik
kubectl get svc -n traefik
# Ingress with Traefik
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: traefik-ingress
annotations:
traefik.ingress.kubernetes.io/router.middlewares: default-rate-limit@kubernetescrd
traefik.ingress.kubernetes.io/router.tls: "true"
traefik.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: traefik
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
# Traefik Middleware for rate limiting
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: rate-limit
spec:
rateLimit:
average: 100
burst: 50
sourceCriterion:
ipStrategy:
depth: 1
# Traefik Middleware for authentication
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: basic-auth
spec:
basicAuth:
secret: basic-auth-secret
# Traefik Middleware for URL rewrite
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: strip-prefix
spec:
stripPrefix:
prefixes:
- /api
HAProxy Ingress Controller is built on the high-performance HAProxy load balancer. It's optimized for production environments requiring high throughput and low latency.
# Install HAProxy Ingress
helm repo add haproxy-ingress https://haproxy-ingress.github.io/charts
helm repo update
helm install haproxy-ingress haproxy-ingress/haproxy-ingress \
--namespace haproxy-ingress \
--create-namespace \
--set controller.service.type=LoadBalancer
# HAProxy Ingress with custom configuration
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: haproxy-ingress
annotations:
haproxy-ingress.github.io/ssl-redirect: "true"
haproxy-ingress.github.io/proxy-body-size: "10m"
haproxy-ingress.github.io/timeout-connect: "5s"
haproxy-ingress.github.io/timeout-server: "60s"
haproxy-ingress.github.io/rate-limit: "10"
spec:
ingressClassName: haproxy
tls:
- hosts:
- app.example.com
secretName: tls-secret
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
# HAProxy ConfigMap for advanced configuration
apiVersion: v1
kind: ConfigMap
metadata:
name: haproxy-config
namespace: haproxy-ingress
data:
global: |
maxconn 2000
defaults: |
timeout connect 5s
timeout client 60s
timeout server 60s
AWS ALB Ingress Controller uses the AWS Application Load Balancer as the ingress controller. It provides native AWS integration, automatic scaling, and high availability.
# Install AWS Load Balancer Controller
helm repo add eks https://aws.github.io/eks-charts
helm repo update
helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
--namespace kube-system \
--set clusterName=my-cluster \
--set serviceAccount.create=true \
--set serviceAccount.name=aws-load-balancer-controller
# Verify installation
kubectl get pods -n kube-system -l app.kubernetes.io/name=aws-load-balancer-controller
# Ingress for ALB
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: alb-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/listen-ports: '[{"HTTPS":443}]'
alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:us-east-1:123456789:certificate/xxxx
alb.ingress.kubernetes.io/ssl-redirect: '443'
alb.ingress.kubernetes.io/group.name: my-ingress-group
alb.ingress.kubernetes.io/group.order: '10'
alb.ingress.kubernetes.io/healthcheck-path: /health
alb.ingress.kubernetes.io/healthcheck-port: '80'
alb.ingress.kubernetes.io/healthcheck-interval-seconds: '30'
spec:
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: web-service
port:
number: 80
# TLS configuration with ACM
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: alb-tls-ingress
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:us-east-1:123456789:certificate/xxxx
alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}]'
spec:
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
- Use TLS termination with ACM certificates
- Configure health checks for target groups
- Use ingress groups for shared ALB across services
- Enable access logs for auditing and troubleshooting
- Use target-type 'ip' for Amazon VPC CNI clusters
GCE Ingress uses Google Cloud Load Balancing (GLB) to manage ingress traffic. It's the default ingress controller for GKE clusters and provides global load balancing capabilities.
# GCE Ingress (GKE default)
# Install GKE Ingress (already included in GKE clusters)
# Enable Ingress in GKE cluster
# Basic GCE Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: gce-ingress
annotations:
kubernetes.io/ingress.class: gce
kubernetes.io/ingress.allow-http: "false"
ingress.gcp.kubernetes.io/pre-shared-cert: my-cert
spec:
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
# Multi-cluster Ingress (GKE)
apiVersion: networking.gke.io/v1
kind: MultiClusterIngress
metadata:
name: global-ingress
namespace: default
spec:
template:
spec:
rules:
- host: app.example.com
http:
paths:
- path: /
backend:
serviceName: web-service
servicePort: 80
# BackendConfig for health checks
apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
name: web-backend-config
spec:
healthCheck:
checkIntervalSec: 10
timeoutSec: 5
healthyThreshold: 2
unhealthyThreshold: 3
port: 80
type: HTTP
requestPath: /health
logging:
enable: true
sampleRate: 0.5
Istio Gateway is part of the Istio service mesh and provides ingress capabilities with advanced traffic management, mTLS, and observability features.
# Install Istio
curl -L https://istio.io/downloadIstio | sh -
cd istio-*
export PATH=$PWD/bin:$PATH
istioctl install --set profile=demo -y
# Verify installation
kubectl get pods -n istio-system
# Gateway configuration
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
name: app-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- app.example.com
- port:
number: 443
name: https
protocol: HTTPS
hosts:
- app.example.com
tls:
mode: SIMPLE
credentialName: tls-secret
# VirtualService with routing rules
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: app-vs
spec:
hosts:
- app.example.com
gateways:
- app-gateway
http:
- match:
- uri:
prefix: /api
route:
- destination:
host: api-service
port:
number: 8080
- match:
- uri:
prefix: /
route:
- destination:
host: web-service
port:
number: 80
# DestinationRule for traffic policies
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: web-dr
spec:
host: web-service
trafficPolicy:
connectionPool:
tcp:
maxConnections: 100
loadBalancer:
simple: ROUND_ROBIN
tls:
mode: ISTIO_MUTUAL
| Feature | NGINX | Traefik | HAProxy | AWS ALB | Istio |
|---|---|---|---|---|---|
| SSL/TLS | Yes | Yes (auto) | Yes | Yes (ACM) | Yes (mTLS) |
| Rate Limiting | Yes | Yes | Yes | Yes | Yes |
| Canary Deployments | Yes | Yes | Yes | Yes | Yes |
| Service Mesh | No | No | No | No | Yes |
| Auto TLS | No | Yes | No | Yes | No |
| Performance | High | Medium | Very High | High | Medium |
| Complexity | Medium | Low | High | Low | Very High |
| Cloud Native | Yes | Yes | Yes | AWS | Yes |
ingressClassName field.nginx.ingress.kubernetes.io/canary: "true" and nginx.ingress.kubernetes.io/canary-weight: "10". For Istio, use VirtualService with weight-based routing. AWS ALB supports weighted target groups.nginx.ingress.kubernetes.io/server-snippet.Choosing the right Ingress Controller is crucial for your Kubernetes deployment. Consider your specific requirements for performance, features, cloud integration, and operational complexity when making your choice.