It’s time to embark on the dockerless journey
Background Introduction
Docker, as one of the earliest and most widely used container runtimes, has become deeply ingrained in user workflows due to its intuitive interface and extensive features. In Kubernetes’ early days, it used the built-in dockershim component to integrate with Docker. However, as container technologies evolved, Kubernetes introduced the Container Runtime Interface (CRI) to standardize and expand container runtime support. This innovation enhanced Kubernetes’ compatibility with multiple container runtimes, offering users greater flexibility and choice.
The CRI enables Kubernetes system components to interact seamlessly with various container runtimes. This shift expanded Kubernetes’ scope beyond Docker and reduced its dependency on Docker and dockershim. Today, Kubernetes users can confidently adopt other robust runtimes like containerd and CRI-O, simplifying the Kubernetes architecture and improving operational efficiency.
Starting with Kubernetes version 1.24, official support for Docker (via dockershim) was removed. Similarly, Amazon EKS declared containerd as its sole supported runtime. Following this direction, our cluster’s container runtime was transitioned to containerd, replacing Docker CLI with nerdctl.
To better understand this shift, it’s important to introduce key container ecosystem components such as libcontainer
, runc
, containerd
, CRI
, and OCI
. These components play critical roles in creating an efficient and flexible container runtime environment. By delving into these concepts, we can enhance operational expertise and lay a solid foundation for future application deployment and maintenance. For detailed information on nerdctl, please refer to the corresponding section.
Technical Background
OCI Standards (Open Container Initiative)
The Open Container Initiative (OCI), spearheaded by organizations like Docker and CoreOS (later acquired by Red Hat), establishes unified industry standards for container formats and runtimes. The OCI defines two primary specifications:
- Image Specification (image-spec): Specifies the format and structure of container images.
- Runtime Specification (runtime-spec): Governs the execution of container images. The most widely used low-level runtime today is runC, which includes
libcontainer
and supports operations like namespace and cgroup calls.
Main High-Level Container Runtimes
High-level container runtimes offer advanced functionality such as image management, unpacking, and API integration. The three most popular ones are:
- containerd: A CNCF project originally contributed by Docker.
- Podman: A Red Hat project, fully supported in RHEL 8.
- CRI-O: Another CNCF project designed to integrate seamlessly with Kubernetes.
Container Relationships
The diagram below illustrates the relationships within the container ecosystem, highlighting the interaction between various components.
Using Docker based on containerd as a container runtime can be categorized as a “high-high-level” runtime.
Containerd
Launched as an independent project in early 2016 and donated to CNCF in March 2017, containerd is a lightweight, robust, and portable container runtime that supports Linux and Windows. It manages complete container lifecycles, including image management, container execution, and networking (via CNI plugins).
Key Components of Containerd
- Runtime: Manages container lifecycle tasks, including creation, execution, and monitoring.
- Storage: Provides image storage and management capabilities.
- gRPC: Facilitates communication with upper-layer applications, offering container management APIs.
- Metrics: Offers performance and resource utilization metrics, primarily based on cgroups.
- Metadata: Stores essential information about images and containers.
- Tasks: Organizes containers as tasks, encompassing runtime states and process data.
- Events: Emits state change notifications to help applications monitor and react to container events.
Comparison Between Docker and Containerd
Feature | Containerd | Docker |
---|---|---|
Architecture | Focused on container lifecycle management. | Comprehensive container platform. |
Image Management | Basic image transfer and storage features. | Advanced image building and versioning. |
Ecosystem | Modular, integrates into larger ecosystems. | Integrated tools and services. |
Security | Optimized for core functionality. | Enhanced with image signing and keys. |
Extensibility | Lightweight, supports diverse scenarios. | Plugin mechanism for customization. |
Deployment | Requires tools like Kubernetes. | All-in-one solution for containers. |
Community | Backed by CNCF and cloud-native ecosystems. | Docker-led, vibrant developer base. |
CRI (Container Runtime Interface)
The CRI, introduced by Kubernetes, standardizes interactions between Kubernetes and container runtimes. Initially, Kubernetes relied on Docker’s API but later adopted the CRI to reduce dependencies and support emerging runtimes.
CRI defines two gRPC services:
- ImageService: Manages operations like pulling, listing, and deleting container images.
- RuntimeService: Handles Pod and container lifecycle management.
Evolution of CRI and Dockershim
In early Kubernetes versions, dockershim acted as an adapter, enabling Docker to conform to CRI. Over time, this approach proved suboptimal due to the complexity of Docker’s architecture. By Kubernetes 1.20, dockershim was deprecated, and by 1.24, it was fully removed.
Switching to containerd offers significant efficiency improvements by simplifying the runtime stack. Kubernetes now interacts directly with CRI-compatible runtimes like containerd, without relying on dockershim. This evolution aligns with Kubernetes’ focus on modularity and scalability.
Command Line Overview
Docker, ctr
, nerdctl
, and crictl
are container management tools, each designed for specific purposes and use cases. Here’s a comparison:
Docker
- Overview: Docker is a popular container management tool providing a comprehensive ecosystem for building, running, and managing containers.
- Features: Supports image building, distribution (integrated with Docker Hub), and container lifecycle management (start, stop, delete, etc.).
- Interface: Offers a powerful and user-friendly CLI and API, making it easy for developers and operators to adopt.
- Key Characteristics:
- Rich ecosystem (e.g., Docker Compose).
- Supports advanced orchestration (e.g., Swarm).
- Includes an additional daemon (
dockerd
) to collaborate with container runtimes.
ctr
- Overview:
ctr
is the native CLI provided bycontainerd
for direct interaction with it. - Features: Enables basic operations like pulling images, running containers, and managing image storage but is simplified for lower-level operations and debugging.
- Interface: Unlike Docker,
ctr
targetscontainerd
users without offering advanced APIs or ecosystem support. - Key Characteristics:
- Suitable for developers and system integrators needing direct access to
containerd
. - Lacks advanced features like image building (focused solely on runtime management).
- Suitable for developers and system integrators needing direct access to
nerdctl
- Overview:
nerdctl
is a CLI tool based oncontainerd
that supports Docker-style commands. - Features: Provides a Docker-like user experience for running containers, building images, and supporting CNI plugins and volumes.
- Interface: Closely mirrors Docker CLI, making migration from Docker to
nerdctl
straightforward. - Key Characteristics:
- Operates without the Docker daemon, relying solely on
containerd
. - Integrates well with Kubernetes (when using
containerd
as the runtime) and supports Docker Compose-like functionality.
- Operates without the Docker daemon, relying solely on
crictl
- Overview:
crictl
is a CLI tool for the Container Runtime Interface (CRI), designed specifically for Kubernetes container management. - Features: Primarily interacts with CRI-compatible runtimes (e.g.,
containerd
andCRI-O
) for managing Pods, images, and containers. - Interface: Focuses on Kubernetes cluster debugging and management, with commands tailored to Kubernetes scenarios.
- Key Characteristics:
- Highly integrated with Kubernetes, often used to debug or manage Pod and container states.
- Cannot build images, focusing exclusively on container and Pod lifecycle management.
Horizontal Comparison for Specific Use Cases
1. Image Management
Feature | Docker CLI | ctr | crictl | nerdctl |
---|---|---|---|---|
List local images | docker images |
ctr i ls |
crictl images |
nerdctl images |
Pull image | docker pull |
ctr i pull |
crictl pull |
nerdctl pull |
Push image | docker push |
ctr i push |
N/A | nerdctl push |
Remove local image | docker rmi |
ctr i rm |
crictl rmi |
nerdctl rmi |
View image details | docker inspect |
N/A | crictl inspecti |
nerdctl inspect |
Tag image | docker tag |
ctr i tag |
N/A | nerdctl tag |
Export image | docker export |
ctr i export |
N/A | nerdctl save |
Import image | docker import |
ctr i import |
N/A | nerdctl load |
Build image | docker build |
N/A | N/A | nerdctl build |
2. Container Management
Feature | Docker CLI | ctr | crictl | nerdctl |
---|---|---|---|---|
List containers | docker ps |
ctr c ls |
crictl ps |
nerdctl ps |
Create container | docker create |
ctr c create |
crictl create |
nerdctl create |
Start container | docker start |
ctr t start |
crictl start |
nerdctl start |
Stop container | docker stop |
N/A | crictl stop |
nerdctl stop |
Remove container | docker rm |
ctr c rm |
crictl rm |
nerdctl rm |
Inspect container | docker inspect |
ctr c info |
crictl inspect |
nerdctl inspect |
Attach container | docker attach |
ctr t attach |
crictl attach |
nerdctl attach |
Execute in container | docker exec |
ctr t exec |
crictl exec |
nerdctl exec |
View logs | docker logs |
N/A | crictl logs |
nerdctl logs |
Monitor stats | docker stats |
ctr t metrics |
crictl stats |
nerdctl stats |
3. Pod Management
Feature | Docker CLI | ctr | crictl | nerdctl |
---|---|---|---|---|
List Pods | N/A | N/A | crictl pods |
N/A |
Inspect Pods | N/A | N/A | crictl inspectp |
N/A |
Run Pod | N/A | N/A | crictl runp |
N/A |
Stop Pod | N/A | N/A | crictl stopp |
N/A |
Remove Pod | N/A | N/A | crictl rmp |
N/A |
Summary
- Docker: User-friendly and feature-rich, ideal for standalone container management and development environments.
- ctr: Lightweight, low-level tool for direct interaction with
containerd
, mainly for debugging and backend management. - nerdctl: Docker CLI-compatible, great for users wanting Docker-like commands while directly utilizing
containerd
. - crictl: A Kubernetes-focused tool for managing Pods and containers via CRI; not suitable for general development.
nerdctl
is a lightweight alternative to Docker based on containerd
, while crictl
specializes in Kubernetes CRI-based Pod management.
Guide to Using Containerd
nerdctl is a CLI tool compatible with the Docker CLI style, and it directly supports Docker Compose syntax. This significantly enhances efficiency when using containerd for local development, testing, or single-node container deployment.
1. Installation
You can download the appropriate package from the GitHub Release page and extract it to a directory in your PATH
:
1 | # If containerd is not installed, use the nerdctl-full-<VERSION>-linux-amd64.tar.gz package. |
Sample output:
1 | WARN[0000] unable to determine buildctl version: exec: "buildctl": executable file not found in $PATH |
After installation, you can start exploring the nerdctl
CLI.
2. Command Overview
Container Management
Run
The nerdctl run
command works similarly to docker run
. For example:
1 | ➜ ~ nerdctl run -d -p 80:80 --name=nginx --restart=always nginx:alpine |
Available options are consistent with Docker, such as -i
, -t
, --cpus
, and --memory
. Use nerdctl run --help
for more options.
Exec
Execute commands within a container:
1 | ➜ ~ nerdctl exec -it <container_id> date |
List Containers (ps)
List all containers (active containers by default):
1 | ➜ ~ nerdctl ps |
For Kubernetes containers, use the -n k8s.io
namespace flag:
1 | ➜ ~ nerdctl -n k8s.io ps |
Inspect
Display detailed container information:
1 | ➜ ~ nerdctl -n k8s.io inspect <container_id> |
Logs
Fetch container logs:
1 | ➜ ~ nerdctl -n k8s.io logs <container_id> |
Supports options like -f
, -t
, -n
, --since
, and --until
.
Stop and Remove
Stop and delete containers:
1 | ➜ ~ nerdctl -n k8s.io stop <container_id> |
Use -f
or --force
for forced removal.
Image Management
List Images
View available images:
1 | ➜ ~ nerdctl -n k8s.io images |
Pull Images
Pull an image from a registry:
1 | ➜ ~ nerdctl -n k8s.io pull <image_name>:<tag> |
Other Commandsnerdctl
supports other image-related commands like build
, tag
, push
, and inspect
. Use nerdctl image --help
for a complete list.
This guide highlights key nerdctl
commands, demonstrating its compatibility with Docker-like workflows while leveraging containerd’s efficiency.
CRICTL Usage Guide
crictl
traces its roots to the Container Runtime Interface (CRI) introduced in Kubernetes version 1.5. CRI standardizes the interface between Kubernetes and container runtimes, enabling Kubernetes to interact seamlessly with various runtimes like Docker, containerd, and CRI-O.
As Kubernetes evolved, the demand for more features and better performance from container runtimes grew. CRI addressed these needs by providing a standardized interface for runtime implementation, simplifying the development of custom runtimes.
In this context, crictl
was developed as a command-line tool to interact with CRI-compliant container runtimes. It facilitates managing containers and images, querying container states and metadata, and viewing logs. By streamlining runtime management and debugging, crictl
promotes CRI adoption.
Below are the primary uses and features of crictl
:
- Container Management: Start, stop, delete, and query container states.
- Image Management: Pull, push, delete, and inspect container images.
- Log Viewing: View stdout and stderr logs of containers.
- Container Information: Query detailed container information such as ID, name, status, and IP.
- Metadata Management: Annotate and tag containers.
crictl
is a robust tool for managing containers and images within a runtime, debugging containerized applications, and integrating with orchestration systems like Kubernetes.
1. Installation
First, install crictl
by downloading the appropriate binary from the cri-tools release page. Extract the binary to a PATH location:
1 | ➜ ~ VERSION="v1.22.0" |
If the version command runs successfully, the crictl
tool is installed.
2. Command Overview
After installation, configure the default settings in /etc/crictl.yaml
by specifying the runtime and image endpoint addresses:
1 | runtime-endpoint: unix:///var/run/containerd/containerd.sock |
Once configured, you can start using crictl
.
Pod Management
Use the crictl pods
command to list the running pods on a node:
1 | ➜ ~ crictl pods |
Filter pods by name or label:
1 | ➜ ~ crictl pods --label app=node-exporter |
Image Management
List all images with crictl images
:
1 | ➜ ~ crictl images |
View detailed image information with the -v
flag:
1 | ➜ ~ crictl images -v |
Container Management
List running containers using crictl ps
:
1 | ➜ ~ crictl ps |
Filter containers by status with the -s
option:
1 | ➜ ~ crictl ps -s Exited |
Execute commands within a container:
1 | ➜ ~ crictl exec -it e7f156d31942f whoami |
View container logs:
1 | ➜ ~ crictl logs e7f156d31942f |
Follow logs in real time using -f
or limit output with --tail N
.
Monitor container resource usage with crictl stats
:
1 | ➜ ~ crictl stats e7f156d31942f |
For more features, refer to kubernetes-sigs/cri-tools.