docker vs. containerd
Content
Docker vs. Containerd: The Ultimate Guide to Demystifying Containers
If you’re working with Kubernetes, you’ve probably heard the names Docker and Containerd. And if you’re like most people, you may have wondered: what’s the difference? Are they the same thing? Why did Kubernetes “drop” Docker?
This article will clarify all of that and give you a clear understanding of each piece of technology.
1. Docker: The Complete Platform
When we think of Docker, we think of the complete platform. It’s an all-in-one solution that popularized containerization. Docker includes everything a developer needs:
- The CLI (Command Line Interface): The docker command-line tool we use to build, run, and manage containers.
- The Docker Engine (Daemon): The background service that manages images, volumes, networks, and the container lifecycle.
- The Container Runtime: The low-level engine that actually runs the container.
You can think of Docker as a complete car.
. It’s ready to go as soon as you get in, with its engine, body, and all its features.
2. Containerd: The Low-Level Engine
Unlike Docker, Containerd is not a complete solution. It is a low-level container runtime. Its job is simple and precise: to manage the complete lifecycle of containers on an operating system. .
Containerd is responsible for:
- Managing images (downloading, storing, etc.).
- Creating and destroying containers.
- Managing network connectivity for containers.
To use the car analogy again, Containerd is the car’s engine. It’s an essential building block, but it doesn’t allow you to drive. It’s designed to be used by other systems, like Docker or Kubernetes.
3. The CRI (Container Runtime Interface)
The CRI (Container Runtime Interface) is a key concept for Kubernetes. It is not a tool or a piece of software, but a standard API. .
Kubernetes is designed to be modular. To avoid being dependent on a single container runtime (like Docker), the Kubelet component needs a standard interface to interact with any runtime. The CRI is that interface.
Containerd was specifically designed to be CRI compliant. This is why Kubernetes was able to integrate directly with Containerd, making it more efficient and lightweight. This is also why many modern clusters no longer have Docker installed.
4. crictl: The Debugging Tool
If docker is the CLI for the Docker engine, then crictl is the CLI for the CRI. . It’s a troubleshooting tool that allows you to interact directly with the container runtime on a node, without going through kubectl or other high-level tools.
crictl is essential for cluster administrators because it allows them to view the status of containers and images independently.
A bridge to the runtime: the endpoint
To work, crictl needs to connect to the container runtime via an endpoint. This endpoint is usually a local UNIX socket. The path to this socket depends on the runtime you are using:
- For Containerd: unix:///run/containerd/containerd.sock
- For CRI-O: unix:///run/crio/crio.sock
- For Docker (via cri-dockerd): unix:///var/run/cri-dockerd.sock
You can specify the endpoint directly in the command or set it as an environment variable to be used by default.
# Specify the endpoint for a single command
sudo crictl --runtime-endpoint unix:///run/containerd/containerd.sock ps
# Set the endpoint for all subsequent commands
export CONTAINER_RUNTIME_ENDPOINT=unix:///run/containerd/containerd.sock
crictl command examples
# List all pods managed by the CRI
sudo crictl pods
# List all running containers
sudo crictl ps
# List all container images on the node
sudo crictl images
5. Nerdctl: The Docker-like CLI
nerdctl is a CLI tool developed by the Containerd project. Its mission is to provide a user interface that mimics the Docker syntax (docker run, docker pull, etc.), but which interfaces directly with the Containerd runtime. . This allows users to easily switch from Docker to a Containerd-based environment without having to learn new commands like crictl, which is more focused on debugging.
To return to our analogy, nerdctl is like an adapter for your car’s steering wheel. It allows you to use your familiar steering wheel (Docker commands) to control the new engine (Containerd).
nerdctl command examples
One of the main advantages of nerdctl is its familiarity. The commands are nearly identical to those of Docker.
- docker run becomes nerdctl run
- docker pull becomes nerdctl pull
- docker ps becomes nerdctl ps
- docker images becomes nerdctl images
nerdctl is ideal for development or testing environments where you want to use familiar Docker commands to build and manage containers while benefiting from Containerd’s lightweight and performance.
In Summary
Feature | Docker | Containerd | CRI | crictl | Nerdctl |
---|---|---|---|---|---|
Type | Complete Platform | Low-level Runtime | Interface (Standard) | CLI Tool | CLI Tool |
Purpose | A-to-Z Management | Container Execution | Runtime Abstraction | Runtime Debugging | Familiar UX (Docker-style) |
Analogy | The Complete Car | The Car’s Engine | The Standard Steering Wheel | The Mechanic | The Steering Wheel Adapter |
Used by K8s | Indirectly | Directly and Standard | Standard Interface | Runtime Debugging | For Developers |
In conclusion, the relationship is simple: Kubernetes uses the standard CRI interface to communicate with Containerd (the engine), which is responsible for running the containers. Docker, while popular, is a heavier platform that uses Containerd at its core. If something doesn’t work, crictl is the tool to look directly under the hood, and nerdctl is the tool for developers who prefer a familiar interface.