Welcome to day 3 of our series on containerd
internals! This post will cover
ctr
, a command-line tool for containerd.
What is ctr
?
containerd is a long-lived daemon for managing the lifecycle of containers and
their associated resources (images, filesystems, processes, etc). containerd
itself isn’t really interactive; the only way to make it do things is via one
of the API surfaces it exposes. Most containerd installations have two API
surfaces: containerd’s primary
first-party gRPC API
and the Kubernetes Container Runtime Interface (CRI)
API.
An API client is how you can interact with containerd. Higher-level tools
like Docker, Kubernetes, or nerdctl
are containerd clients. containerd also
provides a
Go client library
for interacting with the gRPC API.
ctr
is a command-line client of containerd that we built as a development
tool and a demonstrator for how to integrate with the containerd API through
our Go client library.
What isn’t ctr
?
As a development tool and demonstrator, ctr
isn’t the recommended way to
use containerd in a production setting. While ctr
is what we use for our own
development (and thus, should work), we’ve
explicitly excluded it from our stability guarantees.
This means that, while we don’t usually intentionally break ctr
’s
behavior, we don’t consider it to be a high-priority to fix changes like that
or to address bugs in it. The exception would be when a change (exposed
through ctr
) is breaking for other reasons; for example, if a Go client
library change introduces a break in ctr
it likely also introduces a break in
other importers of the client library. In a case like that, we’d fix the
client library and ctr
would get fixed as a result.
When should I use ctr
?
ctr
is our development tool and a demonstration of using the client library.
If you are developing new features in containerd, or if you are integrating
with containerd, ctr
is a great thing to use! Debugging and finding out
about deprecations are other good use-cases.
Development tool
When we first implement new features in containerd, ctr
is usually how we
test them! Lots of the subcommands and tools are a direct mapping to either
the API or to a higher-level action that needs to be accomplished.
For example, the content
and snapshots
subcommands expose lower-level
details of how containerd manages the actual content of container filesystems,
while the images
subcommand demonstrates how the internal Images
service
ties together content and snapshots into a standard workflow for both container
image interchange (push, pull) and using images with containers.
Some subcommands, like shim
, go beyond the normal containerd gRPC API and
client library too. This subcommand bypasses the containerd daemon and can
interact directly with the
shims
that supervise processes within a container.
Demonstrator
The source code
of ctr
is designed to be read and can serve as an example for your own
integrations with containerd. You can look at what it takes to
run a container,
or push an image,
or subscribe to events.
Debugging
When something goes wrong, ctr
can also be a helpful debugging tool. Because
it offers the same set of tools we use for developing features, it also
can expose a lot of useful information about the runtime state of containerd.
The tasks
, snapshots
, events
, and shim
subcommands can be really
helpful for investigating “what does containerd think is going on” and “what is
the state of associated components”, while the events
and pprof
subcommands can dig deeper into the sequence of events that occurs as well as
the runtime state (goroutines, heap, CPU profiles, etc) of the daemon.
Deprecations
ctr
is also our preferred tool for helping you find out about
deprecation warnings.
ctr deprecations list
will expose any usage of deprecated features that
are expected to be removed in future versions of containerd. This can be
really helpful in
preparing for an upgrade to 2.0.
What should I use instead of ctr
in production?
Production use of containerd should be through a fully-supported client (such
as Kubernetes, crictl
, or nerdctl
) or by directly integrating with the gRPC
API.