Why Choose containerd Over Docker? A Deep Dive into Kubernetes Runtime
This article explains how Docker relies on Linux kernel features to isolate processes, introduces containerd as an industrial‑grade container runtime, compares their logging, configuration, CNI handling, and command interfaces, and provides practical tables and examples for migrating from Docker to containerd in Kubernetes environments.
Prospect Summary
Docker uses Linux kernel features such as cgroups and namespaces to isolate processes, enabling independent execution of multiple processes and applications while maintaining system security.
To avoid a Docker monopoly, the original implementation was split into several standardized modules that can be replaced by other implementations.
Docker consists of docker-client, dockerd, containerd, docker-shim, and runc; containerd is one of Docker's core components, and most container management operations are performed through containerd.
Containerd is an industrial‑grade standard container runtime that emphasizes simplicity, robustness, and portability. It manages the full container lifecycle on the host, including image transfer and storage, container execution and management, as well as storage and networking.
Manage container lifecycle (create to destroy)
Pull/push container images
Storage management (images and container data)
Invoke runC to run containers (interact with other runtimes)
Manage container network interfaces and networking
k8s Perspective
From the Kubernetes viewpoint, you can choose containerd or Docker as the runtime; containerd has a shorter call chain, fewer components, greater stability, and lower node resource consumption.
containerd vs Docker Call Relationship
Configuration Parameter Differences
Log configuration
Comparison Item
docker
containerd
Storage Path
docker logs are stored under /var/lib/docker/containers/CONTAINERID; kubelet creates symlinks in /var/log/pods and /var/log/containers pointing to that directory.
containerd logs are written by kubelet to /var/log/pods/$CONTAINER_NAME and symlinked from /var/log/containers.
Configuration Parameters
"log-driver": "json-file", "log-opts": {"max-size": "100m", "max-file": "5"}
--container-log-max-files=5 --container-log-max-size="100Mi" or in KubeletConfiguration: "containerLogMaxSize": "100Mi", "containerLogMaxFiles": 5
Save container logs to data disk
Mount data disk to "data-root" (default /var/lib/docker).
Create a symlink /var/log/pods to a directory on the data‑disk mount point; TKE can auto‑create this symlink.
Stream Server
kubectl exec/logs need a stream channel between apiserver and the runtime.
Docker API provides a stream service; docker‑shim uses it.
containerd requires separate stream service configuration.
[plugins.cri]
stream_server_address = "127.0.0.1"
stream_server_port = "0"
enable_tls_streaming = false
Before Kubernetes 1.11, kubelet only performed a redirect; after 1.11 it introduced a stream proxy, allowing the containerd stream server to listen only on a local address.
CNI Networking
Comparison Item
docker
containerd
Who calls CNI
docker‑shim inside kubelet
cri‑plugin built into containerd (since v1.1)
How to configure CNI
kubelet parameters --cni-bin-dir and --cni-conf-dir
containerd toml: plugins.cri.cni bin_dir = "/opt/cni/bin" conf_dir = "/etc/cni/net.d"
Command Comparison
containerd does not support the Docker API or CLI, but crictl provides similar functionality.
Image Function
docker
containerd
List local images
docker images
crictl images
Pull image
docker pull
crictl pull
Push image
docker push
None
Delete local image
docker rmi
crictl rmi
Inspect image
docker inspect
crictl inspecti
Container Function
docker
containerd
List containers
docker ps
crictl ps
Create container
docker create
crictl create
Start container
docker start
crictl start
Stop container
docker stop
crictl stop
Remove container
docker rm
crictl rm
Inspect container
docker inspect
crictl inspect
Attach
docker attach
crictl attach
Exec
docker exec
crictl exec
Logs
docker logs
crictl logs
Stats
docker stats
crictl stats
POD Function
docker
containerd
List PODs
None
crictl pods
Inspect POD
None
crictl inspectp
Run POD
None
crictl runp
Stop POD
None
crictl stopp
Further Reading
Below are common crictl commands that can fully replace Docker commands, as shown in the table.
crictl covers most container lifecycle management, but image management still relies on ctr; for example: ctr -n k8s.io images list Note that containerd uses namespaces (k8s.io, moby, default); many crictl operations require the -n parameter.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Raymond Ops
Linux ops automation, cloud-native, Kubernetes, SRE, DevOps, Python, Golang and related tech discussions.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
