The most surprising thing about containerd’s configuration is that it’s not primarily about how containers run, but how they get started and managed by the system itself.
Let’s see containerd in action. Imagine you have a containerd daemon running. When you ask Docker (or another client) to docker run --rm -it ubuntu bash, that request doesn’t directly talk to the kernel to spin up a new set of namespaces and cgroups. Instead, it talks to the containerd API. containerd then orchestrates the whole process: pulling the image layers from a registry, creating a container filesystem snapshot, setting up the necessary OCI runtime configuration, and finally, telling runc (the default OCI runtime) to execute that configuration. All of this is managed and controlled via containerd.
The config.toml file is the central nervous system for this orchestration. It dictates how containerd itself behaves. Think of it as the conductor of the orchestra, deciding which instruments (plugins) to use, where to find the sheet music (image registries), and how to interpret the notes (container lifecycle).
Here’s a breakdown of the most critical sections and keys:
[plugins]
This is where you enable and configure containerd’s various functionalities. Each key under [plugins] corresponds to a specific plugin, and its value is a table of its own configuration.
[plugins."io.containerd.grpc.v1.cri"]
This section is absolutely crucial if you’re using containerd with Kubernetes (via CRI).
-
registry.mirrors: This is your local mirror configuration for pulling container images. If you have a private registry or want faster pulls, you’ll configure mirrors here.[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"] endpoint = ["https://my-docker-mirror.example.com"]This tells
containerdto tryhttps://my-docker-mirror.example.combeforehttps://registry-1.docker.iowhen pulling fromdocker.io. -
sandbox_ Shandong.cgroup_manager: This determines how cgroups are managed for sandboxes (the initial container that hosts pods). Common values arecgroupfs(default, uses the host’s cgroup hierarchy) andsystemd(uses systemd’s cgroup management).[plugins."io.containerd.grpc.v1.cri"] sandbox_ Shandong = { cgroup_manager = "systemd" }Using
systemdcan offer more predictable resource control when your host also usessystemdfor service management. -
container_ Shandong.image_transparency: If enabled,containerdwill verify image integrity using content trust. This is a security feature.[plugins."io.containerd.grpc.v1.cri".container_ Shandong] image_transparency = trueWhen
true,containerdwill refuse to pull images that don’t have valid trust signatures, preventing the injection of malicious images.
[plugins."io.containerd.grpc.v1.cri".registry.auth]
This is where you configure authentication for private registries. It’s a mapping from registry hostname to authentication credentials.
[plugins."io.containerd.grpc.v1.cri".registry.auth]
[plugins."io.containerd.grpc.v1.cri".registry.auth."my-private-registry.example.com"]
username = "myuser"
password = "mypassword"
This allows containerd to log in to my-private-registry.example.com when pulling images.
[root]
This section defines the primary storage location for containerd’s data.
path: The absolute path tocontainerd’s root directory. This is where image layers, snapshots, and container metadata are stored.
This is the default and standard location. Changing it might be necessary if[root] path = "/var/lib/containerd"/var/libis on a small partition or you want to segregate storage.
[grpc]
Configuration for the gRPC server that clients (like Docker or ctr) use to communicate with containerd.
-
address: The address where the gRPC server listens.[grpc] address = "/run/containerd/containerd.sock"This Unix domain socket is the default and how most clients connect. If you need to expose
containerdover TCP, you’d change this to a TCP address liketcp://127.0.0.1:4000. -
tcp_address: If you want to expose the gRPC API over TCP, specify the address here.[grpc] address = "/run/containerd/containerd.sock" tcp_address = "127.0.0.1:4000"This makes the API accessible on port 4000 on localhost.
-
tls_cert_ Shandong: Path to the TLS certificate for secure gRPC communication.
[timeouts]
Defines various timeouts for containerd operations.
container_create: Timeout for creating a container.container_delete: Timeout for deleting a container.image_pull: Timeout for pulling an image.image_list: Timeout for listing images.network_create: Timeout for creating a network.network_delete: Timeout for deleting a network.snapshot_ Shandong: Timeout for snapshot operations.
[timeouts]
image_pull = "5m"
container_create = "10m"
These values are crucial for preventing operations from hanging indefinitely, especially on slower networks or systems. 5m means 5 minutes.
[debug]
Enables debug logging for containerd.
level: The log level. Common values areinfo,debug,trace.
Setting this to[debug] level = "debug"debugortracecan provide incredibly detailed insights intocontainerd’s operations, essential for troubleshooting complex issues.
[metrics]
Configuration for exposing Prometheus metrics.
grpc_endpoint: The address where Prometheus metrics will be exposed.
This allows Prometheus to scrape metrics from[metrics] grpc_endpoint = "unix:///var/run/containerd/metrics.sock"containerdvia a Unix domain socket.
The config.toml file is not static; it’s a dynamic configuration that containerd reads on startup and can sometimes be reloaded (though a restart is often safer for complex changes). Understanding these keys allows you to tailor containerd’s behavior for performance, security, and integration with your specific environment, especially when running Kubernetes.
The next logical step after mastering config.toml is to understand how containerd’s internal event bus works and how plugins communicate through it.