Amazon EKS — Upgrade Planning

2 minute read

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

  1. Dev environment: Upgrade first, run integration tests
  2. Staging: Mirror production workloads, validate thoroughly
  3. 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

  1. Stay within one version of latest — don’t fall more than 2 versions behind
  2. Run pluto before every upgrade — catch deprecated APIs early
  3. Use EKS upgrade insights — AWS flags known issues specific to your cluster
  4. Test in non-production first — always
  5. Plan for extended support costs — $0.60/hr/cluster adds up fast ($4,380/year)
  6. Document your upgrade runbook — consistent process prevents mistakes

Updated: