Kubernetes 1.34 Hits End of Life: How to Upgrade EKS, GKE and AKS Without Breaking Production
Kubernetes 1.34 is losing upstream support, and EKS, GKE and AKS each run a different clock. Here is the exact upgrade order that does not break production, the removed APIs to catch first, and what each cloud charges you for running late.
The safe upgrade order never changes: scan live cluster state for removed APIs with Pluto or kubent, upgrade the control plane one minor version at a time, roll node groups with surge or blue-green pools while the old pool stays alive, upgrade add-ons (CNI, CSI, ingress, cert-manager, Argo CD) last, and run smoke tests before you delete the old node pool.
Upstream support is about 14 months, but your real deadline is your provider's. EKS sells paid extended support on top of 14 months of standard support, GKE dates depend on your release channel, and AKS gives community support then LTS, which requires the Premium tier. Confirm your own date in your console, not in a blog post.
You cannot skip a minor version on EKS, GKE or AKS. In-place downgrade is either impossible or narrowly time-boxed, so your dependable rollback is node-level (shift traffic back to the old pool) or cluster-level (a blue-green cluster behind DNS). Most teams discover this mid-incident.
What breaks production is almost never the control plane upgrade. It is removed API versions in Helm charts and CRDs, PodDisruptionBudgets that block every eviction and stall drains, node image changes, and controllers with their own version-skew matrices.
Three upstream releases a year times every cluster you run is 6-12 forced upgrade windows a year. At that point you either automate with provider channels plus a CI deprecation gate, build your own OpenTofu plus Argo CD pipeline, or hand cluster lifecycle to a platform like Qovery.
Here is what actually takes a cluster down during a Kubernetes upgrade: a Helm chart still shipping a removed API version, and a PodDisruptionBudget that refuses every eviction so your node drain hangs for hours. The control plane bump itself is usually a non-event. I have run these upgrades across AWS, GCP and Azure, and the pattern is identical every time - the boring part is safe, the part nobody audited is what pages you at 2am.
Kubernetes 1.34 is now reaching the end of its upstream life, and EKS, GKE and AKS each put you on a different clock with a different bill. This is the runbook: what the real deadline is, what to check before you touch anything, the exact order of operations, and how to stop doing this by hand four times a year.
What happens when Kubernetes 1.34 reaches end of life, and how long do you really have?
When 1.34 reaches end of life upstream, the Kubernetes project stops publishing patches for it, security patches included, but your managed cluster keeps running. EKS, GKE and AKS each extend that deadline on their own terms and at their own price, so the date that governs you is your provider's, not the upstream one.
Upstream ships roughly three minor releases a year, about one every four months, and supports each for around 14 months: about 12 months of patch support plus a 2-month maintenance window (kubernetes.io/releases). Kubernetes 1.34 was released upstream on August 27, 2025, and its end-of-life date is published in the release history table (kubernetes.io/releases) - confirm the exact day there, because patch cadence can move it.
On EKS, a minor version gets 14 months of standard support, then 12 months of extended support, for 26 months total. If you do nothing by the end of extended support, AWS auto-upgrades your control plane to the oldest supported version (EKS version lifecycle). For 1.34 specifically, AWS lists end of standard support as December 2, 2026 and end of extended support as December 2, 2027 - check your own date with the CLI below.
On GKE, your end-of-support date is a function of your release channel. Rapid, Regular and Stable give you roughly the upstream window, while the Extended channel lets you hold a minor version far longer, backed by maintenance windows and exclusions (GKE release schedule).
On AKS, you get about 12 months of community support per minor version, then Long Term Support, which requires the Premium tier and extends the window for up to two more years before a forced upgrade (AKS supported versions, AKS LTS). AKS lists 1.34 end of life as November 2026.
Nothing breaks at midnight on the EOL date. What changes is that the next control-plane or ingress CVE has no patch for you, your SOC 2 and ISO auditors start flagging an unsupported version, support tickets get harder, and on EKS a visible line item lands on the bill. To find your real date:
BASH|EKS
aws eks describe-cluster --name <cluster> --query cluster.version
# GKE
gcloud container clusters describe <cluster> \
--format='value(currentMasterVersion,releaseChannel.channel)'
# AKS
az aks get-upgrades --resource-group <rg> --name <cluster> -o table
Exactly the upstream ~14 months, no vendor backports (docs)
None, you fork or you upgrade
Nothing, your cluster just runs unpatched
No, kubeadm upgrades one minor at a time
Whatever you build: surge, blue-green, drain-and-replace
No supported downgrade path
What do you check before you touch the control plane?
Run the deprecation audit first. Scan live cluster state and Helm release manifests with Pluto or kubent, then check every add-on against its own compatibility matrix. Upgrade outages come from removed API versions, incompatible controllers and PodDisruptionBudgets that block drains, not from the control plane bump.
Scan with Pluto (FairwindsOps) and kubent (kube-no-trouble) against what is actually running, not just your Git repo. CRDs installed by charts drift behind what you committed, so scan the cluster and the Helm releases:
BASH|Pluto: check committed manifests and live Helm releases
pluto detect-files -d ./manifests
pluto detect-helm --output wide
# kubent: scans the current kube-context (live objects + Helm) by default
kubent
Then read the Kubernetes deprecated API migration guide for your target version. The recurring offenders are predictable: policy/v1beta1 PodDisruptionBudget and PodSecurityPolicy, batch/v1beta1 CronJob, autoscaling/v2beta1 HorizontalPodAutoscaler and discovery.k8s.io/v1beta1 EndpointSlice all went away in 1.25, and the flowcontrol.apiserver.k8s.io beta groups were removed in later releases. The deprecation policy guarantees a GA API is supported for at least a year or three releases before removal, which is exactly the window a stale Helm chart quietly burns through.
Audit your add-ons against their support matrices before the upgrade, not after: the CNI (VPC CNI, Calico, Cilium), CSI drivers (EBS, PD, Azure Disk), ingress (ingress-nginx, AWS Load Balancer Controller, Gateway API implementations), cert-manager, external-dns, Argo CD or Flux, kube-prometheus-stack, and any service mesh. Each has its own supported Kubernetes range, and a controller one release too old will crash-loop against a new API server.
Mind the version skew policy: kubelet may run up to 3 minor versions behind the API server, kube-controller-manager and kube-scheduler up to 1 behind, and kubectl within 1 minor version either side. This is why you move one minor at a time and keep nodes close to the control plane.
PodDisruptionBudgets are the quiet killer. A PDB with minAvailable equal to the replica count blocks every eviction and silently stalls a node drain, which Kubernetes documents directly (configure PDB, safely drain a node). Flag single-replica Deployments and StatefulSets with no surge room too.
Each cloud adds its own gotchas: EKS managed add-on versions plus the migration from IRSA to EKS Pod Identity, GKE node image changes (containerd, cgroup v2), and AKS treating a node image upgrade as a separate operation from the Kubernetes version upgrade. Finally, confirm a tested restore path - Velero or provider snapshots for cluster state, etcd snapshots on self-managed, and database backups you have actually restored, not just a backup job that exists.
Pre-flight checklist you can lift whole:
Pluto and kubent clean against live cluster state and every Helm release.
Deprecated API migration guide read for the target version, offenders fixed.
Every add-on confirmed against its Kubernetes compatibility matrix.
Version skew between control plane, nodes and kubectl within policy.
A restore actually tested, not just a backup that exists.
What is the safe order of operations for a Kubernetes upgrade?
Rehearse on a staging cluster that matches production, upgrade the control plane one minor version at a time, then node groups with surge or blue-green pools, then add-ons in dependency order, then validate before you delete the old pool. That five-step order is identical on EKS, GKE and AKS. Only the commands change.
Step 0 - make staging match production. Same Kubernetes version, same add-on versions, same node image family. A rehearsal on a drifted staging cluster is the single most common reason a "tested" upgrade still fails in prod.
Step 1 - control plane, one minor at a time (1.34 to 1.35, then 1.35 to 1.36). No provider lets you jump minors (GKE, AKS).
Step 2 - node groups, old pool stays alive. Use managed node group surge upgrades on EKS, surge or blue-green node pools on GKE (strategies), or max-surge on AKS. GKE blue-green keeps the old "blue" pool through a soak period so you can roll back fast; keep any old pool until smoke tests pass.
Step 3 - add-ons in dependency order. CNI and CSI first, then ingress and cert-manager, then application-layer controllers and the service mesh.
Step 4 - validate against an explicit checklist. API server reachable, all DaemonSets rolled, PVCs attaching and mounting, ingress serving real traffic, HPA scaling, cluster autoscaler or Karpenter provisioning, and your own smoke tests green.
On rollback, be honest with yourself early. EKS lets you roll an in-place upgrade back within 7 days of completion (docs), GKE offers a soak-and-rollback window on 1.33+ minor upgrades (docs), and AKS does not support downgrades at all (docs). The rollback you can always rely on is node-level (shift workloads back to the old pool) or cluster-level (a blue-green cluster behind DNS or a global load balancer).
Get the drain mechanics right so you do not cause the outage yourself: realistic terminationGracePeriodSeconds, topology spread constraints, preStop hooks, one node at a time, and review PDBs rather than deleting them outright. And run the production window when the people who own the add-ons are awake, not just the person running the command.
Stop scheduling Kubernetes upgrades by hand.
Qovery runs managed Kubernetes clusters inside your own AWS, GCP, Azure or Scaleway account - or on a cluster you already operate - and handles the version lifecycle for you. Start in under 10 minutes.
How do EKS, GKE and AKS upgrades differ in practice?
The sequence is the same on all three, but the commands, the node strategy and the automatic behavior you may not have opted into differ enough that one generic runbook will bite you. GKE decides your dates by release channel, AKS treats node image upgrades as a separate operation, and EKS auto-upgrades you at the end of paid extended support.
EKS. Upgrade with aws eks update-cluster-version or eksctl upgrade cluster. You choose between managed node groups, self-managed nodes and Karpenter-provisioned nodes, and between EKS managed add-ons and self-installed charts. Extended support is billed, and at the end of it AWS upgrades your control plane automatically whether you are ready or not (docs).
GKE. The release channel decides both your dates and your automation: Rapid, Regular, Stable or Extended, with maintenance windows and exclusions to control timing, surge versus blue-green node pool strategies, and Autopilot upgrading the whole thing for you (release channels).
AKS. Use az aks upgrade for the control plane and node pools, and remember the node image upgrade is a separate operation. Auto-upgrade channels (patch, stable, rapid, plus the legacy node-image) decide what moves automatically (docs), and LTS sits on the Premium tier.
Two traps hit everyone. First, Karpenter and the cluster autoscaler keep replacing and consolidating nodes during an upgrade, and drift-based replacement interacts badly with PDBs on a half-upgraded cluster - plan for the churn. Second, the OpenTofu/Terraform trap: if the version is pinned in code and you upgrade through the console or CLI, the next apply tries to revert or recreate node pools. Bump the version in code first, then apply.
Multi-cluster is where this compounds. Staging plus production across two regions is four upgrade cycles per release, several times a year, which is the real argument for automating the whole thing.
How much engineering time does staying on a supported Kubernetes version actually cost?
Budget roughly one to three engineer-days per cluster per upgrade once you count the deprecation audit, the staging rehearsal, the out-of-hours production window and the post-upgrade fixes. Then multiply by up to three releases a year and by every cluster you run. For a ten-person team with four clusters, cluster lifecycle quietly becomes a permanent part-time job, and paid extended support is a line item, not a free pass.
The per-upgrade work is always the same parts: deprecation audit, add-on matrix check, staging rehearsal, production window (usually out of hours), post-upgrade firefighting, and the documentation update nobody enjoys. Four clusters times two to three upgrades a year is 8 to 12 cycles, before node image patching and CVE-driven out-of-band updates.
This is not a niche problem. The 2025 CNCF annual survey found tool complexity (37%) and the skills gap (33%) among the top barriers to cloud native adoption, with the average enterprise running several clusters (CNCF). And maintenance already dominates engineering time: Stripe's Developer Coefficient found developers spend about 42% of their week on maintenance and bad code (Stripe). Cluster upgrades land squarely in that bucket.
There is also a bus-factor problem. In most small teams one person owns the upgrade runbook, and upgrades stop when they take holiday or leave. So you really have three choices: automate it, buy it, or keep paying the tax in weekends and extended-support invoices.
Path
Direct cloud cost
Security patches
Support entitlement
Compliance exposure
Engineering effort/year
Upgrade on schedule
Standard control-plane rate (EKS $0.10/cluster/hour, pricing)
Full, current
Full
Clean
8-12 cycles of hands-on work
Run on extended/LTS support
EKS extended support $0.60/cluster/hour, 6x standard (pricing); AKS LTS requires Premium tier (pricing)
Backported by the provider
Full
Usually acceptable
Lower, but you still upgrade eventually
Run past end of support
Low until the forced auto-upgrade, then an unplanned one
None upstream; new CVEs may go unpatched
Degraded or refused
Auditors flag an unsupported version
Unbounded: firefighting on your worst day
How can you automate Kubernetes upgrades instead of running them by hand every quarter?
There are three realistic paths, and they remove different parts of the work. Provider auto-upgrade handles the control plane and node images for free, a self-built OpenTofu plus Argo CD pipeline adds deprecation gating and add-on version control, and an internal developer platform takes the whole cluster lifecycle off your calendar. Pick by how much of Kubernetes you actually want to own.
Path 1 - provider automation. GKE release channels and auto-upgrade, AKS auto-upgrade channels, and EKS auto-upgrade at the end of extended support are all free, well documented, and genuinely good for stateless clusters. To be fair: GKE release channels and AKS stable/rapid channels are the right default for a lot of teams, and I recommend them. The trade-off is timing control, which you claw back with maintenance windows and exclusions.
The honest gap: provider auto-upgrade moves the control plane and node images, but it does not scan your Helm charts for removed APIs, does not keep your add-ons on compatible versions, does not give you a rehearsal environment that matches production, and does not coordinate upgrade order across environments. Those four are exactly where upgrades break.
Path 2 - build it yourself. Pin versions in OpenTofu/Terraform, run Pluto or kubent as a CI gate so a removed API version can never merge, use Argo CD or Flux to hold add-ons at compatible versions, and encode blue-green node pools in the module. This is the right call when someone genuinely owns Kubernetes as part of their job.
Path 3 - an internal developer platform. Qovery is cloud-agnostic and Kubernetes-native. It runs inside your own AWS account, GCP project, Azure subscription or Scaleway project (BYOC, so the cloud bill and any Savings Plans stay in your name), or on a Kubernetes cluster you already operate, and it performs managed Kubernetes cluster upgrades so the version lifecycle stops being a quarterly project you schedule by hand.
Why that helps with upgrades specifically: applications redeploy from the same definition on every environment, preview environments per pull request plus environment auto-stop make a cheap production-shaped rehearsal practical, and per-environment RBAC keeps the production window controlled.
Be clear on the limits. Provider auto-upgrade is free and sufficient for simple clusters. A self-built pipeline gives maximum control. Managed Argo offerings like Akuity and Codefresh solve application delivery, not cluster versions, and fleet managers like Rafay and Plural target large multi-cluster estates. These combine happily - plenty of teams keep Argo CD for apps while letting the platform or the provider own cluster versions.
Approach
Who triggers
Deprecated-API check
Node strategy
Add-on compatibility
Rehearsal env
Rollback
Timing control
Cost model
Best-fit team
Manual runbook
You
Manual (Pluto/kubent)
Manual surge/blue-green
Manual
If you build one
Node/cluster-level
Full
Engineer-time
Any, until it doesn't scale
Provider auto-upgrade
Provider
No
Provider default
No
No
Channel-limited
Windows/exclusions
Free
Stateless, simple clusters
Self-built OpenTofu + Argo/Flux
You via pipeline
Yes, as CI gate
Coded in module
Argo/Flux pins
You build it
Node/cluster-level
Full
Build + maintain
Owns Kubernetes in-house
Managed Argo (Akuity, Codefresh)
You
App-level only
N/A (apps)
App-level
No
App rollback
Full
Per-seat/usage
GitOps-heavy app delivery
Fleet manager (Rafay, Plural)
Platform team
Partial
Orchestrated
Partial
Varies
Orchestrated
Policy-driven
Platform license
Large multi-cluster estates
Qovery
Platform + git push
Via pipeline + previews
Managed
Managed
Preview envs per PR
Node/cluster-level
Per-environment
BYOC in your account
Small teams, no platform team
What should you do this month if your cluster is still on Kubernetes 1.34?
Start today, in this order. Each step is small enough to finish in an afternoon.
Look up the real end-of-support date for every cluster (aws eks describe-cluster, GKE release notes for your channel, az aks get-upgrades) and put it in the shared calendar as a hard deadline.
Run Pluto and kubent against every cluster and every Helm release today. Fix removed APIs before touching anything else.
Pin and document current add-on versions, then check each one against the target Kubernetes version's compatibility matrix.
Rehearse the full upgrade on staging with identical add-on versions and node image family. If staging does not match prod, fix the drift first.
Upgrade one minor version at a time: control plane, then nodes, then add-ons, using surge or blue-green node pools so rollback stays node-level.
Schedule the production window, review PDBs so drains can complete, and keep the old node pool until smoke tests pass.
Book the next upgrade immediately. If you run more than two clusters, decide now whether you automate it, buy it, or keep paying for it in weekends.
Frequently asked questions
How long is each Kubernetes minor version supported upstream?
About 14 months: roughly 12 months of patch support plus a 2-month maintenance period, with new minor releases arriving about three times a year (kubernetes.io/releases). Your managed provider's window is usually longer, and it is the one that actually governs you.
When exactly does Kubernetes 1.34 reach end of life on EKS, GKE and AKS?
The dates differ by provider. EKS lists end of standard support as December 2, 2026 and end of extended support as December 2, 2027 (EKS); AKS lists end of life as November 2026 (AKS); GKE depends on your release channel (GKE). Confirm your own date in your console, because these shift with patch cadence.
What happens if my EKS, GKE or AKS cluster keeps running past end of support?
The cluster keeps running, but you stop getting control-plane CVE patches, support tickets get degraded or refused, and auditors flag the unsupported version. AWS auto-upgrades the control plane at the end of extended support (EKS), and Azure may auto-upgrade a cluster that falls more than three minor versions out of support (AKS).
Can you skip a Kubernetes minor version when upgrading EKS, GKE or AKS?
No. All three upgrade one minor version at a time for supported versions (GKE, AKS), so going from 1.34 to 1.36 means passing through 1.35. This is enforced by the kubelet/API-server version skew policy.
Can you roll back or downgrade a Kubernetes upgrade on a managed cluster?
Only in narrow windows. EKS allows rolling an in-place upgrade back within 7 days (EKS), GKE offers a soak-and-rollback window on 1.33+ minor upgrades (GKE), and AKS does not support downgrades (AKS). Your reliable rollback is node-level or a blue-green cluster behind DNS.
How do you find deprecated or removed Kubernetes APIs before upgrading?
Scan live cluster state and Helm releases with Pluto (pluto detect-helm --output wide) or kubent (kubent), then cross-check the deprecated API migration guide for your target version. Scanning the live cluster matters because chart-installed CRDs drift behind your Git repo.
How long does a Kubernetes cluster upgrade take, and does it cause downtime?
The control plane upgrade is typically minutes to under an hour, and on regional/HA control planes the API stays available (GKE). Node rollout is the long part and causes no downtime if you use surge or blue-green pools and your PodDisruptionBudgets allow evictions; a bad PDB can stall a drain for hours (Kubernetes).
Can Qovery handle Kubernetes cluster upgrades for us, and does it work outside AWS?
Yes. Qovery performs managed Kubernetes cluster upgrades and is cloud-agnostic: it runs inside your own AWS, GCP, Azure or Scaleway account under BYOC, or on a Kubernetes cluster you already operate. It is not AWS-only, and the cloud bill stays in your name.
One real example of why the patches matter: the IngressNightmare vulnerability (CVE-2025-1974, CVSS 9.8) disclosed in March 2025 allowed unauthenticated remote code execution in ingress-nginx versions below 1.11.5 and 1.12.1, and by default could reach every Secret in the cluster (Kubernetes blog). On a supported cluster you patch it. On an abandoned one, you find out the hard way. Keep your clusters current - by hand if you must, automated if you can.
Romaric founded Qovery to make Kubernetes accessible to every engineering team. He writes about platform strategy, developer experience, and the future of cloud infrastructure.
Next step
Stop scheduling Kubernetes upgrades by hand.
Qovery runs managed Kubernetes clusters inside your own AWS, GCP, Azure or Scaleway account - or on a cluster you already operate - and handles the version lifecycle for you. Start in under 10 minutes.