Skip to content

EKS Cluster with Ingress-NGINX Controller

Ingress Nginx

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


Verification

# Check Ingress-NGINX pods and service
kubectl get pods,svc -n ingress-nginx

# Obtain the NLB external address
kubectl get ingress demo-ingress

# Send a test request
curl -i http://<NLB-DNS-NAME>/