containerd Configuration
Master containerd configuration for production environments. Learn to configure the CRI plugin, registry mirrors, snapshot drivers, and performance tuning parameters.
containerd is configured using a TOML file located at `/etc/containerd/config.toml`. This file controls every aspect of containerd's behavior: from basic settings like logging and storage paths to advanced plugin configurations for the CRI (Container Runtime Interface), snapshot drivers, and registry mirrors.
Proper configuration is essential for production environments. The default configuration works for development, but for production you'll need to tune settings like cgroup management, image pull behavior, and registry authentication. This guide covers the most important configuration options.
# Generate default configuration
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
# View current configuration
containerd config dump
# Validate configuration
containerd config validate
# Test configuration
sudo containerd --config /etc/containerd/config.toml --log-level debug
# Basic config.toml structure
version = 2
# Root directory for containerd state
root = "/var/lib/containerd"
# State directory
state = "/run/containerd"
# Log level (trace, debug, info, warn, error, fatal, panic)
log_level = "info"
# Log format (text or json)
log_format = "text"
# Disable plugins
disabled_plugins = []
# Required plugins (empty means all enabled)
required_plugins = []
The CRI plugin is the most important configuration for Kubernetes nodes. It controls how containerd interacts with kubelet.
# CRI plugin configuration
[plugins."io.containerd.grpc.v1.cri"]
# Pause image (sandbox container)
sandbox_image = "registry.k8s.io/pause:3.9"
# Max log line size
max_container_log_line_size = 16384
# Cgroup driver for kubelet
[plugins."io.containerd.grpc.v1.cri".cgroup]
# Path to cgroup for pods
path = "/"
# containerd settings
[plugins."io.containerd.grpc.v1.cri".containerd]
# Default runtime
default_runtime_name = "runc"
# Snapshotter
snapshotter = "overlayfs"
# Runtime 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]
# Use systemd cgroups
SystemdCgroup = true
# Image pulling settings
[plugins."io.containerd.grpc.v1.cri".containerd]
# Pull image timeout
image_pull_progress_timeout = "120s"
# Image pull behavior
# Valid values: always, missing, never
image_pull_behavior = "missing"
Configure registry mirrors, authentication, and TLS settings for pulling images from private registries.
# Registry configuration
[plugins."io.containerd.grpc.v1.cri".registry]
# Path to registry configuration directory
config_path = "/etc/containerd/certs.d"
# Registry mirrors
[plugins."io.containerd.grpc.v1.cri".registry.mirrors]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
endpoint = ["https://registry-1.docker.io"]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."myregistry.azurecr.io"]
endpoint = ["https://myregistry.azurecr.io"]
# Auth configuration
[plugins."io.containerd.grpc.v1.cri".registry.configs."myregistry.azurecr.io".auth]
username = "myuser"
password = "mypassword"
# TLS configuration
[plugins."io.containerd.grpc.v1.cri".registry.configs."myregistry.azurecr.io".tls]
insecure_skip_verify = false
ca_file = "/etc/containerd/certs.d/ca.crt"
# Snapshotter configuration
[plugins."io.containerd.snapshotter.v1.overlayfs"]
root_path = "/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs"
# For ZFS
[plugins."io.containerd.snapshotter.v1.zfs"]
root_path = "/var/lib/containerd/io.containerd.snapshotter.v1.zfs"
# For native (copy-based)
[plugins."io.containerd.snapshotter.v1.native"]
root_path = "/var/lib/containerd/io.containerd.snapshotter.v1.native"
# Runtime configuration
[plugins."io.containerd.runtime.v2.task"]
# Platform-specific settings
[plugins."io.containerd.runtime.v2.task".platforms]
[plugins."io.containerd.runtime.v2.task".platforms.linux]
# Runtime root directory
root = "/run/containerd/runtime/v2/task"
# Logging configuration
[plugins."io.containerd.runtime.v2.task".options]
# Enable debug logging for runtime
debug = false
# Metrics configuration
[metrics]
# Address to serve metrics on
address = "0.0.0.0:1338"
# Enable metrics
enabled = true
# Metrics path
[metrics.prometheus]
# Enable Prometheus metrics
enabled = true
# Global logging
log_level = "info"
log_format = "text"
# CRI plugin logging
[plugins."io.containerd.grpc.v1.cri"]
# Additional logging for CRI
stream_server_address = "127.0.0.1"
stream_server_port = "0"
[plugins."io.containerd.grpc.v1.cri".cgroup]
# Log cgroup operations
path = "/"
# Runtime logging
[plugins."io.containerd.runtime.v2.task".options]
# Enable debug logging
debug = false
Timeouts
Storage
Plugins
Security
# Validate configuration
containerd config validate
# Test configuration
sudo containerd --config /etc/containerd/config.toml --log-level debug
# Restart containerd
sudo systemctl restart containerd
# Check status
sudo systemctl status containerd
# Verify configuration is loaded
containerd config dump | grep -A 10 "cri"
# Scenario 1: Use registry mirror for Docker Hub
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
endpoint = ["https://mirror.gcr.io", "https://registry-1.docker.io"]
# Scenario 2: Configure private registry with auth
[plugins."io.containerd.grpc.v1.cri".registry.configs."myregistry.azurecr.io".auth]
auth = "base64_encoded_credentials"
# Scenario 3: Use ZFS snapshotter
snapshotter = "zfs"
[plugins."io.containerd.snapshotter.v1.zfs"]
root_path = "/var/lib/containerd/zfs"
# Scenario 4: Disable unnecessary plugins
disabled_plugins = ["io.containerd.snapshotter.v1.devicemapper"]
Proper configuration is essential for production containerd deployments. Use these settings as a starting point and adjust based on your specific requirements.