containerd/containerd
Image distribution
How containerd pulls, pushes, imports, exports, and unpacks images. Spread across core/remotes/, core/images/, core/transfer/, core/unpack/, and the transfer plugin.
Purpose
- Talk to OCI distribution registries (Docker registry v2 protocol, OCI distribution-spec).
- Stream layers into the content store with resumption and parallelism.
- Materialize image layers as committed snapshots in a chosen snapshotter ("unpack").
- Provide a higher-level transfer API that bundles pull/push/import/export in a single streaming gRPC call.
Pieces
| Piece | Code | Role |
|---|---|---|
| Resolver | core/remotes/, core/remotes/docker/ |
Resolves a reference (docker.io/library/alpine:3) to a Resolver capable of fetching/pushing |
| Auth | core/remotes/docker/auth/, pkg/oci/ |
Handles bearer tokens, basic auth, dockerconfig |
| Hosts | core/remotes/docker/config/ |
hosts.toml mirror configuration (per-host TLS, capabilities, mirrors) |
| Image store | core/images/, core/metadata/images.go |
Image records: name → root descriptor |
| Unpack | core/unpack/ |
Walks a manifest, pulls each layer, applies it to a snapshotter |
| Differ | core/diff/, plugins/diff/walking/ |
Computes / applies layer diffs |
| Transfer | core/transfer/, plugins/transfer/ |
High-level streaming pipeline that exposes pull/push/import/export over a single gRPC stream |
Pull flow
sequenceDiagram
autonumber
participant Client
participant TransferSvc as Transfer service
participant Resolver as remotes.Resolver
participant Content as Content store
participant Unpack as unpack pipeline
participant Snap as Snapshotter
participant Meta as Metadata
Client->>TransferSvc: Transfer(Pull{ref, unpack=true})
TransferSvc->>Resolver: Resolve(ref)
Resolver-->>TransferSvc: Descriptor, Fetcher
TransferSvc->>Content: ingest manifest
TransferSvc->>Content: ingest config
TransferSvc->>Content: ingest layers (parallel)
TransferSvc->>Unpack: Unpack(image, snapshotter)
Unpack->>Snap: Prepare each layer
Unpack->>Snap: Apply diff
Unpack->>Snap: Commit
TransferSvc->>Meta: store image
TransferSvc-->>Client: Progress eventsResolver
core/remotes/docker/resolver.go implements remotes.Resolver:
type Resolver interface {
Resolve(ctx context.Context, ref string) (name string, desc ocispec.Descriptor, err error)
Fetcher(ctx context.Context, ref string) (Fetcher, error)
Pusher(ctx context.Context, ref string) (Pusher, error)
}The Docker resolver speaks the registry v2 HTTP API. It uses core/remotes/docker/config/ to read host overrides from hosts.toml (mirror lists, scheme, TLS) and core/remotes/docker/auth/ to handle Bearer/Basic auth.
Hosts.toml
docs/hosts.md describes the registry config format. Common fields:
server = "https://my-private-registry.example.com"
[host."https://mirror1.example.com"]
capabilities = ["pull", "resolve"]
skip_verify = falseThe config is read on-demand per registry. See core/remotes/docker/config/hosts.go.
Unpacking
core/unpack/unpacker.go orchestrates layer extraction:
- Read the manifest from the content store.
- For each layer (in order),
Preparea new snapshot whose parent is the previous layer's commit. - Run the differ to apply the layer's tar stream onto the prepared snapshot.
Committhe snapshot under a content-derived name (uncompressed digest).- Repeat until the manifest is exhausted.
The differ is pluggable via the DiffPlugin type — walking (the default) walks the layer tar; erofs, windows, and lcow provide platform-specific paths.
Transfer service
The transfer service is the modern entry point. Clients send a single streaming Transfer RPC carrying:
- A source (
OCIRegistry,ImageStore,Importer, …) - A destination (
ImageStore,OCIRegistry,Exporter, …) - Optional filters/transformations
The plugin in plugins/transfer/ registers TransferPlugin builtins for the supported source/destination types; core/transfer/ defines the interfaces.
The newer transfer service supersedes direct use of the Images / Content gRPC services for pulls and pushes from clients that don't need fine-grained control.
Push flow
The mirror image of pull. Resolver becomes a Pusher; layers are uploaded in parallel; at the end, the manifest is uploaded.
Import / export
ctr image import and ctr image export use the transfer service's Importer/Exporter types, which read/write OCI image layouts (and Docker save/load tarballs).
Image verification
Before an image is committed to the image store, the daemon can run an external verifier. The ImageVerifierPlugin (plugins/imageverifier/bindir) runs configured binaries against each manifest and short-circuits on failure. See docs/image-verification.md.
Entry points for modification
- New auth scheme: extend
core/remotes/docker/auth/. - New transport: implement
remotes.Resolverand register it from a plugin. - New differ: implement
core/diff/diff.go's interface and add a plugin underplugins/diff/<name>/. - New transfer source/destination: register a
TransferPluginand implement the correspondingcore/transferinterface.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.