| name | eks |
| description | AWS EKS Kubernetes management for clusters, node groups, and workloads. Use when creating clusters, configuring IRSA, managing node groups, deploying applications, or integrating with AWS services. |
| last_updated | 2026-01-07 |
| doc_source | https://docs.aws.amazon.com/eks/latest/userguide/ |
AWS EKS
Amazon Elastic Kubernetes Service (EKS) runs Kubernetes without installing and operating your own control plane. EKS manages the control plane and integrates with AWS services.
Table of Contents
Core Concepts
Control Plane
Managed by AWS. Runs Kubernetes API server, etcd, and controllers across multiple AZs.
Node Groups
| Type | Description |
|---|
| Managed | AWS manages provisioning, updates |
| Self-managed | You manage EC2 instances |
| Fargate | Serverless, per-pod compute |
IRSA (IAM Roles for Service Accounts)
Associates Kubernetes service accounts with IAM roles for fine-grained AWS permissions.
Add-ons
Operational software: CoreDNS, kube-proxy, VPC CNI, EBS CSI driver.
Common Patterns
Create a Cluster
AWS CLI:
aws iam create-role \
--role-name eks-cluster-role \
--assume-role-policy-document '{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {"Service": "eks.amazonaws.com"},
"Action": "sts:AssumeRole"
}]
}'
aws iam attach-role-policy \
--role-name eks-cluster-role \
--policy-arn arn:aws:iam::aws:policy/AmazonEKSClusterPolicy
aws eks create-cluster \
--name my-cluster \
--role-arn arn:aws:iam::123456789012:role/eks-cluster-role \
--resources-vpc-config subnetIds=subnet-12345678,subnet-87654321,securityGroupIds=sg-12345678
aws eks wait cluster-active --name my-cluster
aws eks update-kubeconfig --name my-cluster --region us-east-1
eksctl (Recommended):
eksctl create cluster \
--name my-cluster \
--region us-east-1 \
--version 1.29 \
--nodegroup-name standard-workers \
--node-type t3.medium \
--nodes 3 \
--nodes-min 1 \
--nodes-max 5 \
--managed
Add Managed Node Group
aws iam create-role \
--role-name eks-node-role \
--assume-role-policy-document '{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {"Service": "ec2.amazonaws.com"},
"Action": "sts:AssumeRole"
}]
}'
aws iam attach-role-policy --role-name eks-node-role --policy-arn arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy
aws iam attach-role-policy --role-name eks-node-role --policy-arn arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly
aws iam attach-role-policy --role-name eks-node-role --policy-arn arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy
aws eks create-nodegroup \
--cluster-name my-cluster \
--nodegroup-name standard-workers \
--node-role arn:aws:iam::123456789012:role/eks-node-role \
--subnets subnet-12345678 subnet-87654321 \
--instance-types t3.medium \
--scaling-config minSize=1,maxSize=5,desiredSize=3 \
--ami-type AL2_x86_64
Configure IRSA
eksctl utils associate-iam-oidc-provider \
--cluster my-cluster \
--approve
eksctl create iamserviceaccount \
--cluster my-cluster \
--namespace default \
--name my-app-sa \
--attach-policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess \
--approve
Manual IRSA setup:
OIDC_ISSUER=$(aws eks describe-cluster --name my-cluster --query "cluster.identity.oidc.issuer" --output text)
OIDC_ID=${OIDC_ISSUER##*/}
cat > trust-policy.json << EOF
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::123456789012:oidc-provider/oidc.eks.us-east-1.amazonaws.com/id/${OIDC_ID}"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"oidc.eks.us-east-1.amazonaws.com/id/${OIDC_ID}:sub": "system:serviceaccount:default:my-app-sa",
"oidc.eks.us-east-1.amazonaws.com/id/${OIDC_ID}:aud": "sts.amazonaws.com"
}
}
}]
}
EOF
aws iam create-role --role-name my-app-role --assume-role-policy-document file://trust-policy.json
Kubernetes Service Account
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-app-sa
namespace: default
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/my-app-role
Install Add-ons
aws eks create-addon \
--cluster-name my-cluster \
--addon-name coredns \
--addon-version v1.11.1-eksbuild.4
aws eks create-addon \
--cluster-name my-cluster \
--addon-name vpc-cni \
--addon-version v1.16.0-eksbuild.1
aws eks create-addon \
--cluster-name my-cluster \
--addon-name kube-proxy \
--addon-version v1.29.0-eksbuild.1
aws eks create-addon \
--cluster-name my-cluster \
--addon-name aws-ebs-csi-driver \
--addon-version v1.27.0-eksbuild.1 \
--service-account-role-arn arn:aws:iam::123456789012:role/ebs-csi-role
Deploy Application
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
serviceAccountName: my-app-sa
containers:
- name: app
image: 123456789012.dkr.ecr.us-east-1.amazonaws.com/my-app:latest
ports:
- containerPort: 8080
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
---
apiVersion: v1
kind: Service
metadata:
name: my-app
annotations:
service.beta.kubernetes.io/aws-load-balancer-type: nlb
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 8080
selector:
app: my-app
CLI Reference
Cluster Management
| Command | Description |
|---|
aws eks create-cluster | Create cluster |
aws eks describe-cluster | Get cluster details |
aws eks update-cluster-config | Update cluster settings |
aws eks delete-cluster | Delete cluster |
aws eks update-kubeconfig | Configure kubectl |
Node Groups
| Command | Description |
|---|
aws eks create-nodegroup | Create node group |
aws eks describe-nodegroup | Get node group details |
aws eks update-nodegroup-config | Update node group |
aws eks delete-nodegroup | Delete node group |
Add-ons
| Command | Description |
|---|
aws eks create-addon | Install add-on |
aws eks describe-addon | Get add-on details |
aws eks update-addon | Update add-on |
aws eks delete-addon | Remove add-on |
Best Practices
Security
- Use IRSA for pod-level AWS permissions
- Enable cluster encryption with KMS
- Use private endpoint for API server
- Enable audit logging to CloudWatch
- Use security groups for pods
- Implement network policies
aws eks create-cluster \
--name my-cluster \
--encryption-config '[{
"provider": {"keyArn": "arn:aws:kms:us-east-1:123456789012:key/..."},
"resources": ["secrets"]
}]' \
...
High Availability
- Deploy across multiple AZs
- Use managed node groups
- Set pod disruption budgets
- Configure horizontal pod autoscaling
Cost Optimization
- Use Spot instances for non-critical workloads
- Right-size nodes and pods
- Use Fargate for variable workloads
- Implement cluster autoscaler
- Use Karpenter for efficient scaling
Troubleshooting
Cannot Connect to Cluster
aws eks update-kubeconfig --name my-cluster --region us-east-1
aws sts get-caller-identity
aws eks describe-cluster --name my-cluster --query 'cluster.status'
Nodes Not Joining
Check:
- Node IAM role has required policies
- Security groups allow node-to-control-plane communication
- Nodes have network access to API server
kubectl get nodes
kubectl describe configmap aws-auth -n kube-system
journalctl -u kubelet
Pod Cannot Access AWS Services
kubectl describe sa my-app-sa
kubectl exec my-pod -- env | grep AWS
kubectl exec my-pod -- aws sts get-caller-identity
DNS Issues
kubectl get pods -n kube-system -l k8s-app=kube-dns
kubectl run test --image=busybox:1.28 --rm -it -- nslookup kubernetes
kubectl logs -n kube-system -l k8s-app=kube-dns
References