Kubernetes End-to-End Project on Amazon EKS: Architecture, Deployment, & Ingress Setup
1. Why Do We Need AWS EKS? (The Problem Statement)
Managing a self-managed Kubernetes cluster on cloud virtual machines (such as EC2 using kubeadm or cops) introduces immense operational overhead. In a traditional 3-master, 3-worker node architecture, a DevOps engineer is personally responsible for provisioning and maintaining critical control plane components:
Key Operational Pain Points:
- Control Plane Failures: If
etcdcrashes, the API server slows down or becomes unresponsive, or TLS certificates expire, production environments break immediately. - Scale and Fragmentation: Managing hundreds of disparate clusters means spending hours every day debugging control plane issues rather than delivering business value.
- The Managed Solution: AWS Elastic Kubernetes Service (EKS) shifts the burden of control plane maintenance to AWS under a robust Service Level Agreement (SLA), letting engineers focus strictly on workloads and data planes.
2. Core Mental Model: EKS Architecture & Fargate
AWS EKS provides a fully managed control plane while leaving the data plane flexible.
Real-Life Analogy: Renting a Commercial Office Building
Running a self-managed Kubernetes cluster is like renting an empty warehouse where you must install your own plumbing, electrical wiring, and security systems. When something breaks in the walls, it is entirely your problem.
Using AWS EKS with Fargate is like moving into a fully serviced corporate skyscraper: the landlord (AWS) guarantees that the elevators, security, and structural integrity (Control Plane) never fail. You simply bring your furniture and desks (Containers/Pods) and start working without worrying about underlying infrastructure maintenance.
EKS Worker Node Strategy Table
3. Traffic Routing Challenge: From Pod to External World
By default, when you deploy an application as a Pod inside an EKS cluster, it receives a ClusterIP, meaning it is only reachable from inside the cluster. External users cannot access it.
The Evolution of Service Exposure Options:
- ClusterIP: Internal-only access. Inaccessible to the outside world.
- NodePort: Opens a specific port across all worker nodes. If your cluster sits inside a private subnet behind a VPC, external users still cannot reach it directly without public IPs or a load balancer.
- LoadBalancer: Provisions an AWS Elastic Load Balancer (ELB) directly. While functional, creating a dedicated load balancer for every single microservice becomes prohibitively expensive at scale.
- Ingress + Ingress Controller (The Best Practice): A centralized entry point where a single Application Load Balancer (ALB) routes traffic to multiple services based on URL paths or hostnames.
4. Prerequisites & Client Tooling Setup
Before provisioning an EKS cluster, ensure the following command-line tools and authentication configurations are installed on your local workstation:
Essential Tools:
kubectl: The Kubernetes command-line tool for interacting with clusters.eksctl: The official CLI tool for Amazon EKS to create and manage clusters easily.- AWS CLI: For communicating with AWS APIs.
Configuring AWS CLI:
Run the configuration command and provide your root/IAM administrative credentials:
aws configure
Provide your AWS Access Key ID, AWS Secret Access Key, default region (e.g., us-east-1), and output format (json).
5. Step-by-Step EKS Cluster Provisioning with eksctl
Instead of clicking through the AWS Management Console, create an EKS cluster using eksctl with Fargate enabled:
eksctl create cluster \
--name demo-cluster-1 \
--region us-east-1 \
--fargate
Note: Cluster creation provisions a dedicated VPC with both public and private subnets, along with the managed control plane. This process typically takes between 10 to 15 minutes.
Once the cluster is ready, update your local kubeconfig so kubectl can communicate with your new cluster:
aws eks update-kubeconfig --name demo-cluster-1 --region us-east-1
Verify that the cluster is active and reachable:
kubectl get svc
6. Deploying the Real-Time Application (Game 2048)
We will deploy the popular 2048 game application inside a custom namespace (game-2048) backed by AWS Fargate.
Step A: Create a Fargate Profile for the Namespace
Fargate requires a dedicated profile mapped to your namespace so it knows where to schedule pods:
eksctl create fargateprofile \
--cluster demo-cluster-1 \
--region us-east-1 \
--name alb-sample-app \
--namespace game-2048
Step B: Apply Manifests (Namespace, Deployment, Service, & Ingress)
Create a unified manifest file (ingress.yaml) containing the complete application architecture:
apiVersion: v1
kind: Namespace
metadata:
name: game-2048
---
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: game-2048
name: deployment-2048
spec:
replicas: 5
selector:
matchLabels:
app.kubernetes.io/name: app-2048
template:
...
---
apiVersion: v1
kind: Service
metadata:
namespace: game-2048
name: service-2048
spec:
ports:
- port: 80
targetPort: 80
selector:
app.kubernetes.io/name: app-2048
type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
namespace: game-2048
name: ingress-2048
annotations:
kubernetes.io/ingress.class: "alb"
alb.ingress.kubernetes.io/scheme: "internet-facing"
alb.ingress.kubernetes.io/target-type: "ip"
spec:
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: service-2048
port:
number: 80
Apply the deployment manifest to the cluster:
kubectl apply -f ingress.yaml
Check the pod status:
kubectl get pods -n game-2048
(Pods will initially show as Pending while Fargate provisions underlying serverless worker capacity, eventually transitioning to Running).
7. Installing and Configuring the AWS Load Balancer Controller
Merely deploying an Ingress resource does nothing on its own; an Ingress Controller is required to watch for Ingress objects and dynamically provision AWS Application Load Balancers.
Step 1: Associate IAM OIDC Provider
To allow Kubernetes service accounts to assume IAM roles and call AWS APIs, associate the OpenID Connect (OIDC) provider:
eksctl utils associate-iam-oidc-provider \
--cluster demo-cluster-1 \
--approve
Step 2: Create IAM Policy for the ALB Controller
Download and create the AWS-managed IAM policy granting permissions to manage ALBs:
curl -o iam-policy.json https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/main/docs/install/iam_policy.json
aws iam create-policy \
--policy-name AWSLoadBalancerControllerIAMPolicy \
--policy-document file://iam-policy.json
Step 3: Create IAM Service Account (IRSA)
Create a Kubernetes service account linked to the IAM role using your AWS Account ID (<YOUR_AWS_ACCOUNT_ID>):
eksctl create iamserviceaccount \
--cluster=demo-cluster-1 \
--namespace=kube-system \
--name=aws-load-balancer-controller \
--role-name AmazonEKSLoadBalancerControllerRole \
--attach-policy-arn=arn:aws:iam::<YOUR_AWS_ACCOUNT_ID>:policy/AWSLoadBalancerControllerIAMPolicy \
--approve \
--override-existing-serviceaccounts
Step 4: Install the Controller via Helm
Add the EKS Helm chart repository and install the 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 \
-n kube-system \
--set clusterName=demo-cluster-1 \
--set serviceAccount.create=false \
--set serviceAccount.name=aws-load-balancer-controller \
--set region=us-east-1 \
--set vpcId=<YOUR_VPC_ID>
Verify that the controller pods are running successfully (2/2 replicas):
kubectl get deployment aws-load-balancer-controller -n kube-system
8. Real-World Debugging & Troubleshooting Mindset
When deploying production-grade Kubernetes workloads, you may encounter edge cases. Here is how to debug common cluster failures:
Common Troubleshooting Workflow:
- Check Pod Health & Crash Loops:
BASH
kubectl get pods -n kube-system kubectl describe pod <pod-name> -n kube-system - Inspect AWS CloudFormation / IAM Service Account Conflicts:
- If
eksctl create iamserviceaccountthrows an error stating that the stack or role already exists, navigate to the AWS CloudFormation console, locate the stale stack (e.g.,eksctl-demo-cluster-1-addon-iamserviceaccount-...), delete it, and rerun your command.
- If
- Verify Ingress Address Resolution:
Once the ALB controller successfully provisions the load balancer, inspect your Ingress resource:
When theBASH
kubectl get ingress -n game-2048ADDRESSfield populates with your AWS ELB DNS name, the integration is fully complete.
9. Complete Flow Walkthrough
Here is the exact sequence of events when a user accesses the deployed application:
10. Summary and Key Takeaways
- Managed Control Plane: AWS EKS removes the heavy burden of patching, monitoring, and maintaining master nodes (
etcd, API servers, controllers). - Compute Flexibility: You can power your EKS worker nodes using either traditional EC2 instances or serverless AWS Fargate for zero-maintenance container execution.
- Ingress Architecture: Ingress resources cleanly manage external HTTP/HTTPS routing without needing costly individual LoadBalancer services for every pod.
- ALB Controller Integration: The AWS Load Balancer Controller watches Ingress resources in real-time, automatically provisioning and configuring AWS Application Load Balancers.
- IRSA (IAM Roles for Service Accounts): Secures cluster workloads by binding fine-grained AWS IAM permissions directly to Kubernetes service accounts.
- Production Readiness: Implementing a fully functional EKS cluster with Ingress controllers and Fargate serves as a high-impact, resume-worthy DevOps portfolio project.