containerd/containerd
Plugin runtime
The plugin runtime is the part of the daemon that owns which plugins exist, in what order they initialize, and how they discover each other. It's a thin layer on top of github.com/containerd/plugin, with containerd-specific wiring in cmd/containerd/server/server.go and a per-type registry in plugins/types.go.
Purpose
- Register all built-in plugins via
init()side effects (blank imports fromcmd/containerd/builtins/). - Translate operator-supplied proxy plugin entries in
config.tomlinto in-process plugin registrations whoseInitFndials a remote socket. - Compute a dependency-ordered initialization graph and run each plugin's
InitFn. - Make the resulting plugin instances visible to other plugins through the
plugin.Setpassed viaInitContext.
Plugin types
The complete set of plugin types is defined as plugin.Type constants in plugins/types.go. Each constant encodes the URI scheme that the daemon uses to address the plugin in config and introspection:
const (
InternalPlugin plugin.Type = "io.containerd.internal.v1"
RuntimePlugin plugin.Type = "io.containerd.runtime.v1" // legacy
RuntimePluginV2 plugin.Type = "io.containerd.runtime.v2"
ServicePlugin plugin.Type = "io.containerd.service.v1"
GRPCPlugin plugin.Type = "io.containerd.grpc.v1"
TTRPCPlugin plugin.Type = "io.containerd.ttrpc.v1"
SnapshotPlugin plugin.Type = "io.containerd.snapshotter.v1"
DiffPlugin plugin.Type = "io.containerd.differ.v1"
MetadataPlugin plugin.Type = "io.containerd.metadata.v1"
ContentPlugin plugin.Type = "io.containerd.content.v1"
GCPlugin plugin.Type = "io.containerd.gc.v1"
EventPlugin plugin.Type = "io.containerd.event.v1"
LeasePlugin plugin.Type = "io.containerd.lease.v1"
StreamingPlugin plugin.Type = "io.containerd.streaming.v1"
TracingProcessorPlugin plugin.Type = "io.containerd.tracing.processor.v1"
MetricsPlugin plugin.Type = "io.containerd.metrics.v1"
NRIApiPlugin plugin.Type = "io.containerd.nri.v1"
TransferPlugin plugin.Type = "io.containerd.transfer.v1"
SandboxStorePlugin plugin.Type = "io.containerd.sandbox.store.v1"
SandboxControllerPlugin plugin.Type = "io.containerd.sandbox.controller.v1"
PodSandboxPlugin plugin.Type = "io.containerd.podsandbox.controller.v1"
ImageVerifierPlugin plugin.Type = "io.containerd.image-verifier.v1"
WarningPlugin plugin.Type = "io.containerd.warning.v1"
CRIServicePlugin plugin.Type = "io.containerd.cri.v1"
ShimPlugin plugin.Type = "io.containerd.shim.v1"
HTTPHandler plugin.Type = "io.containerd.http.v1"
ServerPlugin plugin.Type = "io.containerd.server.v1"
MountManagerPlugin plugin.Type = "io.containerd.mount-manager.v1"
MountHandlerPlugin plugin.Type = "io.containerd.mount-handler.v1"
)The same file defines RuntimeRuncV2, RuntimeRunhcsV1 (runtime IDs reachable from CRI config), the property keys PropertyRootDir, PropertyStateDir, PropertyGRPCAddress, PropertyTTRPCAddress and the SnapshotterRootDir exports key.
How plugins discover each other
Each plugin's Registration lists the types it needs:
&plugin.Registration{
Type: plugins.GRPCPlugin,
ID: "containers",
Requires: []plugin.Type{plugins.ServicePlugin},
InitFn: func(ic *plugin.InitContext) (any, error) {
plugins, err := ic.GetByType(plugins.ServicePlugin)
...
},
}registry.Graph returns the registrations in topological order, so by the time InitFn runs, all required types are already initialized and reachable via ic.Get(t) or ic.GetByType(t).
Proxy plugins
server.LoadPlugins (in cmd/containerd/server/server.go) iterates config.ProxyPlugins (from [proxy_plugins.*]) and synthesizes a plugin.Registration per entry. Currently supported types:
TOML type |
Mapped to | Wrapper |
|---|---|---|
snapshot |
SnapshotPlugin |
core/snapshots/proxy.NewSnapshotter |
content |
ContentPlugin |
core/content/proxy.NewContentStore |
sandbox |
SandboxControllerPlugin |
core/sandbox/proxy.NewSandboxController |
diff |
DiffPlugin |
core/diff/proxy.NewDiffApplier |
The wrapper opens a gRPC connection to the configured address (lazily, sharing a connection per address via proxyClients) and returns a Go-native interface implementation that forwards calls.
Initialization sequence
apply(ctx, config)— handle deprecated config keys, apply OOM score, configure sub-reapers.- For each
Timeoutsentry,timeout.Setthe duration so plugins can read it. LoadPluginsbuilds the graph.- For each
StreamProcessorsentry, register a binary differ viadiff.RegisterProcessor. - Walk the graph: build an
InitContext, callInit, store the result. - Track
RequiredPlugins; at the end, error out if any required ID failed. recordConfigDeprecationswrites any deprecated-key warnings into the warning service for later read bycontainerd deprecations(seeplugins/services/warning).
Failure semantics
server.New distinguishes three plugin outcomes:
- Skipped (
plugin.IsSkipPlugin(err)— typically platform unsupported): logged at INFO and continues. - Failed required: aborts daemon startup.
- Failed optional: logged at WARN, plugin is omitted, but if the plugin had already called
RegisterReadinessthen containerd treats this as fatal (the plugin promised to come up).
Key source files
| File | Purpose |
|---|---|
plugins/types.go |
Plugin type and property constants |
cmd/containerd/server/server.go |
New, LoadPlugins, Server.Start, Server.Stop, proxy plugin wiring |
cmd/containerd/builtins/builtins.go |
Cross-platform blank imports |
cmd/containerd/builtins/builtins_linux.go |
Linux-specific imports (devmapper, blockio, NRI, …) |
vendor/github.com/containerd/plugin/registry/registry.go |
Topological sort over registrations |
Entry points for modification
- New plugin type: add a constant in
plugins/types.goand a corresponding service interface (typically undercore/<area>/). - New built-in: add a Go file under
plugins/<type>/<name>/, register it ininit(), and blank-import it fromcmd/containerd/builtins. - New proxy plugin shape: extend the
switch pp.TypeinLoadPlugins. - Different startup ordering: prefer
Requiresover hand-coded sequences.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.