Kubernetes EKS
Quick Start: EKS with Classic Load Balancer
Minimal setup for deploying nginx on EKS with internet-facing load balancer in EU (Ireland).
Prerequisites
- AWS Account with admin access
- AWS CLI installed and configured
- kubectl installed (verify with
kubectl version --client)
Step 1: Create EKS Cluster (AWS Console)
1.1 Create Cluster with Auto Mode
- Go to EKS Console
- Click Create cluster
- Select Quick configuration (default)
- Cluster name:
my-cluster - Kubernetes version: Latest (e.g., 1.34)
1.2 Configure IAM Roles
- Cluster IAM role: Click Create recommended role
- Creates
AmazonEKSAutoClusterRole - Click refresh icon if needed
- Creates
- Node IAM role: Click Create recommended role
- Creates
AmazonEKSAutoNodeRole - Click refresh icon if needed
- Creates
1.3 Configure Networking
VPC: Click Create VPC
This opens the VPC wizard. Configure these settings:
- Resources to create: VPC and more (auto-selected)
- Name tag auto-generation: Your cluster name is used
- Number of Availability Zones: 2 (recommended)
- Number of public subnets: 2
- Number of private subnets: 2
- NAT gateways: 1 per AZ (costs ~$35/month per NAT Gateway)
- VPC endpoints: S3 Gateway (recommended to reduce NAT costs)
Additional tags (scroll down):
- Click Add new tag
- Key:
kubernetes.io/cluster/my-cluster - Value:
shared - This tags ALL 4 subnets (both public and private)
Click Create VPC, wait ~2 minutes, then return to EKS setup
Back in EKS cluster creation:
- VPC: Select the VPC you just created
- Subnets: EKS auto-selects the 2 private subnets (correct!)
Click Create cluster
Wait ~10-15 minutes for Active status
Note: You tagged all 4 subnets with kubernetes.io/cluster/my-cluster = shared in the VPC wizard. Next, you need to add kubernetes.io/role/elb = 1 to the 2 public subnets only (for internet-facing load balancers).
1.4 Tag Public Subnets for Load Balancers (CRITICAL!)
Why this is critical: Kubernetes needs the kubernetes.io/role/elb = 1 tag on public subnets to know where to create internet-facing load balancers.
Steps (AWS Console):
Go to VPC Console β Subnets
Find your public subnets:
- Look for subnets with your VPC name (created in step 1.3)
- Public subnets have “Auto-assign public IPv4 address” = Yes
- You should have 2 public subnets (one per availability zone)
Tag the first public subnet:
- Select the first public subnet
- Click Actions β Manage tags
- Click Add new tag
- Key:
kubernetes.io/role/elb - Value:
1 - Click Save changes
Tag the second public subnet:
- Repeat step 3 for the second public subnet
Verify: Both public subnets should now have these tags:
kubernetes.io/cluster/my-cluster = sharedβ (added in VPC wizard)kubernetes.io/role/elb = 1β (just added)
Step 2: Connect to Cluster
aws eks update-kubeconfig --region eu-west-1 --name my-cluster
kubectl get nodesExpected output: No resources found (EKS Auto Mode creates nodes when you deploy pods)
Step 3: Deploy Nginx
kubectl run my-nginx --image=nginxWait 1-2 minutes for the node to be created automatically, then:
kubectl get podsExpected: Pod status changes from Pending β ContainerCreating β Running
Step 4: Expose with Load Balancer
kubectl expose pod my-nginx --type=LoadBalancer --port=80
kubectl annotate service my-nginx service.beta.kubernetes.io/aws-load-balancer-scheme=internet-facingWhy the annotation? By default, AWS tries to create an internal load balancer (only accessible within the VPC). This annotation tells AWS to create an internet-facing load balancer, which uses the public subnets you tagged in Step 1.4.
Wait 2-3 minutes for AWS to create the Classic Load Balancer:
kubectl get service my-nginx --watchPress Ctrl+C when you see EXTERNAL-IP change from <pending> to a DNS name.
Get the Load Balancer URL:
Option 1 - AWS Console:
- Go to EC2 Console β Load Balancers (in left menu)
- Find the load balancer (name starts with
k8s-default-mynginx) - Copy the DNS name (e.g.,
k8s-default-mynginx-abc123.eu-west-1.elb.amazonaws.com) - Open in browser:
http://DNS-NAME
Option 2 - kubectl:
kubectl get service my-nginxCopy the EXTERNAL-IP value and open http://EXTERNAL-IP in your browser.
Expected: You should see the nginx welcome page! π
Cleanup
Delete Kubernetes resources:
kubectl delete service my-nginx
kubectl delete pod my-nginxWait 5-10 minutes - EKS Auto Mode will automatically terminate the node when no pods are running.
Delete the cluster:
- Go to EKS Console
- Select your cluster β Delete
- Type cluster name to confirm
- Wait ~5 minutes for deletion
Delete the VPC (if you created one):
- Go to VPC Console
- Find VPC named
eks-vpc-xxx - Select it β Actions β Delete VPC
- Deletes VPC, subnets, NAT Gateways, Internet Gateway automatically
Troubleshooting
EXTERNAL-IP stuck at <pending>
Check for errors:
kubectl describe service my-nginxCommon issues:
“Failed build model due to unable to resolve at least one subnet”
- The subnet tags are wrong
- Run the subnet tag fix commands in Step 1.4 again
“Evaluated 0 subnets”
- Missing the internet-facing annotation
- Add it:
kubectl annotate service my-nginx service.beta.kubernetes.io/aws-load-balancer-scheme=internet-facing
Re-create service:
kubectl delete service my-nginx
kubectl expose pod my-nginx --type=LoadBalancer --port=80
kubectl annotate service my-nginx service.beta.kubernetes.io/aws-load-balancer-scheme=internet-facingPod stuck in Pending
Check pod status:
kubectl describe pod my-nginxCommon causes:
- Node still provisioning (EKS Auto Mode takes 1-2 minutes)
- Wait and check again:
kubectl get pods --watch
Summary
What you built:
- EKS cluster with Auto Mode in EU (Ireland)
- VPC with 4 subnets (2 public, 2 private)
- Nginx pod running in private subnet
- Classic Load Balancer in public subnets
- Internet β Load Balancer β Pod flow
Key learnings:
- EKS Auto Mode creates nodes automatically (no manual node groups!)
- Public subnets need
kubernetes.io/role/elb = 1tag for load balancers - Private subnets should NOT have the
elbtag - The wizard tags things wrong - you need to fix it manually
Total time: ~20 minutes
Total cost:
- Control plane: $0.10/hour (~$73/month)
- Nodes: Only when pods are running (Auto Mode!)
- NAT Gateway: $0.048/hour (~$35/month)
- Load Balancer: $0.027/hour (~$20/month)
π‘ Tip: Delete everything when not using to avoid charges!
Tools needed: kubectl only!