Containerd has emerged as the industry-standard container runtime, serving as the foundation for modern containerization platforms like Docker and Kubernetes. This comprehensive guide explores everything you need to know about containerd on Linux, from basic concepts to advanced deployment strategies.
What is containerd?
Containerd is a high-level container runtime that manages the complete container lifecycle on Linux systems. Originally developed by Docker and later donated to the Cloud Native Computing Foundation (CNCF), containerd provides a stable, production-ready foundation for container operations.
Unlike Docker, which includes additional features like image building and networking, containerd focuses solely on container runtime functionality, making it lightweight and efficient for production environments.
Key Features of containerd
- OCI Compliance: Fully compatible with Open Container Initiative standards
- Kubernetes Integration: Native CRI (Container Runtime Interface) support
- Image Management: Efficient container image storage and distribution
- Snapshot Management: Advanced filesystem layering capabilities
- Plugin Architecture: Extensible design for custom implementations
Installing containerd on Linux
Installation methods vary depending on your Linux distribution. Here are the most common approaches:
Ubuntu/Debian Installation
# Update package index
sudo apt update
# Install containerd
sudo apt install containerd.io
# Enable and start containerd service
sudo systemctl enable containerd
sudo systemctl start containerd
# Verify installation
sudo systemctl status containerd
CentOS/RHEL Installation
# Add Docker repository
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# Install containerd
sudo yum install containerd.io
# Start and enable service
sudo systemctl start containerd
sudo systemctl enable containerd
Manual Binary Installation
# Download latest containerd binary
wget https://github.com/containerd/containerd/releases/download/v1.7.6/containerd-1.7.6-linux-amd64.tar.gz
# Extract to system directory
sudo tar Cxzvf /usr/local containerd-1.7.6-linux-amd64.tar.gz
# Create systemd service file
sudo mkdir -p /usr/local/lib/systemd/system/
sudo curl -o /usr/local/lib/systemd/system/containerd.service https://raw.githubusercontent.com/containerd/containerd/main/containerd.service
# Install runc
wget https://github.com/opencontainers/runc/releases/download/v1.1.9/runc.amd64
sudo install -m 755 runc.amd64 /usr/local/sbin/runc
containerd Configuration
The primary configuration file for containerd is located at /etc/containerd/config.toml. Generate a default configuration:
# Generate default configuration
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
# Edit configuration
sudo nano /etc/containerd/config.toml
Essential Configuration Options
[grpc]
address = "/run/containerd/containerd.sock"
tcp_address = ""
tcp_tls_cert = ""
tcp_tls_key = ""
[debug]
address = ""
level = "info"
[metrics]
address = ""
grpc_histogram = false
[plugins."io.containerd.grpc.v1.cri"]
enable_selinux = false
sandbox_image = "k8s.gcr.io/pause:3.7"
[plugins."io.containerd.grpc.v1.cri".containerd]
snapshotter = "overlayfs"
default_runtime_name = "runc"
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes]
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
runtime_type = "io.containerd.runc.v2"
Using ctr Command-Line Tool
The ctr command is containerd’s native client for container management. Here are essential commands:
Image Management
# Pull an image
sudo ctr images pull docker.io/library/nginx:latest
# List images
sudo ctr images list
# Tag an image
sudo ctr images tag docker.io/library/nginx:latest nginx:web
# Remove an image
sudo ctr images remove nginx:web
Expected Output:
$ sudo ctr images list
REF TYPE DIGEST SIZE PLATFORMS LABELS
docker.io/library/nginx:latest application/vnd.docker.distribution.manifest.v2+json sha256:4c0fdaa8b6341bfdeca5f18f7837462c80cff90527ee35ef185571e1c327beac 67.2 MiB linux/amd64 -
Container Operations
# Create a container
sudo ctr container create docker.io/library/nginx:latest nginx-container
# List containers
sudo ctr container list
# Start a container
sudo ctr task start nginx-container
# Execute commands in running container
sudo ctr task exec --exec-id bash nginx-container /bin/bash
# Stop a container
sudo ctr task kill nginx-container
# Remove a container
sudo ctr container delete nginx-container
Namespace Management
Containerd uses namespaces to isolate container resources. The default namespace is “default”, but you can create custom namespaces:
# List namespaces
sudo ctr namespace list
# Create a new namespace
sudo ctr namespace create production
# Use specific namespace
sudo ctr --namespace production images pull nginx:latest
# List containers in specific namespace
sudo ctr --namespace production container list
Integration with Kubernetes
Containerd serves as the default container runtime for Kubernetes. Configure kubelet to use containerd:
Kubelet Configuration
# Edit kubelet configuration
sudo nano /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
# Add containerd socket
Environment="KUBELET_EXTRA_ARGS=--container-runtime=remote --container-runtime-endpoint=unix:///run/containerd/containerd.sock"
# Restart kubelet
sudo systemctl daemon-reload
sudo systemctl restart kubelet
CRI Configuration for Kubernetes
[plugins."io.containerd.grpc.v1.cri"]
enable_selinux = false
sandbox_image = "k8s.gcr.io/pause:3.7"
[plugins."io.containerd.grpc.v1.cri".cni]
bin_dir = "/opt/cni/bin"
conf_dir = "/etc/cni/net.d"
max_conf_num = 1
conf_template = ""
[plugins."io.containerd.grpc.v1.cri".registry]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
endpoint = ["https://registry-1.docker.io"]
Advanced Snapshot Management
Containerd’s snapshot system manages container filesystem layers efficiently:
# List snapshots
sudo ctr snapshots list
# Create a snapshot from an image
sudo ctr images mount docker.io/library/alpine:latest /mnt/alpine
# Commit changes to new snapshot
sudo ctr snapshots commit overlay alpine-custom /mnt/alpine
# Remove snapshot
sudo ctr snapshots remove alpine-custom
Monitoring and Logging
Viewing containerd Logs
# View service logs
sudo journalctl -u containerd -f
# Check containerd status
sudo systemctl status containerd
# View containerd metrics
sudo ctr pprof goroutines
Container Logs
# View container logs
sudo ctr task logs nginx-container
# Follow logs in real-time
sudo ctr task logs --follow nginx-container
Performance Optimization
Storage Driver Configuration
# Configure overlay2 for better performance
[plugins."io.containerd.snapshotter.v1.overlayfs"]
root_path = "/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs"
upperdir_label = false
# Enable parallel downloads
[plugins."io.containerd.grpc.v1.cri"]
max_concurrent_downloads = 10
Memory and CPU Limits
# Create container with resource limits
sudo ctr run --rm --memory-limit 512MB --cpus 1.0 docker.io/library/nginx:latest limited-nginx
Security Considerations
User Namespace Configuration
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
runtime_type = "io.containerd.runc.v2"
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
SystemdCgroup = true
[plugins."io.containerd.grpc.v1.cri"]
enable_selinux = true
selinux_category_range = 1024
Registry Security
[plugins."io.containerd.grpc.v1.cri".registry.configs]
[plugins."io.containerd.grpc.v1.cri".registry.configs."private-registry.com"]
[plugins."io.containerd.grpc.v1.cri".registry.configs."private-registry.com".tls]
ca_file = "/etc/containerd/certs/ca.pem"
cert_file = "/etc/containerd/certs/client.pem"
key_file = "/etc/containerd/certs/client-key.pem"
Troubleshooting Common Issues
Service Startup Problems
# Check containerd service status
sudo systemctl status containerd
# Verify configuration syntax
sudo containerd config dump
# Test containerd connectivity
sudo ctr version
Image Pull Issues
# Check network connectivity
ping registry-1.docker.io
# Verify DNS resolution
nslookup registry-1.docker.io
# Check registry configuration
sudo ctr images pull --debug docker.io/library/hello-world:latest
Permission Issues
# Check socket permissions
ls -la /run/containerd/containerd.sock
# Verify user groups
groups $USER
# Add user to docker group (if using Docker integration)
sudo usermod -aG docker $USER
Migration from Docker
Migrating from Docker to standalone containerd requires careful planning:
Image Migration
# Export Docker images
docker save nginx:latest -o nginx.tar
# Import to containerd
sudo ctr images import nginx.tar
# Verify imported image
sudo ctr images list | grep nginx
Container State Migration
# Stop Docker service
sudo systemctl stop docker
# Configure containerd for existing containers
sudo containerd config default > /etc/containerd/config.toml
# Start containerd
sudo systemctl start containerd
Best Practices
- Regular Updates: Keep containerd updated for security patches
- Resource Monitoring: Monitor container resource usage regularly
- Backup Configuration: Maintain backups of containerd configuration
- Security Scanning: Implement image vulnerability scanning
- Log Management: Configure centralized logging for containers
Conclusion
Containerd represents the evolution of container runtime technology, providing a robust, lightweight foundation for modern containerized applications. Its integration with Kubernetes and compliance with OCI standards make it an essential tool for DevOps engineers and system administrators.
By mastering containerd’s configuration, management, and troubleshooting techniques, you can build more reliable and efficient containerized infrastructure. Whether you’re migrating from Docker or implementing new container solutions, containerd offers the stability and performance required for production environments.
The future of containerization continues to evolve, and containerd’s modular architecture positions it perfectly to adapt to emerging technologies and requirements in the cloud-native ecosystem.








