Ingress Controller
Overview
An Ingress Controller is a specialized load balancer for Kubernetes that manages external access to services within a cluster. While Kubernetes Services expose applications internally, an Ingress Controller acts as the entry point for HTTP/HTTPS traffic from outside the cluster.
What Does an Ingress Controller Do?
An Ingress Controller watches for Ingress resources in your cluster and configures the underlying load balancer accordingly. It typically handles:
- Routing: Directing traffic to the correct service based on hostname and URL path
- TLS Termination: Handling HTTPS certificates and encryption
- Load Balancing: Distributing traffic across multiple pod replicas
- Authentication: Validating requests before they reach your application
- Traffic Management: URL rewriting, redirects, rate limiting, and more
Choosing an Ingress Controller
We offer multiple ingress controller options, each with different strengths:
| Controller | Type | Best For |
|---|---|---|
| AWS Load Balancer Controller | Managed (AWS) | Standard routing, TLS, authentication, minimal operational overhead |
| Traefik | K8s component | CORS, rate limiting, advanced proxy configuration |
| Ingress-NGINX Controller (Deprecated) | K8s component | Compatibility with existing nginx setups, extensive community support |
The right choice depends on your specific needs. See Making Your Choice below.
AWS LoadBalancer Controller
The AWS Load Balancer Controller provisions and manages AWS Elastic Load Balancers for your Kubernetes services. For Ingress resources, it creates Application Load Balancers (ALBs).
How It Works
Unlike traditional ingress controllers that run as pods inside your cluster, the ALB controller only runs a control plane component. The actual load balancing happens on AWS-managed infrastructure (the ALB) outside your cluster:
AWS Cloud
┌─────────────────────────────────────────────────────────┐
│ │
│ ┌─────────────┐ ┌──────────────────────────┐ │
│ │ ALB │ │ Kubernetes Cluster │ │
│ │ (AWS Managed)────────▶ Pods (target-type: ip) │ │
│ └─────────────┘ └──────────────────────────┘ │
│ ▲ ▲ │
│ │ │ │
│ │ watches & configures │ │
│ │ ┌──────────────────┘ │
│ │ │ │
│ │ ┌─────┴──────┐ │
│ └───│ ALB Controller │ │
│ └────────────┘ │
└─────────────────────────────────────────────────────────┘Key Characteristics
| Aspect | Description |
|---|---|
| Infrastructure | AWS-managed Application Load Balancers |
| Operational Overhead | Minimal — no load balancer pods to manage |
| Scaling | Automatic — ALB scales with traffic |
| Cost Model | Pay per ALB + Load Balancer Capacity Units (LCU) |
| AWS Integration | Native integration with ACM, WAF, Shield, CloudWatch |
Traefik
Traefik is a modern, cloud-native ingress controller that runs as pods within your Kubernetes cluster. It’s designed for dynamic environments and supports both the traditional Ingress API and the newer Gateway API.
How It Works
Traefik runs as a deployment in your cluster, watching for Ingress resources and routing traffic accordingly:
Kubernetes Cluster
┌───────────────────────────────────────────────────────┐
│ │
│ ┌─────────────────┐ │
│ │ Traefik Pods │──────▶ Service A ──▶ Pods │
│ │ (Deployment) │──────▶ Service B ──▶ Pods │
│ └────────┬────────┘──────▶ Service C ──▶ Pods │
│ │ │
│ │ watches │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Ingress / CRDs │ │
│ └─────────────────┘ │
│ │
└───────────────────────────────────────────────────────┘
▲
│
Internet (via NLB/Service)Key Characteristics
| Aspect | Description |
|---|---|
| Infrastructure | Pods in your cluster |
| Scaling | HPA-based pod scaling |
| Cost Model | Pay per launched load balancer + compute costs for Traefik pods |
| Configuration | Annotations, Middlewares (CRDs), or (in the future) Gateway API |
Ingress-NGINX Controller
Warning
Deprecation Notice: The Kubernetes community announced that ingress-nginx will be retired in March 2026. After this date, there will be no security patches, bug fixes, or updates. You must migrate to an alternative before this deadline.
The ingress-nginx controller was historically the most popular Kubernetes ingress controller, running NGINX as a reverse proxy inside your cluster.
Migration from Ingress-NGINX to ALB/Traefik
In general we will follow a simple process by enabling the new ingress controller alongside ingress-nginx, migrating workloads together with the customer one-by-one, and then decommissioning ingress-nginx once all workloads have been migrated.
- Launch new ingress solution in parallel
- Switch workloads and ingresses case by case to the new ingress, using examples from the How-To Guides
- Verify everything is working
- Disable ingress-nginx through cluster definition file
Making your choice
| Feature | ALB Controller | Traefik |
|---|---|---|
| TLS/SSL Management | ✅ ACM integration | ✅ cert-manager |
| URL Rewriting | ✅ v2.14.1+ (regex) | ✅ replacepath(regex) middleware |
| Redirects | ✅ Actions annotation | ✅ redirectRegex middleware |
| IP Whitelisting | ✅ inbound-cidrs | ✅ ipAllowList middleware |
| WebSocket | ✅ Native | ✅ Native |
| Basic Routing | ✅ Full | ✅ Full |
| mTLS | ✅ Full | ✅ Full |
| Authentication | ✅ Native OIDC/Cognito | ✅ ForwardAuth |
| Proxy Timeouts | ⚠️ Less granular | ✅ Full control |
| Session Affinity | ⚠️ IP mode only | ✅ Cookie-based |
| CORS | ❌ Requires CloudFront | ✅ Native middleware |
| Rate Limiting | ❌ Requires WAF | ✅ Native middleware |
| Custom Snippets | ❌ None | ⚠️ Via middleware |
✅ Full native support | ⚠️ Partial/limited support | ❌ Not supported
Strengths & Weaknesses
| Aspect | AWS ALB Controller | Traefik |
|---|---|---|
| Managed Service | ✅ AWS Native | ✅ K8s component managed by Skyscrapers |
| AWS Integration | ✅ WAF, Shield, GuardDuty, CloudWatch | ❌ Requires separate setup |
| Native Authentication | ✅ OIDC/Cognito at LB level | ⚠️ ForwardAuth (extra hop) |
| CORS Support | ❌ Requires app changes or CloudFront (additional costs) | ✅ Native middleware |
| Rate Limiting | ❌ Requires WAF (additional costs) | ✅ Native middleware |
| Session Affinity | ⚠️ IP mode only | ✅ Full cookie-based |
| Proxy Configuration | ⚠️ Less granular control | ✅ Full timeout/buffer control |
| Custom Snippets | ❌ No equivalent | ⚠️ Middleware (not 1:1) |
| Gateway API | ❌ Not supported yet | ✅ Full support (future-proof) |
| Reliability/SLA | ✅ AWS SLA-backed | ⚠️ Self-managed |
| Learning Curve | ✅ Familiar AWS patterns | ⚠️ New middleware/CRD patterns |
When to use what
Choose Traefik when:
- You need CORS headers at the ingress level
- You need rate limiting without additional AWS costs
- You have complex proxy timeout/buffer requirements
- You’re migrating from ingress-nginx with custom annotations
- You need cookie-based session affinity
See the Traefik How-To Guide for configuration examples.
Choose AWS Load Balancer Controller when:
- You need standard HTTP routing with TLS termination
- You’re using OIDC or Cognito for authentication
- You want a more AWS Native, managed solution
See the AWS Load Balancer Controller How-To Guide for configuration examples.
Migration Coverage Summary
In preparation for migrating from ingress-nginx to a new ingress controller, we analyzed ~1,100 existing ingresses to determine how many could be migrated easily, which would require moderate effort, and which would face significant blockers. Below is a summary of our findings for both the AWS ALB Controller and Traefik.
ALB Controller
| Category | Status |
|---|---|
| Easy Migration (~75%) | TLS, URL rewriting, auth, redirects, simple routing, IP filtering |
| Medium Migration (~10%) | Proxy timeouts, session affinity (requires IP mode) |
| Hard/Blocked (~15%) | CORS, rate limiting, custom snippets requiring application and/or infrastructure changes |
ALB Hard Blockers
| Blocker | Example Annotations | Issue | Workaround |
|---|---|---|---|
| CORS | nginx.ingress.kubernetes.io/enable-corsnginx.ingress.kubernetes.io/cors-allow-originnginx.ingress.kubernetes.io/cors-allow-headers | No native CORS header support | Move to application layer, or use CloudFront Response Headers Policy (adds cost + complexity) |
| Rate Limiting | nginx.ingress.kubernetes.io/limit-rpsnginx.ingress.kubernetes.io/limit-burst-multipliernginx.ingress.kubernetes.io/limit-connections | No native rate limiting | AWS WAF Rate-Based Rules (~$400/month), or implement in application |
| Custom Snippets | nginx.ingress.kubernetes.io/server-snippetnginx.ingress.kubernetes.io/configuration-snippetnginx.ingress.kubernetes.io/modsecurity-snippet | No equivalent for nginx server/location snippets | Manual audit required; refactor to application logic, Lambda@Edge, or keep on Traefik |
| Consistent Hashing | nginx.ingress.kubernetes.io/upstream-hash-bynginx.ingress.kubernetes.io/load-balance | Only round-robin and least-outstanding-requests supported | Accept different algorithm, or keep on Traefik |
| Granular Proxy Config | nginx.ingress.kubernetes.io/proxy-buffer-sizenginx.ingress.kubernetes.io/proxy-buffers-numbernginx.ingress.kubernetes.io/proxy-busy-buffers-size | Limited buffer/timeout control | Trust ALB defaults, or keep on Traefik for highly-tuned configs |
Traefik
| Category | Status |
|---|---|
| Easy Migration (~90%) | TLS, URL rewriting, CORS, rate limiting, redirects, routing, IP filtering, however requires changes in annotations and creation of Traefik resources |
| Medium Migration (~10%) | ForwardAuth setup: requires changes in annotations and creation of Traefik resources |
| Hard/Blocked (~0%) | No true blockers, but depending on what snippets are in place conversion might be challenging |
Traefik Hard Blockers
| Blocker | Example Annotations | Issue | Workaround |
|---|---|---|---|
| Custom Snippets | nginx.ingress.kubernetes.io/server-snippetnginx.ingress.kubernetes.io/configuration-snippet | Not 1:1 compatible; nginx syntax doesn’t translate to middleware | Audit each snippet; most can be converted to Traefik middleware (headers, redirects, rewrites), some may need application changes |
| ModSecurity Snippets | nginx.ingress.kubernetes.io/modsecurity-snippet | No native WAF in Traefik | Use AWS WAF or move security logic to application |