Amazon EKS — Node Groups — Practice Exercises
Chapter 5 — Practice Exercises
Exercise 1: Node Group Design
Question: Design node groups for a cluster running: 3 microservices (steady load), a Redis cache (memory-intensive), and batch ML training jobs (GPU, intermittent). Include instance types, scaling, and labels/taints.
Show Solution
managedNodeGroups:
- name: general
instanceType: m5.large
desiredCapacity: 3
minSize: 2
maxSize: 8
labels: { workload: general }
- name: memory
instanceType: r5.large
desiredCapacity: 2
minSize: 1
maxSize: 4
labels: { workload: memory }
taints:
- key: dedicated
value: memory
effect: NoSchedule
- name: gpu-training
instanceType: g4dn.xlarge
desiredCapacity: 0
minSize: 0
maxSize: 4
spot: true
labels: { workload: gpu }
taints:
- key: nvidia.com/gpu
value: "true"
effect: NoSchedule
GPU nodes start at 0 and scale up only when training jobs are submitted.
Exercise 2: Max Pods Calculation
Question: Calculate the maximum number of pods for an m5.xlarge instance. It has 4 ENIs with 15 IPs per ENI. Show the formula.
Show Solution
Formula: Max Pods = (ENIs × IPs per ENI) - 1
m5.xlarge:
ENIs: 4
IPs per ENI: 15
Max Pods = (4 × 15) - 1 = 59
The EKS default is 58 (slightly lower due to reserved IPs).
With prefix delegation enabled: Max Pods = (ENIs × (IPs per ENI - 1) × 16) + 2 = much higher (110+).
Exercise 3: Spot Strategy
Question: Why should you specify at least 3 instance types for Spot node groups? What happens if you only specify one?
Show Solution
Why 3+ instance types:
- Each instance type in each AZ is a separate Spot capacity pool
- More pools = more chances of getting capacity
- If one pool is interrupted, others may still have availability
- AWS Spot best practice documentation recommends diversification
With only 1 type:
- Single capacity pool per AZ
- Higher interruption rate
- Possible complete capacity loss during demand spikes
- All nodes could be reclaimed simultaneously
Example: m5.large only → 1 pool per AZ = 2-3 pools
m5.large + m5a.large + m4.large → 3 pools per AZ = 6-9 pools
Exercise 4: Bottlerocket vs AL2
Question: Your security team requires minimal attack surface, no SSH, and immutable infrastructure. Which AMI should you use and why?
Show Solution
Use Bottlerocket.
| Requirement | Bottlerocket |
|---|---|
| Minimal attack surface | ✅ No shell, no package manager |
| No SSH | ✅ SSH disabled by default (use SSM) |
| Immutable infrastructure | ✅ Read-only root filesystem, atomic updates |
Additional benefits:
- Automatic security updates via atomic A/B partition swap
- Only container runtime + kubelet installed
- Smaller base image = faster boot
- CIS benchmarks compliance built-in
Exercise 5: Node Troubleshooting
Question: A node shows NotReady status. List 5 things you would check and the commands to check them.
Show Solution
# 1. Check node conditions
$ kubectl describe node <node-name> | grep -A5 "Conditions:"
# 2. Check kubelet logs (SSH or SSM into node)
$ journalctl -u kubelet -n 100 --no-pager
# 3. Check system pods on that node
$ kubectl get pods -A --field-selector spec.nodeName=<node-name>
# 4. Check EC2 instance status
$ aws ec2 describe-instance-status --instance-ids <instance-id>
# 5. Check security groups (node-to-control-plane communication)
$ aws ec2 describe-security-groups --group-ids <sg-id>
Common causes of NotReady:
- kubelet can’t reach API server (security group issue)
- Disk pressure (volume full)
- Memory pressure (OOM)
- VPC CNI IP exhaustion
- Certificate expired
What’s Next?
Serverless pods: Chapter 6 — Fargate.