Jacar mascot — reading along A laptop whose eyes follow your cursor while you read.
Arquitectura Tecnología

containerd 2.0 in production: real migrations

containerd 2.0 in production: real migrations

Actualizado: 2026-05-03

containerd 2.0 shipped in November 2024 and we’ve had six months to watch how it behaves in real deployments. 1.7 still gets support, but the 1.6 branch reached end of life in March 2025, forcing many teams to plan the jump. Enough reports have surfaced since to allow an honest read: what breaks, what improves, and when planning the migration pays off.

Key takeaways

  • The main driver to jump is that 1.6 no longer has support, not that 2.0 brings indispensable features.
  • CRI v1alpha2 is removed: kubelet must be on 1.26+ before migrating Kubernetes clusters.
  • The configuration file format changes: version = 3 instead of version = 2.
  • OCI Schema 1 image support is removed: images built before 2017 may not run.
  • Docker Swarm migration is gentler than Kubernetes because Swarm doesn’t depend on CRI.
  • Key metrics during migration: active container count, failed-pull ratio, task API latency, and shim errors.

What 2.0 brings that justifies the jump

Beyond internal cleanup, four things have concrete operational value:

  • Native sandbox support. Kata Containers and Firecracker can integrate as runtimes via the sandbox API without external shims. For teams evaluating reinforced isolation this reduces the number of moving parts. Connects directly to what we described in Firecracker: microVMs for multi-tenant services.
  • CRI v1 stable and v1alpha2 removed. Kubernetes 1.26 and later use CRI v1 by default. containerd 2.0 removes the v1alpha2 implementation, simplifying code but breaking compatibility with kubelet older than 1.26.
  • Runtime shim improvements. The runc shim was refactored and uses less memory per container. On a host with hundreds of containers the savings are noticeable: tens of megabytes less total overhead.
  • NRI as stable plugin API. The Node Resource Interface, previously experimental, is now the official interface for integrating custom CNI, device plugins and security agents.

What breaks on migration

It’s not a drop-in upgrade for most cases. There are at least five places where you need to touch config or scripts:

  1. Config file format. The version = 2 clause is no longer recognised; declare version = 3 in /etc/containerd/config.toml. Ansible or Puppet scripts injecting configuration must adjust the template. containerd 2.0 converts version 2 automatically but emits a warning, and 2.1 plans to drop automatic conversion.
  2. Deregistered plugins. Several plugins like io.containerd.grpc.v1.introspection changed namespace or name. If external integrations do plugin introspection, review them.
  3. OCI Schema 1 image support removed. Old images built before 2017 may be Schema 1 and containerd 2.0 won’t run them. Most modern registries convert on pull, but images in old private registries need repackaging.
  4. ctr behaviour on namespace-shared containers. Some commands that previously worked silently across namespaces now require the explicit namespace. Scripts using ctr without --namespace fail with clear errors, but if they run in cron or CI you need to update them.
  5. CNI 0.x deprecation. containerd 2.0 requires CNI plugins 1.0 or higher. If the cluster has Calico 3.17 or pre-0.20 Flannel, upgrade them.

The Docker Swarm case

For those still running Swarm, migration is gentler than on Kubernetes because Swarm doesn’t depend on CRI. What matters is that Docker Engine accepts containerd 2.0 as the underlying runtime.

Docker Engine 27.x, shipped through 2024, already supports containerd 2.0 as backend. For installations with standalone containerd (system containerd used by Docker Engine via socket, which is how well-configured Debian servers work), the order was:

  1. Update containerd from 1.7 to 2.0.
  2. Restart containerd.service.
  3. Verify ctr version and that existing containers kept running.
  4. Bump Docker Engine to 27.x and restart docker.service.

No container drops, but two images had to be rebuilt because they were Schema 1.

Observability during migration

Something I learned the hard way in a previous migration: default containerd doesn’t emit Prometheus metrics without configuration. Before migrating, ensure metrics.address = "0.0.0.0:1338" is set in config and the exporter is scraped. Without that, the only signal something’s wrong is containers dying.

Key metrics to watch during and after migration:

  • Active container count.
  • Failed-pull ratio.
  • Task API latency.
  • Shim errors.

With those four signals covered, a bad migration shows up in minutes instead of hours. The same observe-before-acting principle applies to Kubernetes 1.32 operations management.

My read

containerd 2.0 is a mandatory but not urgent migration for most teams. The main driver is that 1.6 no longer has support. If the cluster is on 1.7 with no regulatory pressure, waiting for 2.1 (planned for late 2025) can avoid some sharp edges I still see.

What I find most positive about the release is the cleanup. Removing CRI v1alpha2 and OCI Schema 1 are decisions the community postponed for years and that will pay maintainability dividends.

My practical recommendation:

  • If you run Kubernetes: check kubelet on every node before touching anything, upgrade Calico or your CNI to 1.0, and plan a maintenance window with rollback.
  • If you run Swarm: simpler, but watch old images.
  • If you run plain docker without Swarm or Kubernetes: migration is nearly transparent as long as you update Docker Engine in the same cycle.
Was this useful?
[Total: 12 · Average: 4.1]

Written by

CEO - Jacar Systems

Passionate about technology, cloud infrastructure and artificial intelligence. Writes about DevOps, AI, platforms and software from Madrid.