AWS Containers
EKS
Managed Kubernetes - run K8s without maintaining the control plane
Amazon Elastic Kubernetes Service (EKS) is a managed Kubernetes service that runs the Kubernetes control plane across multiple availability zones, handling availability, scalability, and patching automatically. EKS lets you run standard Kubernetes workloads on AWS without managing etcd, the API server, or control plane upgrades. It is the right choice when you need the full Kubernetes ecosystem, multi-cloud portability, or have existing K8s expertise.
EKS Architecture: Control Plane and Data Plane
EKS splits Kubernetes into a managed control plane (run by AWS) and a data plane (your worker nodes). Understanding this split is essential for troubleshooting and cost management.
| Component | Managed By | Location | Cost |
|---|---|---|---|
| API Server | AWS | AWS-managed VPC, multi-AZ | Included in $0.10/hr cluster fee |
| etcd | AWS | AWS-managed VPC, multi-AZ | Included in $0.10/hr cluster fee |
| Controller Manager | AWS | AWS-managed VPC | Included in $0.10/hr cluster fee |
| Worker Nodes (Managed Node Group) | Shared | Your VPC, EC2 instances you pay for | Standard EC2 pricing |
| Worker Nodes (Fargate) | Shared | AWS-managed, your VPC via ENI | Fargate per-vCPU/memory pricing |
| Worker Nodes (Self-managed) | You | Your VPC, EC2 instances you manage | Standard EC2 + your ops time |
The control plane communicates with worker nodes via the Kubernetes API. Worker nodes run the kubelet, kube-proxy, and container runtime (containerd).
EKS adds a cross-account ENI (elastic network interface) into your VPC to enable API server to kubelet communication. This ENI is in the EKS-managed VPC but has an IP in your subnet range.
Node Group Types: Managed, Self-Managed, and Fargate
EKS offers three ways to run worker nodes. Each has different trade-offs in operational overhead, flexibility, and cost.
| Type | Management | Upgrade Process | Best For |
|---|---|---|---|
| Managed Node Groups | AWS handles provisioning and lifecycle | Automated rolling upgrade via AWS console/CLI | Most production workloads |
| Self-managed Nodes | You provision EC2 + join to cluster | Manual - drain, update, replace | Custom AMIs, Windows, GPU with custom config |
| Fargate Profiles | AWS manages all compute | Re-deploy pods - no node patching | Variable batch jobs, microservices with varying load |
Fargate profiles use label selectors to determine which pods run on Fargate. Any pod matching the namespace and label selector runs serverlessly.
# Create a Fargate profile
aws eks create-fargate-profile \
--cluster-name my-cluster \
--fargate-profile-name my-profile \
--pod-execution-role-arn arn:aws:iam::123:role/eks-fargate-role \
--subnets subnet-abc subnet-def \
--selectors namespace=production,labels={app=api}EKS Fargate does not support DaemonSets, hostNetwork, hostPort, privileged containers, or persistent volumes backed by EBS. Use EFS for shared storage on Fargate. Also, each Fargate pod gets its own micro-VM, so pods cannot share node resources.
Networking with the AWS VPC CNI
EKS uses the Amazon VPC CNI plugin by default, which assigns real VPC IP addresses to pods. Each pod gets a secondary IP from the node's ENIs. This is fundamentally different from most Kubernetes CNIs that use overlay networks.
| Concept | EKS VPC CNI | Traditional Overlay (Flannel/Calico) |
|---|---|---|
| Pod IPs | Real VPC IPs - routable natively | Virtual IPs inside overlay - need NAT |
| IP limits | Limited by ENIs per instance type | Unlimited overlay IPs |
| Security groups | Security Groups for Pods supported | Node-level SGs only by default |
| Network policy | Requires Calico or Amazon VPC CNI Network Policy | Built into CNI |
| Performance | Native VPC performance, no overlay overhead | Small overlay encapsulation overhead |
The number of pods per node is limited by the instance's ENI count and secondary IPs per ENI. A t3.medium supports 3 ENIs x 6 IPs = 17 pods max (subtract 1 per ENI for the primary IP).
# Check max pods for an instance type
aws ec2 describe-instance-types \
--instance-types t3.medium \
--query "InstanceTypes[0].NetworkInfo.{MaxENI:MaximumNetworkInterfaces,IPv4PerENI:Ipv4AddressesPerInterface}"
# Enable prefix delegation to increase pod density
# (assigns /28 CIDR blocks instead of single IPs)
kubectl set env daemonset aws-node \
-n kube-system \
ENABLE_PREFIX_DELEGATION=trueEnable prefix delegation on the VPC CNI to significantly increase pod density. Instead of 1 IP per secondary IP slot, you get a /28 CIDR (16 IPs) per slot. A t3.medium goes from 17 max pods to 110.
IAM and RBAC: aws-auth ConfigMap and IRSA
EKS maps AWS IAM identities to Kubernetes RBAC using the aws-auth ConfigMap. IAM Roles for Service Accounts (IRSA) lets pods assume IAM roles via OIDC federation - the correct way to give pods AWS API access.
| Mechanism | Purpose | How It Works |
|---|---|---|
| aws-auth ConfigMap | Maps IAM users/roles to K8s RBAC groups | Stored in kube-system namespace, read by aws-iam-authenticator |
| IRSA (IAM Roles for Service Accounts) | Gives pods scoped AWS IAM permissions | OIDC provider + IAM role trust policy + K8s service account annotation |
| EKS Access Entries (new) | IAM-native alternative to aws-auth ConfigMap | Managed via EKS API, no ConfigMap editing required |
| Node IAM Role | Permissions for kubelet and VPC CNI | Attached to node group - never grant overly broad permissions |
# 1. Associate OIDC provider with cluster
eksctl utils associate-iam-oidc-provider \
--cluster my-cluster --approve
# 2. Create IAM role with IRSA trust policy
eksctl create iamserviceaccount \
--cluster my-cluster \
--namespace production \
--name my-app-sa \
--attach-policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess \
--approve
# 3. Reference in pod spec
# spec:
# serviceAccountName: my-app-saNever manually edit the aws-auth ConfigMap without a backup - a malformed entry can lock everyone out of the cluster. Use EKS Access Entries (available in EKS 1.29+) as the safer alternative. Always grant kubectl access to at least one IAM role before finishing cluster setup.
Scaling: Cluster Autoscaler, KEDA, and Karpenter
EKS workload scaling has two levels: pod scaling (HPA, VPA, KEDA) and node scaling (Cluster Autoscaler, Karpenter). Karpenter is the modern replacement for Cluster Autoscaler on EKS.
| Tool | Scales What | Approach | EKS Recommendation |
|---|---|---|---|
| HPA | Pod replicas | CPU/memory/custom metrics | Use for stateless services |
| VPA | Pod CPU/memory requests | Adjusts resource requests | Use carefully - requires pod restarts |
| KEDA | Pod replicas | Event-driven (SQS, Kafka, etc.) | Use for event-driven workloads |
| Cluster Autoscaler | EC2 node count | Watches for pending pods, adjusts ASG | Legacy - still works, slower |
| Karpenter | EC2 node count + type | Provisions optimal nodes directly | Preferred for new clusters |
Karpenter is faster than Cluster Autoscaler (seconds vs minutes) because it calls EC2 APIs directly instead of adjusting ASG desired count and waiting. It also chooses the right instance type per workload based on pod resource requests.
# Karpenter NodePool example
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
name: default
spec:
template:
spec:
requirements:
- key: "karpenter.k8s.aws/instance-category"
operator: In
values: ["c", "m", "r"]
- key: "karpenter.sh/capacity-type"
operator: In
values: ["spot", "on-demand"]
limits:
cpu: 1000
disruption:
consolidationPolicy: WhenEmptyOrUnderutilized
consolidateAfter: 30sEKS Version Upgrades and Add-on Management
EKS supports Kubernetes versions for 14 months after release. Clusters must be upgraded before end-of-support. The upgrade process is sequential - you cannot skip minor versions.
| Upgrade Step | Action | Notes |
|---|---|---|
| 1. Update control plane | eksctl upgrade cluster or console | In-place, rolling, ~10 min, no downtime for workloads |
| 2. Update EKS add-ons | Update VPC CNI, kube-proxy, CoreDNS | Each add-on has a compatible version range per K8s version |
| 3. Update managed node groups | Rolling node replacement | Drains nodes before termination |
| 4. Validate | Test workloads, check API deprecations | Use kubectl deprecations warnings from prior version |
EKS add-ons are managed components that EKS can update automatically. Core add-ons include vpc-cni, kube-proxy, coredns, and aws-ebs-csi-driver.
Check for Kubernetes API deprecations BEFORE upgrading. A deployment using apps/v1beta1 will fail after the version that removes it. Use tools like kubent (kube-no-trouble) to scan for deprecated API usage in your cluster before initiating an upgrade.
Interview Focus Points
- 1How does IRSA (IAM Roles for Service Accounts) work and why is it better than using node IAM roles?
- 2Explain the EKS VPC CNI and the pod IP density limitation - how do you work around it?
- 3What is Karpenter and how does it differ from the Cluster Autoscaler?
- 4Walk me through upgrading an EKS cluster from 1.28 to 1.30 - what are the steps and risks?
- 5How does the aws-auth ConfigMap work and what happens if you misconfigure it?
- 6EKS vs ECS - what factors would lead you to choose EKS for a new project?
- 7How would you implement zero-downtime deployments in EKS using rolling updates or Argo Rollouts?
- 8Explain the difference between Managed Node Groups, Self-managed nodes, and Fargate profiles - when would you use each?
- 9How do you enforce network policies between namespaces in EKS?
- 10What is EKS Anywhere and when would a customer choose it over cloud-based EKS?