EKS Cluster with Ingress-NGINX Controller

Ingress-NGINX is one of the most widely adopted reverse proxies and ingress controllers in Kubernetes. When deployed on Amazon EKS in conjunction with the AWS Load Balancer Controller, it provides high-throughput Layer 4 load balancing via an AWS Network Load Balancer (NLB) combined with feature-rich Layer 7 routing inside the cluster.
📁 Source Code: aws-eks-terraform / EKS-Cluster-ingress
📺 Video Walkthrough
Architecture: Ingress-NGINX on EKS
graph TD
Client["Client / Browser"] --> NLB["AWS Network Load Balancer (L4)"]
NLB -- "Target Type: IP (Direct)" --> NGINX["Ingress-NGINX Pods"]
NGINX -- "ClusterIP Routing" --> SvcA["Service A (Pod)"]
NGINX -- "ClusterIP Routing" --> SvcB["Service B (Pod)"]
Why Pair Ingress-NGINX with the AWS Load Balancer Controller?
By default, creating a LoadBalancer Service in Kubernetes creates a classic load balancer using NodePort targets. By installing the AWS Load Balancer Controller and VPC-CNI, you can provision an AWS NLB with target-type: ip.
This allows the NLB to route traffic directly to the Ingress-NGINX pods without extra NodePort network hops or kube-proxy translation.
Comparison: Ingress-NGINX vs AWS ALB Controller
| Feature | Ingress-NGINX (with AWS NLB) | AWS ALB Controller (ALB Ingress) |
|---|---|---|
| Load Balancer Layer | NLB (Layer 4) + NGINX (Layer 7) | ALB (Layer 7 managed by AWS) |
| Routing / Path Rewrites | Extensive regex, Lua scripts, custom headers | Basic AWS ALB path/host rule engine |
| In-Cluster Metrics | Native Prometheus metrics per service/route | CloudWatch metrics (per ALB / Target Group) |
| Target Group Delays | Minimal (internal NGINX upstream reloads) | Target Group health check registration delays |
| Certificate Management | Native Cert-Manager integration (Let's Encrypt) | AWS Certificate Manager (ACM) |
| Cost Efficiency | Single NLB fronting multiple apps/namespaces | 1 ALB per Ingress (unless using IngressGroups) |
Step-by-Step Installation
Step 1. Install Ingress-NGINX via Helm
Use the Helm values below to configure the Ingress-NGINX Service with AWS Load Balancer Controller annotations:
ingress-nginx-values.yaml
controller:
replicaCount: 2
service:
type: LoadBalancer
annotations:
service.beta.kubernetes.io/aws-load-balancer-type: "external"
service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: "ip"
service.beta.kubernetes.io/aws-load-balancer-scheme: "internet-facing"
service.beta.kubernetes.io/aws-load-balancer-attributes: load_balancing.cross_zone.enabled=true
metrics:
enabled: true
Install the Helm chart:
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 \
-f ingress-nginx-values.yaml
Step 2. Deploy Sample Application
sample-app.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-app
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: demo-app
template:
metadata:
labels:
app: demo-app
spec:
containers:
- name: web
image: nginxdemos/hello:plain-text
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: demo-svc
namespace: default
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 80
selector:
app: demo-app
Step 3. Create Ingress Resource
Create an Ingress rule pointing to the backend Service using the nginx IngressClass:
demo-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: demo-ingress
namespace: default
annotations:
ingress.kubernetes.io/ssl-redirect: "false"
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: demo-svc
port:
number: 80