Amazon EKS — Upgrade Planning
Upgrades should be planned, not reactive. Understanding the EKS version lifecycle, identifying deprecated APIs, and testing in non-production environments are critical for zero-downtime upgrades.
EKS Kubernetes Version Lifecycle
| Phase | Duration | Support |
|---|---|---|
| Standard support | ~14 months after release | Full support, no extra cost |
| Extended support | 12 months after standard ends | Additional $0.60/cluster/hour |
| End of life | After extended support | Cluster auto-upgraded to latest |
# Check current cluster version
aws eks describe-cluster --name my-cluster --query "cluster.version"
# List available EKS versions
aws eks describe-addon-versions --query "addons[0].addonVersions[*].compatibilities[*].clusterVersion" --output text | tr '\t' '\n' | sort -u
EKS Upgrade Insights
EKS provides upgrade insights to flag potential issues:
aws eks list-insights --cluster-name my-cluster
aws eks describe-insight \
--cluster-name my-cluster \
--id <insight-id>
Insights check for:
- Deprecated API usage
- Add-on version compatibility
- Unhealthy node groups
- Workload compatibility issues
Pre-Upgrade Checklist
1. Check Deprecated APIs
# Install pluto (detects deprecated APIs)
brew install FairwindsOps/tap/pluto
# Scan cluster
pluto detect-all-in-cluster
# Scan Helm releases
pluto detect-helm --output wide
Example output:
NAME KIND VERSION REPLACEMENT DEPRECATED REMOVED
my-ingress Ingress networking.k8s.io/v1beta1 networking.k8s.io/v1 true true
my-pdb PodDisruptionBudget policy/v1beta1 policy/v1 true true
2. Check Add-on Compatibility
# List current add-on versions
aws eks describe-addon --cluster-name my-cluster --addon-name vpc-cni --query "addon.addonVersion"
aws eks describe-addon --cluster-name my-cluster --addon-name coredns --query "addon.addonVersion"
aws eks describe-addon --cluster-name my-cluster --addon-name kube-proxy --query "addon.addonVersion"
# Check compatible versions for target K8s version
aws eks describe-addon-versions --addon-name vpc-cni --kubernetes-version 1.30 \
--query "addons[0].addonVersions[*].addonVersion"
3. Check Node Health
kubectl get nodes
kubectl describe nodes | grep -A5 Conditions
4. Verify PodDisruptionBudgets
kubectl get pdb --all-namespaces
5. Review Release Notes
Always read:
Upgrade Planning Matrix
| Check | Tool | Action |
|---|---|---|
| Deprecated APIs | pluto, kubectl convert | Update manifests |
| Add-on versions | aws eks describe-addon-versions | Match to target K8s version |
| Node group AMIs | aws eks describe-nodegroup | Plan rolling update |
| Helm charts | helm list | Check chart supports new K8s version |
| Custom webhooks | kubectl get validatingwebhookconfigurations | Test with new API server |
| PDBs | kubectl get pdb | Ensure graceful node drains |
Testing Strategy
- Dev environment: Upgrade first, run integration tests
- Staging: Mirror production workloads, validate thoroughly
- Production: Schedule maintenance window, upgrade with monitoring
# Create a test cluster at the target version
eksctl create cluster \
--name upgrade-test \
--version 1.30 \
--nodegroup-name test-nodes \
--node-type t3.medium \
--nodes 2
Best Practices
- Stay within one version of latest — don’t fall more than 2 versions behind
- Run pluto before every upgrade — catch deprecated APIs early
- Use EKS upgrade insights — AWS flags known issues specific to your cluster
- Test in non-production first — always
- Plan for extended support costs — $0.60/hr/cluster adds up fast ($4,380/year)
- Document your upgrade runbook — consistent process prevents mistakes