Open-Source Wikis

/

containerd

/

Systems

/

Runtime v2

containerd/containerd

Runtime v2

The daemon-side counterpart to the shim binary. Owns the lifecycle of every running task: spawning shims, dispatching ttrpc calls, watching for exits, and reattaching after daemon restarts.

Purpose

  • Convert containerd Task operations (Create/Start/Pause/Resume/Kill/Exec/Delete) into ttrpc requests against the right shim.
  • Track running tasks across daemon restarts by re-discovering shim sockets in the state directory.
  • Multiplex events from N shims into the daemon's event stream.

Directory layout

core/runtime/
├── runtime.go        # high-level Runtime interface
├── task.go           # Task interface
├── monitor.go        # OOM and exit monitor abstractions
├── events.go
├── nsmap.go          # per-namespace task index
├── opts/             # task and runtime options
├── restart/          # restart-on-exit policy
└── v2/               # the runtime v2 implementation
    ├── manager.go    # the heart of the system
    ├── shim.go       # daemon-side ttrpc client wrapper
    ├── runc/         # convenience for runtime IDs starting with io.containerd.runc.*
    └── ...

Key abstractions

Type / file Purpose
runtime.PlatformRuntime (core/runtime/runtime.go) The interface plugins of type RuntimePluginV2 register
runtime.Task (core/runtime/task.go) The daemon-facing handle on a running container
v2.TaskManager (core/runtime/v2/manager.go) The runtime v2 implementation; loads existing tasks at startup, spawns shims for new ones
v2.shim (core/runtime/v2/shim.go) Wraps a ttrpc client to a single shim with a connection-loss watcher
nsMap (core/runtime/nsmap.go) Namespace-keyed map of tasks; handles concurrent add/get/remove

Spawning a shim

sequenceDiagram
    autonumber
    participant TaskSvc as Tasks gRPC
    participant Manager as v2.TaskManager
    participant Binary as containerd-shim-runc-v2
    participant Daemon as containerd

    TaskSvc->>Manager: Create(id, runtime, bundle)
    Manager->>Manager: locate shim binary by runtime ID
    Manager->>Binary: exec --start --address=<daemon ttrpc> --bundle=<dir>
    Binary-->>Manager: print socket path on stdout, then exit
    Manager->>Binary: dial socket (ttrpc client)
    Manager->>Binary: TaskService.Create(...)
    Binary-->>Manager: created
    Manager->>Daemon: insert into nsMap
    TaskSvc-->>Manager: Start
    Manager->>Binary: TaskService.Start

The runtime ID (io.containerd.runc.v2, io.containerd.runhcs.v1, …) determines the binary name: containerd looks for containerd-shim-<id> on $PATH. Custom runtimes are registered via the CRI config or the Go client.

Reattach after daemon restart

v2.TaskManager.loadExistingTasks walks the state directory looking for shim socket paths and per-task metadata files. For each, it:

  1. Dials the existing ttrpc socket.
  2. Calls TaskService.State to verify the shim is alive.
  3. Inserts the task into the in-memory nsMap.

If the shim is unresponsive or the socket is dead, the task is marked as exited and cleaned up.

Event plumbing

Each shim publishes events back to the daemon over the events service (api/services/events/v1/). The runtime v2 manager subscribes and forwards them onto the daemon's event exchange (plugins/events). Consumers downstream (ctr events, the metrics pipeline, the CRI plugin) see them via the standard events stream.

Integration points

  • Shim binary: see containerd-shim-runc-v2. The two are designed to evolve together via the ttrpc API in api/runtime/task/v3/.
  • Tasks gRPC service: plugins/services/tasks/ translates gRPC Tasks.* requests into runtime calls.
  • Sandbox controller: pod-sandbox shims are managed via the same code path; the sandbox controller registers RuntimePluginV2 extensions for sandbox-aware shims (internal/cri/server/podsandbox).

Failure modes

Symptom Likely site
failed to publish task to events: ttrpc connection closed Shim died; manager cleans up
containerd-shim-runc-v2: not found The runtime binary isn't on PATH or the runtime ID is misspelled
Tasks "leak" across restarts A shim is alive but the daemon's state file was deleted; manager will spawn a fresh shim and the orphan stays

Entry points for modification

  • New runtime: implement a binary that responds to --start and exposes TaskService over ttrpc; register it as a RuntimePluginV2 (or just rely on the runtime ID convention and supply the binary).
  • New event hook: subscribe to the events service rather than modifying the runtime manager.
  • Custom shim spawn options: extend core/runtime/opts/ with new Opt functions.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Runtime v2 – containerd wiki | Factory