Managing Amazon EKS at Fleet Scale · Part 14 of 18
Upgrading an EKS Fleet: The Version Treadmill and the Extended-Support Trap
Every cluster you run is on a support clock, and the clock ends in a bill. Standard support lasts 14 months from an EKS version’s release; extended support adds 12 more at six times the price. This is the version calendar (stamped and re-verifiable), the skew rules you cannot break, the scanners that catch a deprecated API before it breaks a deploy, and the blast-radius-controlled rollout that upgrades a whole fleet without an outage — or a surprise invoice.
TL;DR
- Every EKS version gets 14 months of standard support, then 12 of extended — a 26-month lifecycle, after which the control plane auto-upgrades. AWS keeps at least three versions in standard support and gives at least 60 days’ notice before end-of-standard-support.
- The trap is the price. The control plane costs $0.10 per cluster-hour in standard support and $0.60 in extended — a 6× jump. Let a fleet drift into extended support and you have a silent, six-figure budget leak.
- Upgrade policy is a per-cluster choice. STANDARD auto-upgrades the cluster at end of standard support; EXTENDED keeps it on the old version and charges the 6× fee. Auto-upgrade moves the control plane only — your node groups stay put.
- Never skip a minor version. Upgrade one at a time, in order: control plane, then add-ons (kube-proxy, then VPC CNI, then CoreDNS), then node groups. Nodes may run at most two minor versions behind the control plane; managed node groups and Fargate only one.
- Gate every upgrade on a scan. EKS Cluster Insights flags deprecated APIs and add-on incompatibilities; Pluto and kubent do the same in CI, where you fail the build on
--exit-error. - Roll it across the fleet in waves. Canary clusters first, then widen by GitOps label (Part 4), each promotion gated by the scan — so one bad version never takes the whole fleet down.
- The entire calendar and every price below is current as of 2026-06-30 and must be re-verified at publish; it moves roughly every four months.
Run it this way
- Upgrade before end-of-standard-support, every time — treat the date as a deadline, not a target.
- Set upgrade policy deliberately per cluster; default to STANDARD so nothing drifts into the 6× fee unnoticed.
- Gate every upgrade on Cluster Insights + Pluto/kubent in CI and Argo CD pre-sync hooks.
- Roll fleet-wide in blast-radius waves — canary clusters, then promote by label.
Don’t do this
- Don’t let a cluster slide into extended support by inattention — that is the six-figure leak.
- Don’t skip a minor version, or run nodes further ahead of the control plane than the skew allows.
- Don’t flip the whole fleet at once — one bad add-on version takes out everything.
- Don’t trust yesterday’s calendar — versions roll ~every four months, so re-verify on publish day.
Every cluster is on a support clock — the 26-month treadmill you can’t step off
Here is the day-2 reality nobody sells you on cluster one: an EKS cluster is never done. From the day a Kubernetes version ships in EKS, a clock starts, and that clock ends whether you act or not. Managing a fleet is, in large part, managing hundreds of these clocks so none of them runs out on you.
The lifecycle has two phases.1 Standard support runs 14 months from a version’s EKS release. Extended support adds another 12 months, for a 26-month total. After that, the version reaches end of life and the control plane is upgraded for you — more on that, and its cost, in the next section.
Two guarantees make this plannable rather than frightening. AWS keeps at least three versions in standard support at any time, so you always have somewhere current to land. And it gives at least 60 days’ notice before a version leaves standard support.1 Sixty days is your minimum planning window for a fleet-wide upgrade — and on a fleet, sixty days goes fast.
The reason this is genuinely hard at fleet scale is not any single upgrade. It is that clusters are on different clocks — built at different times, on different versions, by different teams — and the fleet as a whole is only ever a few months from someone’s cluster falling out of standard support. Treat upgrades as a continuous program, not an annual event. Figure 1 lays out the clock and the cost cliff sitting at the end of the first phase.
The 6× bill waiting at the deadline — standard vs extended support policy
This is the headline, so let me put the number first. The EKS control plane costs $0.10 per cluster-hour in standard support and $0.60 in extended — a 6× jump for the exact same managed control plane.2 You get nothing new for the extra money. You are paying a penalty for running a version past its standard-support window, and that is the entire trap.
At one cluster the numbers look almost trivial: standard support is about $74 a month, extended about $438. At fleet scale they stop being trivial. Run 300 clusters in standard support and the control-plane floor alone is roughly $21,900 a month (300 × $0.10 × 730 hours).2 Let that same fleet drift into extended support and the same line item becomes about $131,000 a month — a six-figure leak for versions you were going to have to upgrade anyway. Part 15 works the full cost picture; here the point is narrow and sharp: extended support is the most avoidable large cost in a fleet budget.
What makes it a silent leak is that nobody chooses it out loud. A cluster crosses its end-of-standard-support date, the meter quietly switches to $0.60, and unless someone is watching the calendar the first sign is the invoice. Over a full 26-month lifecycle a cluster that rides all the way to end of life averages $0.33 per cluster-hour — the blended cost of doing nothing.2
The one setting that decides whether you pay it
Each cluster carries an upgrade policy, and it is a deliberate choice with two values.1
- STANDARD — at end of standard support, EKS auto-upgrades the cluster to the next version. You never enter extended support, and you never pay the 6× fee. The cost is that the upgrade happens on AWS’s schedule, not yours.
- EXTENDED — the cluster stays on its current version past end of standard support and you pay $0.60 per cluster-hour for up to 12 more months. You are buying time, deliberately, at a premium.
The critical detail, the one that catches teams out: the end-of-lifecycle auto-upgrade moves the control plane only.1 Your managed and self-managed node groups stay exactly where they are. So an auto-upgrade is not a rescue — it can leave you with a control plane on a new version and node groups two versions behind, which is its own problem (the skew rules in the next section). Auto-upgrade prevents the bill; it does not do the upgrade for you.
Where every version stands today — the calendar that moves under you
Everything above is a rule; this section is the live board, and the live board is the part that expires. The calendar below is current as of 2026-06-30 and must be re-verified against the AWS version page on publish day.1 Versions roll roughly every four months, so if you are reading this more than a quarter after that date, treat the specific dates as illustrative and pull the current ones.
As of 2026-06-30, 1.36 is the newest version, and the board looks like this:1
| Version | Phase | Key date | What it means for you |
|---|---|---|---|
| 1.36 | Standard | Std ends 2027-08-02 | Newest; the safe landing target |
| 1.35 | Standard | Std ends 2027-03-27 | Comfortable |
| 1.34 | Standard | Std ends 2026-12-02 | Plan the next hop |
| 1.33 | Standard | Std ends 2026-07-29 | Imminent — upgrade now or start paying 6× |
| 1.32 | Extended | Ext ends 2027-03-23 | Last version with AL2 AMIs; on the $0.60 meter |
| 1.31 | Extended | Ext ends 2026-11-26 | On the $0.60 meter |
| 1.30 | Extended | Ext ends 2026-07-23 | Imminent — control plane auto-upgrades after this |
Two rows should make you move. 1.33 leaves standard support on 2026-07-29 — any cluster still on it after that date starts paying the 6× fee. And 1.30 leaves extended support on 2026-07-23, at which point its control plane auto-upgrades whether or not the workloads are ready. Both are inside the 60-day window right now; on a fleet, that is a live incident, not a future one.
The breaking changes hiding in specific hops
A version number is not just a support date — some hops change the ground under your workloads. Three that matter as of this calendar:1
- 1.32 is the last version to ship Amazon Linux 2 AMIs. From 1.33 on, nodes are AL2023 or Bottlerocket only. If you still bake AL2 node images, the jump to 1.33 is an AMI migration, not just a version bump.
- Ingress-NGINX is being retired upstream (March 2026). Plan a migration to the Gateway API. This is a workload change, not a control-plane one, and it is the connectivity story from Part 9 — fold it into your upgrade planning so it is not a separate fire drill.
gitRepovolumes are permanently disabled in 1.36. Anything still mounting agitRepovolume breaks on that hop. The pre-upgrade scanners in the next section are exactly how you find out before it does.
The pattern to internalize: the support date tells you when you must upgrade; the release notes tell you what will break when you do. You need both, and you need them per version, because the fleet spans several.
What you can and can’t skip — the skew rules and the upgrade order
Before you upgrade anything, learn the two rules Kubernetes will enforce for you, because breaking them is how a routine upgrade becomes an outage.
Rule one: one minor version at a time. You cannot jump from 1.30 to 1.33 in a single step. Each upgrade moves the control plane exactly one minor version, so catching a badly-lagged cluster up is a sequence of hops, each with its own scan and its own soak time.3 This is the real cost of letting a cluster fall behind: a cluster three versions back is three upgrades away from current, not one.
Rule two: the version skew between nodes and control plane is bounded. A node’s kubelet may run at most two minor versions behind the control plane. But managed node groups and Fargate support only a one-version skew — the tighter, and in practice the binding, constraint for most fleets.3 This is why the control plane goes first and the nodes follow promptly: upgrade the control plane and your nodes are now one version behind, right at the managed-node-group limit, so the node upgrade is not optional cleanup — it is the second half of the same operation.
Those two rules dictate a fixed order. You upgrade the control plane, then the add-ons, then the node groups — and the add-ons themselves go in a specific sequence (Figure 2).
Within the add-ons, the sequence is kube-proxy, then the VPC CNI, then CoreDNS.3 The instinct behind it is compatibility: bring the networking data plane (kube-proxy and the CNI) in line with the new control plane before you touch cluster DNS, which depends on that networking already being healthy. Then, and only then, roll the node groups — drain and replace, so pods reschedule onto nodes running the new kubelet.
Find the blockers before they find you — the pre-upgrade scanners
The single most common way an EKS upgrade breaks is a deprecated API. A Kubernetes minor version removes an API that your manifests, your Helm charts, or some third-party controller still call, and the upgrade goes through cleanly while the workloads that depended on that API quietly stop working. You do not want to discover this in production. The whole game is to find it before you upgrade, and there is a good toolchain for exactly that.
Start with what AWS builds in. EKS Cluster Insights (also called Upgrade Insights) is a built-in scanner that checks each cluster for upgrade blockers — deprecated API usage and add-on incompatibilities — and reports a status of Passing, Warning, Error, or Unknown.4 Crucially, it inspects actual deprecated-API calls over the trailing 30 days, not just what is present in your manifests, so it catches the controller that hits a doomed API once a night as well as the obvious Deployment. It costs nothing and it is already watching every cluster; read it first.
Cluster Insights is necessary but not sufficient, because it sees the live cluster — not the change you are about to merge. Complement it with tools that scan your source of truth:
- Pluto finds deprecated and removed API versions in static IaC and Helm charts, and can also check the live cluster.5 Because it reads the repo, it catches a bad API in a manifest that has not been applied yet — the one Cluster Insights cannot see because it never ran.
- kubent (kube-no-trouble) does the same detection against a live cluster and its Helm releases — a fast, focused second opinion.6
- eksup and GoNoGo go further into upgrade readiness — eksup produces an EKS-specific pre-upgrade analysis and playbook; GoNoGo scores whether a cluster is safe to upgrade.78 Reach for these when you want a structured go/no-go per cluster rather than a raw list of findings.
The discipline that makes this matter at fleet scale is wiring the scan into the pipeline so it is not a thing anyone can forget. Run Pluto or kubent in CI and fail the build on --exit-error when a removed API shows up, so a manifest that would break the next upgrade never merges.5 Add an Argo CD pre-sync hook that runs the same check, so a sync that would introduce a doomed resource is stopped before it lands.4 The goal is a fleet where a deprecated API cannot reach a cluster in the first place, and where every upgrade is gated on a green scan.
Rolling it across the fleet without an outage — canary clusters, then waves
You now have the rules, the calendar, and the scans. The last problem is scale: you are not upgrading one cluster, you are upgrading hundreds, and the failure you fear is a version or add-on that passes every scan and still breaks something you did not anticipate on the clusters that matter most. The answer is to never expose the whole fleet to a change at once. Control the blast radius (Figure 3).
The mechanics are the same GitOps machinery the golden path already uses (Part 4). You pick the target version in the fleet repo, and an Argo CD ApplicationSet fans it out to clusters by label. So a wave is nothing more than which clusters match at each step: env=dev first, then env=staging, then env=prod. Promoting is moving the label match forward; pausing is stopping it. The same commit that rolls a version out rolls it back.
Two things make the waves trustworthy. First, canary clusters go first — a small set you are willing to break, upgraded and then given real soak time so a latent problem has a chance to surface before the next wave. Second, every promotion is gated by the same scan from the previous section. A wave does not advance because a timer expired; it advances because Cluster Insights is Passing and CI is green on the clusters already upgraded. Blast-radius control plus a gate at every step is what lets you upgrade a fleet of hundreds and still sleep.
What to actually do — the thresholds that keep you off the treadmill’s shoulder
The mechanics all reduce to a handful of standing decisions. Wire these into how the fleet runs and the version treadmill becomes routine instead of recurring crisis.
- Upgrade before end-of-standard-support, always. The 60-day notice window is the deadline; cross it and the 6× fee starts.
- Default every cluster to STANDARD. Choose EXTENDED only as a conscious, dated exception — never open-ended.
- Gate every upgrade on a green scan. Cluster Insights Passing, plus Pluto/kubent green in CI on
--exit-error. - Never skip a minor version; keep nodes inside the skew. One hop at a time — control plane, then add-ons, then nodes — with managed node groups no more than one version behind.
- Roll fleet-wide in gated waves. Canary clusters with real soak time, then promote by label.
Do that, and you have turned the two failure modes into non-events. You never drift into extended support, so the 6× fee never appears on the invoice by accident. And you never ship a version that breaks on a deprecated API, because a scan caught it in CI and a canary caught what the scan missed. That is what a day-2 upgrade program is for: not heroics on upgrade day, but a fleet that is never more than a routine hop from current.
One last honest caveat, because it is the whole reason this article is dated. Every version, every date, and every price above is current as of 2026-06-30 and rolls roughly every four months. Before you act on any specific number here, re-verify it against the AWS version calendar and pricing page. The rules are stable; the board is not.
Sources
Grounding for the claims above. The version calendar and control-plane pricing are current as of 2026-06-30 and must be re-verified against the AWS pages the day this publishes — they roll roughly every four months.
- AWS — Amazon EKS Kubernetes versions and support policy: standard support (14 months) and extended support (12 months), the ≥3-versions-in-standard and ≥60-days-notice guarantees, the live version calendar, per-version breaking changes (AL2 AMIs, Ingress-NGINX,
gitRepo), and the STANDARD/EXTENDED upgrade policy with control-plane-only auto-upgrade. docs.aws.amazon.com/.../kubernetes-versions.html - AWS — Amazon EKS pricing: control plane at $0.10/cluster-hour (standard) and $0.60/cluster-hour (extended), the 6× jump, and the blended $0.33/cluster-hour lifecycle average. aws.amazon.com/eks/pricing
- AWS — Updating an EKS cluster: the upgrade order (control plane → kube-proxy → VPC CNI → CoreDNS → node groups), one-minor-version-at-a-time, and the node/control-plane version skew (≤2, managed node groups and Fargate 1). docs.aws.amazon.com/.../update-cluster.html
- AWS — EKS Cluster Insights (Upgrade Insights): built-in upgrade-blocker scanner for deprecated APIs and add-on compatibility, with Passing/Warning/Error/Unknown status over the trailing 30 days; usable in CI and Argo CD pre-sync hooks. docs.aws.amazon.com/.../cluster-insights.html
- Pluto (Fairwinds) — finds deprecated/removed API versions in static IaC and Helm charts as well as live clusters; supports
--exit-errorto fail a CI build. github.com/FairwindsOps/pluto - kubent (kube-no-trouble) — detects deprecated and removed Kubernetes APIs against a live cluster and its Helm releases. github.com/doitintl/kube-no-trouble
- eksup — EKS-specific pre-upgrade analysis and playbook generation. github.com/clowdhaus/eksup
- GoNoGo (Fairwinds) — scores whether an EKS cluster is safe to upgrade. github.com/FairwindsOps/GoNoGo