Kubernetes 1.35 is the last release supporting containerd 1.x: a 2026 upgrade guide

Kubernetes 1.35 is the last release to support containerd 1.x; plan the containerd 2.0 move before upgrading to 1.36.

Read time
15 min
Word count
2.6K
Sections
11
FAQs
8
Share
Data-center rack with a glowing container module being swapped, cyan edge lighting
Moving nodes from containerd 1.x to 2.0 before upgrading past Kubernetes 1.35.
On this page · 11 sections
  1. Why containerd 2.0 is now a hard dependency
  2. What actually breaks: the config that stops loading
  3. How to find the nodes that are about to break
  4. The migration, step by step, for self-managed nodes
  5. Managed clusters: GKE, EKS and AKS are not the same
  6. DRA, in-place resize, and the other changes worth planning for
  7. India-specific considerations
  8. A pragmatic upgrade posture
  9. FAQ
  10. How eCorpIT can help
  11. References

Summary. Kubernetes 1.35, released on 17 December 2025, is the final minor release that supports containerd 1.x. From the next minor version, containerd 2.0 becomes the floor, so any node still on containerd 1.6 or 1.7 will stop being supported once you move past 1.35. As of July 2026 the project maintains three minor branches, 1.36, 1.35 and 1.34, with 1.36.2 and 1.35.6 both shipped on 9 June 2026 and 1.33 already out of support since 28 June 2026. The migration is not a version bump you can defer to the same maintenance window as the control plane: containerd 2.0 changes the CRI plugin path and deprecates the old registry config, so a node config that worked for years can silently fail to load. Managed platforms differ too. A production control plane runs about $0.10 per cluster per hour (near $73 per month) on Amazon EKS, Google GKE and Azure AKS Standard, while AKS Premium at $0.60 per hour (about $438 per month) buys long-term support for teams that cannot keep pace with the three-release window. This guide covers what breaks, how to detect at-risk nodes, and a concrete order of operations.

If your platform team treats Kubernetes upgrades as routine, the move off containerd 1.x is the one to slow down for. The runtime sits below the kubelet, so a broken container runtime does not surface as a clean API error. It surfaces as nodes that will not pull images, pods stuck in ImagePullBackOff, or a kubelet that refuses to register. The good news: the deprecation has been visible for more than a year, and the fix is mechanical once you know the two things that actually change.

Why containerd 2.0 is now a hard dependency

Kubernetes talks to a container runtime through the Container Runtime Interface (CRI). For most clusters that runtime is containerd. The Kubernetes release notes have been walking containerd 1.x toward the exit across three releases, and 1.35 is the last stop.

The timeline, drawn from the Kubernetes release history and the v1.35 sneak peek, works like this. containerd 1.6 and 1.7 were deprecated in Kubernetes 1.34. They receive their final support in 1.35. They are slated for removal in the following minor release, which makes containerd 2.0 the practical minimum once you move past 1.35. The Kubernetes container runtimes documentation is the reference for supported versions.

There is a subtlety worth stating plainly, because it trips teams up. containerd 1.6 is a long-term-support branch and lives on its own schedule, so "containerd 1.6 is still supported by the containerd project" and "Kubernetes still supports containerd 1.6" are two different claims. Kubernetes drops containerd 1.x on the Kubernetes timeline regardless of containerd's own LTS. The version that governs your upgrade is the Kubernetes one.

containerd branch Kubernetes 1.34 Kubernetes 1.35 Kubernetes 1.36 and later
containerd 1.6 Deprecated Final support Removed
containerd 1.7 Deprecated Final support Removed
containerd 2.0 Supported Supported Minimum required
containerd 2.1 or newer Supported Supported Supported
Docker Engine (direct) Not a CRI runtime Not a CRI runtime Not a CRI runtime

The dates matter because the support window is short. Kubernetes 1.35 reaches end of life on 28 February 2027 and 1.36 on 28 June 2027, per the release history. Kubernetes 1.33 already went out of support on 28 June 2026. A cluster on containerd 1.7 today has a real deadline, not a theoretical one, because staying on a supported Kubernetes version now forces the runtime move within the next upgrade or two.

What actually breaks: the config that stops loading

Two things change in containerd 2.0, and both live in /etc/containerd/config.toml. Miss either one and the CRI plugin fails to load on restart.

First, the CRI plugin identifier moved. In containerd 1.x the CRI settings sit under io.containerd.grpc.v1.cri. In containerd 2.x the image and registry settings live under io.containerd.cri.v1.images. A config file that hard-codes the old plugin path will not apply the settings you think it does.

Second, the registry configuration format changed. The containerd project registry documentation is direct about it: "registry.mirrors and registry.configs as previously described in this document have been DEPRECATED." The replacement is config_path, which points at a directory of hosts.toml files, the same pattern Docker uses under /etc/containerd/certs.d.

Here is the shape of the change. The old, deprecated form under containerd 1.x looked like this:


            version = 2

[plugins."io.containerd.grpc.v1.cri".registry]
  [plugins."io.containerd.grpc.v1.cri".registry.mirrors]
    [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
      endpoint = ["https://registry-1.docker.io"]
          

The containerd 2.x form uses config version 3, the new plugin path, and a config_path:


            version = 3

[plugins."io.containerd.cri.v1.images".registry]
  config_path = "/etc/containerd/certs.d"
          

You then create per-registry hosts.toml files under that directory. For a Docker Hub mirror, /etc/containerd/certs.d/docker.io/hosts.toml:


            server = "https://registry-1.docker.io"

[host."https://your-mirror.internal"]
  capabilities = ["pull", "resolve"]
          

Config version 2, used by containerd 1.x, is still read by containerd 2.0 and converted automatically, so a plain node with default settings often survives the runtime bump untouched. The clusters that break are the ones with custom registry mirrors, private registry credentials, or automation that injects the old config blocks. That last category is the quiet killer: a node bootstrap script that writes a registry.mirrors block on every new node will keep producing nodes whose CRI plugin ignores the mirror, so images pull from the public registry, egress bills climb, and nothing throws an obvious error.

Credentials need special handling. The containerd docs note that registry.configs.*.auth is deprecated and has no host-file equivalent for storing unencrypted secrets. The supported path is to let Kubernetes pass credentials over CRI using imagePullSecrets on the pod or service account, rather than baking static auth into the node. Treat the runtime migration as the moment to move registry credentials out of node config and into Kubernetes secrets.

containerd 2.0 also drops two older behaviours that matter for legacy clusters: support for Docker Schema 1 images and the v1alpha2 CRI API, per Google's containerd 2 migration guide. If you still pull very old images built years ago, rebuild them before the runtime move.

How to find the nodes that are about to break

You do not have to guess which nodes are on an unsupported runtime. The Kubernetes container runtimes documentation is the reference for supported versions, and the kubelet exposes a metric for exactly this. Watch kubelet_cri_losing_support: a non-zero value flags nodes running a containerd version that is about to lose Kubernetes support. Scrape it with Prometheus across the fleet and alert on it before you touch the control plane.

A quick manual audit works for smaller clusters. To list the container runtime version reported by every node:


            kubectl get nodes -o wide
# The CONTAINER-RUNTIME column shows, for example:
# containerd://1.7.20  (needs migration)
# containerd://2.0.5   (safe)
          

For a scripted check across the fleet:


            kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.nodeInfo.containerRuntimeVersion}{"\n"}{end}'
          

Anything reporting containerd://1.x is on the clock. Sort those nodes into node pools so you can replace them in controlled batches.

The migration, step by step, for self-managed nodes

If you run your own nodes with kubeadm, cluster-api, or a custom image pipeline, the runtime move is a node-replacement exercise, not an in-place package upgrade. Rolling nodes is safer than upgrading containerd underneath a running kubelet, because it gives you a clean image and an easy rollback.

  1. Audit first. Run the containerRuntimeVersion check above and confirm which node pools are on containerd 1.x. Record the current Kubernetes minor version; the version skew policy in the Kubernetes release documentation still governs how far kubelet can trail the control plane.
  1. Rebuild the node image on containerd 2.0 or newer. Bake the new config.toml with version = 3, the io.containerd.cri.v1.images plugin path, and config_path = "/etc/containerd/certs.d". Ship your registry mirrors as hosts.toml files in the image.
  1. Move credentials to Kubernetes. Replace any node-level registry.configs.*.auth with imagePullSecrets referenced from the workloads or their service accounts.
  1. Validate on one node. Cordon and drain a single canary node, replace it with the new image, and confirm three things: the node registers, crictl pull succeeds against your private registry, and a test pod schedules and runs. crictl info should report the version 3 config.
  1. Roll the pool. Cordon, drain, and replace nodes in batches sized to your pod disruption budgets. Keep one old-image node pool alive until the new pool has taken production traffic through at least one deploy.
  1. Only then bump the control plane. With every node on containerd 2.0, upgrading Kubernetes past 1.35 no longer carries runtime risk. Do the control plane, then the node pools' Kubernetes version, one minor at a time.

The order is the point. Teams that upgrade Kubernetes first and discover the runtime problem second end up debugging image pulls on a live cluster. The real cost here is almost never the containerd package; it is the custom registry config and the bootstrap automation that has to change with it.

Managed clusters: GKE, EKS and AKS are not the same

If you run a managed service, you own less of this, but "the platform handles it" is an assumption to verify, not to trust. Each provider treats the runtime move differently, and the guardrails differ.

Managed service containerd 2.0 handling Control-plane price (production) Long-term support option
Google GKE Ships containerd 2.0 on newer node images; pauses auto-upgrades when it detects deprecated features About $0.10 per cluster per hour, with $74.40 monthly credit for one cluster Extended-support channel (paid)
Amazon EKS containerd is the only runtime on current node images $0.10 per cluster per hour, about $72 per month Extended support for older minors (paid)
Azure AKS Standard containerd only; Azure Linux 2.0 node image frozen and being retired $0.10 per hour, about $73 per month, with uptime SLA Move to Premium tier
Azure AKS Premium containerd only $0.60 per hour, about $438 per month Long-term support for Kubernetes versions included

Google GKE is the most protective: its containerd 2 migration guide explains that GKE pauses automatic upgrades for clusters where it detects use of deprecated features, so a cluster relying on Docker Schema 1 images or the old CRI API will not be silently broken by an upgrade. That is a safety net, not a fix: the cluster is stuck until you remove the deprecated dependency.

Amazon EKS publishes a version support matrix and charges $0.10 per cluster per hour for the control plane, roughly $72 per month, with a paid extended-support window for teams that need longer on an older minor.

Azure AKS is the one with a hard node-image deadline in play: Azure Linux 2.0 node images stopped receiving security updates on 30 November 2025 and are being removed, so AKS clusters on that image need to move regardless of the containerd question. AKS also makes the upgrade-fatigue tradeoff explicit in pricing. The Standard tier at about $73 per month gives the uptime SLA; the Premium tier at about $438 per month adds long-term support for Kubernetes versions, which is the escape hatch for organisations that genuinely cannot upgrade every few months.

The pricing convergence is worth noting for budgeting: all three land near $73 per month for a production-grade control plane, so the control-plane fee is rarely the deciding cost. The deciding cost is the engineering time to keep nodes current, which is exactly what the containerd move adds this year.

DRA, in-place resize, and the other changes worth planning for

The containerd cutoff is the mandatory item, but 1.34 and 1.35 shipped two graduations that change how you plan capacity, and they are worth folding into the same upgrade project.

Dynamic Resource Allocation (DRA) graduated to general availability in Kubernetes 1.34, per the Kubernetes DRA update, and is enabled by default. DRA gives the scheduler a structured way to request, allocate and share specialised hardware, GPUs, FPGAs, NPUs and custom accelerators, through a ResourceClaim rather than the old opaque device-plugin path. For any team running AI or machine-learning workloads, DRA is the feature that lets multiple pods share a GPU and lets the scheduler track consumable device capacity. It is directly relevant to GPU cost, which remains a top cloud-spend concern for teams running accelerators. If you are upgrading anyway, plan a review of your GPU scheduling against DRA.

In-place Pod Resize graduated to stable in Kubernetes 1.35, per the Kubernetes 1.35 release notes and reporting from InfoQ. You can now change a running pod's CPU and memory requests and limits without recreating the pod, and often without restarting the container. For stateful services and long-running batch jobs, that removes a class of disruptive restarts from vertical scaling. It is not a runtime dependency, but it changes day-two operations enough to test during the upgrade.

Kubernetes 1.35 shipped 60 enhancements in total, including 17 that graduated to stable, so read the deprecations section of the release notes for your specific add-ons before you plan the window. Ingress controllers, kube-proxy modes, and older APIs all have their own timelines that a runtime-focused checklist can miss.

India-specific considerations

For teams in India running regulated workloads, the upgrade discipline is also a compliance point. The Digital Personal Data Protection Act (DPDP), 2023 expects reasonable security safeguards, and running an unsupported Kubernetes minor or an end-of-life container runtime is hard to defend as reasonable once a fix is available and documented. Staying inside the three-release support window is part of a defensible security posture, not only an operations preference.

The cost math reads a little differently in rupee terms. A production control plane at about $0.10 per cluster per hour works out to roughly ₹6,000 to ₹6,500 per cluster per month at mid-2026 exchange rates, or about ₹75,000 per cluster per year, before any node or GPU cost. For an organisation running dozens of clusters across dev, staging and production, the AKS Premium long-term-support tier at about $438 per month per cluster is a meaningful line item, so the cheaper answer is usually to invest in the automation that keeps nodes current rather than to pay for a longer support tail. Teams weighing that tradeoff can compare it against the broader picture in our guide to cloud FinOps for Indian teams and the reasons GPU spend is now the top FinOps concern.

A pragmatic upgrade posture

The Kubernetes project and the managed platforms both recommend staying within the supported window rather than chasing the newest release on day one. Running N-1 or N-2, one or two minors behind the latest, gives the ecosystem time to catch up while keeping you inside the roughly one year of patch support each minor receives. With the latest minor being 1.36 as of July 2026, an N-1 posture puts you on 1.35, which is precisely the release where the containerd 1.x support ends. That is the trap: an N-1 team feels current and is one upgrade away from a broken runtime.

The move that keeps you safe is to decouple the runtime migration from the Kubernetes version bump. Get every node onto containerd 2.0 while you are still on 1.35, verify it under production load, and only then continue up the release train. Handle the runtime as its own project, with its own canary and its own rollback, and the Kubernetes upgrades that follow become boring again, which is what you want them to be. For clusters running AI platforms where GPU scheduling and DRA are in play, a managed approach can take the runtime and version treadmill off your team; see how we run managed Kubernetes AI platforms. Security-focused teams should also review node and workload hardening alongside the upgrade, as covered in our note on Kubernetes 1.35 pod certificates and constrained impersonation.

FAQ

How eCorpIT can help

eCorpIT runs Kubernetes upgrades and container-runtime migrations for teams that would rather not debug image pulls on a live cluster. Our senior engineering teams audit node pools for containerd 1.x, rebuild node images on containerd 2.0 with the new registry configuration, move credentials into Kubernetes secrets, and roll pools within your disruption budgets, then keep clusters inside the supported window with tested upgrade automation. If you are planning a move past Kubernetes 1.35 or running GPU-heavy AI platforms, contact us to scope the migration.

References

  1. Kubernetes release history and end-of-life dates — Kubernetes project.
  1. Kubernetes v1.35 sneak peek — Kubernetes blog.
  1. Kubernetes v1.35: Timbernetes release announcement — Kubernetes blog.
  1. Kubernetes release notes — Kubernetes project.
  1. Container runtimes documentation — Kubernetes project.
  1. Version skew policy — Kubernetes project.
  1. Configure image registry (CRI) — containerd project.
  1. Migrate nodes to containerd 2 — Google Kubernetes Engine documentation.
  1. Kubernetes v1.34: DRA has graduated to GA — Kubernetes blog.
  1. Kubernetes 1.35 released with in-place pod resize — InfoQ.
  1. Amazon EKS pricing — Amazon Web Services.
  1. Google Kubernetes Engine pricing — Google Cloud.
  1. Supported Kubernetes versions in AKS — Microsoft Learn.

_Last updated: 19 July 2026._

Frequently asked

Quick answers.

01 Is Kubernetes 1.35 really the last release to support containerd 1.x?
Yes. Per the Kubernetes v1.35 sneak peek and release notes, containerd 1.6 and 1.7 were deprecated in 1.34, get their final support in 1.35, and are slated for removal in the next minor. Once you upgrade past 1.35, containerd 2.0 is the effective minimum runtime version.
02 Do I have to change my containerd config, or does it upgrade automatically?
It depends. containerd 2.0 still reads the old config version 2 and converts it. Plain nodes with default settings often survive untouched. Clusters with custom registry mirrors, private-registry credentials, or bootstrap scripts that inject registry.mirrors blocks must move to the new config_path format under /etc/containerd/certs.d.
03 How do I find nodes running an unsupported containerd version?
Watch the kubelet metric kubelet_cri_losing_support, which flags nodes on a soon-unsupported runtime. For a manual check, run kubectl get nodes -o wide and read the container-runtime column, or script the containerRuntimeVersion field. Any node reporting containerd://1.x needs migration before you upgrade past 1.35.
04 What exactly changed in the containerd 2.0 registry configuration?
The CRI plugin path moved from io.containerd.grpc.v1.cri to io.containerd.cri.v1.images, and config version 3 replaced version 2. The registry.mirrors and registry.configs blocks are deprecated in favour of config_path, which points at per-registry hosts.toml files, following the same directory pattern Docker uses.
05 Do managed services like GKE, EKS and AKS handle this for me?
Partly. All three ship containerd as the only runtime on current node images. GKE pauses automatic upgrades when it detects deprecated features. AKS is retiring Azure Linux 2.0 node images. You still own removing deprecated dependencies, such as Docker Schema 1 images, and validating your own registry configuration.
06 What is Dynamic Resource Allocation and why does it matter for this upgrade?
Dynamic Resource Allocation (DRA) graduated to general availability in Kubernetes 1.34 and is enabled by default. It gives the scheduler a structured way to request and share GPUs, FPGAs, NPUs and custom accelerators through a ResourceClaim. For AI workloads it enables GPU sharing across pods, so it is worth reviewing GPU scheduling during the same upgrade project.
07 How much does a Kubernetes control plane cost in 2026?
A production control plane runs about $0.10 per cluster per hour on EKS, GKE and AKS Standard, roughly $73 per month, near ₹6,000 to ₹6,500 in rupee terms. AKS Premium costs about $0.60 per hour, near $438 per month, and adds long-term support for Kubernetes versions for teams that cannot upgrade frequently.
08 What upgrade posture should we run: latest, N-1, or N-2?
Staying one or two minors behind the latest, N-1 or N-2, keeps you inside the roughly one year of patch support each minor receives. The catch in 2026 is that N-1 puts you on 1.35, the last containerd 1.x release. Move nodes to containerd 2.0 while on 1.35, then continue upgrading.

About the author

Manu Shukla

Founder & Director

Founder of eCorpIT. Hands-on engineer leading senior-only delivery for AI apps, custom software, and cloud systems for global clients.

Subscribe

One engineering note a week. No fluff, no spam.

Senior-architect playbooks on AI agents, mobile apps, cloud, security, data, and marketing — delivered every Wednesday.

Past the reading

Read enough. Let's build something.

A senior architect responds in 24 working hours with scope, indicative cost, and a timeline. NDA before any technical conversation.