The Evolution of Container Runtimes
At the dawn of the container era, Docker reigned supreme thanks to its intuitive interface. Even though alternative tools like Rocket existed, Kubernetes was initially designed to orchestrate Docker-based containers, creating a strong coupling between Docker and Kubernetes. However, as Kubernetes expanded its ecosystem, other container runtimes sought integration. Kubernetes addressed this need by introducing the Container Runtime Interface (CRI). The CRI standardizes container runtimes by ensuring compliance with the Open Container Initiative (OCI) standards—the image specification (for building images) and the runtime specification (for container execution). This standardization paved the way for runtimes like Rocket and others to be supported by Kubernetes. Since Docker was developed before CRI was established, it wasn’t built with CRI compatibility in mind. To allow Docker to function with Kubernetes, a temporary solution known as the Docker Shim was implemented. Over time, native CRI-compatible runtimes such as ContainerD emerged, shifting Docker’s primary role within the Kubernetes architecture. ContainerD, a CRI-compatible runtime, integrates directly with Kubernetes—eliminating the need for the Docker Shim. Originally bundled with Docker, ContainerD has evolved into a standalone project under the Cloud Native Computing Foundation. This decoupling means you can install and use ContainerD without needing the entire Docker ecosystem if your goal is solely container runtime functionality. The diagram below illustrates the relationship between Docker, Kubernetes, and alternative container runtimes (like rkt), highlighting components such as containerd, the Docker Shim, and the Container Runtime Interface (CRI).
- Docker CLI and API
- Image build tools
- Support for volumes, authentication, and security
- The container runtime (runc) managed by containerd
Diving Deeper into ContainerD
ContainerD began as an internal component of Docker but is now maintained as an independent project. If you do not require Docker’s additional features, you can install ContainerD on its own. Traditionally, Docker users ran containers using commands likedocker run, but ContainerD introduces different CLI tools.
Note: Installation Example
To install ContainerD, execute the following command:

Using CTR
For example, to pull and run a Redis image using CTR, use the following commands:NerdCTL: A Docker-like CLI for ContainerD
NerdCTL offers a CLI experience similar to Docker’s while providing additional features unique to ContainerD. Key features include:- Encrypted container images
- Lazy pulling of images
- Peer-to-peer image distribution
- Image signing and verification in Kubernetes namespaces
CRI Tools: A Kubernetes Perspective
Another significant CLI utility is CRI CTL (crictl), designed to interact with any CRI-compatible container runtime, including ContainerD, Rocket, and others. Unlike CTR and NerdCTL—which are developed by the ContainerD community—crictl is maintained by the Kubernetes community and is primarily intended for debugging and inspection.
- Pulling container images
- Listing images and containers
- Inspecting logs and executing commands inside containers (using options like -i and -t)
- Listing pods (a functionality not provided by Docker commands)


Changes in Kubernetes Runtime Endpoints
Earlier versions of Kubernetes had the kubelet connect to container runtime endpoints in the following default order:cri-dockerd.sock and the kubelet default endpoints were updated. Users are now encouraged to manually set their runtime endpoint using:
Summary
- The CTR tool, bundled with ContainerD, is primarily used for debugging.
- NerdCTL offers a Docker-like CLI for general-purpose container operations and advanced ContainerD features.
- Crictl, maintained by the Kubernetes community, is designed for interacting with all CRI-compatible container runtimes and is mainly used for debugging and inspection.
