Deploying Ingress Nginx Controller ELB in EKS Cluster with multiple nodes
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
Running ingress on Amazon EKS is straightforward in a demo cluster and surprisingly fragile in a real multi-node environment. You are not only deploying a controller; you are connecting Kubernetes service discovery, AWS load balancer provisioning, node placement, and health checks into one path. A reliable setup comes from making each layer explicit instead of hoping the defaults line up.
Install the Controller With Intentional Defaults
The NGINX Ingress Controller is commonly installed with Helm. In a multi-node cluster, the first thing to decide is replica count. A single controller pod means node failure can take all ingress routing down even if your workloads are healthy.
That command asks Kubernetes to create the controller deployment and a LoadBalancer service in front of it. In EKS, that service is the bridge into AWS infrastructure.
Make AWS Networking Match the Kubernetes Plan
If the load balancer never appears, the problem is usually outside the ingress manifest. EKS needs correctly tagged subnets, security groups that allow traffic, and node reachability that matches the load balancer type you requested. It is worth validating those prerequisites before you debug the controller itself.
When you need specific AWS behavior, add service annotations deliberately instead of relying on implicit provider choices.
An internal service can use a private scheme instead. The important thing is that the annotation set reflects the actual network exposure you want, not a leftover example from another cluster.
Spread Controller Pods Across Nodes
Multiple replicas only help if the scheduler places them sensibly. In production, you usually want anti-affinity or topology spread constraints so a single node problem does not take out every ingress controller replica.
Pair that with a PodDisruptionBudget so voluntary disruptions, such as upgrades or node drains, do not evict all replicas at once. Resource requests also matter because overloaded ingress pods tend to fail in noisy, intermittent ways that are painful to trace.
Wire an Ingress Resource to a Real Service
Once the controller is stable, expose an application through a normal Kubernetes service and ingress object.
This part is often where people discover that the ingress class name does not match the controller, or that the backend service points to the wrong port. Keep the path from DNS to service port easy to trace on paper. If you cannot explain the route clearly, troubleshooting will be much slower later.
Operate the Ingress Layer Like Shared Infrastructure
Ingress is a platform component, not a one-time install. Monitor controller pod readiness, request error rates, target health, certificate expiration, and latency. During incidents, debug in layers: first the LoadBalancer service, then controller logs, then the ingress resource, then the backend service and pods.
TLS and request policy also belong here. Rate limits, body size limits, header behavior, and timeouts should be version-controlled and reviewed. If those settings are tuned ad hoc in production, the cluster tends to collect inconsistent behavior across teams.
Common Pitfalls
The most frequent failure is assuming that a LoadBalancer service guarantees a reachable AWS load balancer. Missing subnet tags and security group rules break that assumption quickly. Single-replica controllers are another common mistake in multi-node clusters, as are missing anti-affinity rules, wrong ingress class names, and health checks that do not reflect real application readiness.
Summary
- Install ingress-nginx with an explicit replica count and service type.
- Verify AWS subnet tagging, security groups, and exposure mode before debugging Kubernetes objects.
- Spread controller replicas across nodes and protect them during disruption events.
- Keep ingress class, backend service, and DNS mapping consistent and easy to trace.
- Monitor ingress as shared production infrastructure, not as a one-time deployment.
Related reading
- Deploying local Docker image DockerFIle as local Kubernetes pod
- Deploying stateful application as master slave (replicas) in kubernetes
- Deployment invalid spec.template.metadata.labels Invalid value
- Deprecated k8s API
- Deploying Java webapp to Tomcat 8 running in Docker container
- Deploying Keras Models via Google Cloud ML
- Determine what resource was not found from Error from server NotFound the server could not find the requested resource
- DevOps CI/CD pipelines broken after Kubernetes upgrade to v1.22

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.