containerd/containerd
v2 reorganization
The directory layout you see today is the result of a deliberate reorganization carried out in early 2024. This page explains what changed and why.
Before v2
In containerd 1.x, the repository root held the containerd package. Every file at the root (container.go, client.go, task.go, image.go, …) was imported as github.com/containerd/containerd. Subpackages were sprawling: images/, snapshots/, runtime/, metadata/, etc. all sat at the root, mingling user-facing types with daemon internals.
This had a few painful consequences:
- The Go module's import path (
github.com/containerd/containerd) was the same as the root package, making the root a hot zone for breaking changes. - Internal-only daemon code was importable from the outside (people accidentally took dependencies on packages they shouldn't have).
containerd config dumphad to know about every config struct, but those structs lived next to their plugins, scattered around the tree.
What changed
The v2 reorg, done in a burst of move-only commits in January–February 2024, did the following:
- Renamed the module from
github.com/containerd/containerdtogithub.com/containerd/containerd/v2. - Moved the embeddable client from the repository root to
client/(preserving the type names). - Moved core subsystem interfaces (and their built-in implementations) into
core/(core/content,core/images,core/runtime,core/snapshots,core/sandbox,core/transfer,core/diff,core/leases,core/metadata,core/mount,core/metrics,core/remotes,core/streaming,core/unpack). - Moved daemon-internal packages into
internal/(most importantly the CRI plugin ininternal/cri/). - Forbade source files at the repository root from this point forward (only configuration and build files allowed).
The blamed commits include:
21b4f3f0a"Move content to core/content"9456048f4"Move containers to core/containers"913edcd48"Move diff to core/diff"57ea8aef3"Move images to core/images"f80760f9f"Move leases to core/leases"1a1e0e8c8"Move metadata to core/metadata"6e5408dce"Move mount to core/mount"0dabf6f15"Move remotes to core/remotes"228ad5a5c"Move sandbox to core/sandbox"fcd39ccc5"Move snapshots to core/snapshots"df9b0a067"Move metrics to core/metrics"dbc74db6a"Move runtime to core/runtime"f46aea618(Feb 2024) "Move transfer and unpack packages"72f21833b(Feb 2024) "Move events to plugins and core"
What stayed
pkg/— reusable helpers, kept as-is.api/— already a separate module, kept.cmd/— already had per-binary subdirectories, kept.defaults/,version/— small leaf packages, kept.
What this means for contributors
CONTRIBUTING.md codifies the rule:
Try to put a new package under the appropriate root directories. The root directory is reserved for configuration and build files, no source files will be accepted in root since containerd v2.0.
The directory you choose now matters for visibility:
core/— interface + built-ins, importable by plugins and clientspkg/— generic helpers, importable by anyoneinternal/— daemon-internal, not importable outside this module (Go enforces this)client/— public Go embedding APIplugins/— register-by-import plugin code
Migration helper
contrib/v2-migrate.sh is a sed-on-imports script for downstream consumers updating from v1.x to v2.x. It rewrites github.com/containerd/containerd (and the well-known subpackage paths) to their v2 equivalents.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.