Open-Source Wikis

/

containerd

/

Apps

/

containerd-shim-runc-v2

containerd/containerd

containerd-shim-runc-v2

The default per-container shim. One process per container (or per pod sandbox), spawned by the daemon's runtime v2 plugin and surviving daemon restarts. The shim is the bridge between containerd and runc.

Purpose

A shim:

  1. Receives a Create/Start/Exec/Kill/Delete request over ttrpc from the daemon.
  2. Translates it into a runc invocation (runc create, runc start, etc.).
  3. Holds the container's stdio (pipes, fifos, or streamed over the daemon's streaming service).
  4. Reaps the container's process and forwards TaskExit, TaskOOM, and friends back to the daemon.

Because the shim is a separate process, the daemon can be restarted (or crash) without killing running containers.

Directory layout

cmd/containerd-shim-runc-v2/
├── main.go             # 30-line entry point: shim.Run("io.containerd.runc.v2", manager.NewShimManager)
├── main_tracing.go     # build-tag-gated OTel hookup
├── manager/            # shim manager: responds to Start (spawn) / Stop (cleanup)
├── runc/               # runc invocation helpers (cgroup, mounts, console)
├── process/            # the per-process abstraction (init, exec'd, signals)
└── task/               # the ttrpc TaskService implementation

How it runs

sequenceDiagram
    participant Daemon
    participant Shim as containerd-shim-runc-v2
    participant Runc

    Daemon->>Shim: spawn binary with --address, --bundle, --id, ...
    Shim->>Shim: register ttrpc TaskService on socket
    Daemon->>Shim: Create (bundle, options)
    Shim->>Runc: runc create
    Daemon->>Shim: Start
    Shim->>Runc: runc start
    Shim-->>Daemon: TaskStart event
    Note over Shim,Runc: shim watches container PID
    Runc-->>Shim: process exits
    Shim-->>Daemon: TaskExit event
    Daemon->>Shim: Delete
    Shim->>Shim: cleanup, exit

The shim binary is invoked twice:

  • Start: the daemon execs the shim with mode start. The shim daemonizes, spawns its own ttrpc server on a derived address, and prints that address back on stdout for the daemon to read.
  • Serve: the daemonized shim then registers the TaskService ttrpc handlers under cmd/containerd-shim-runc-v2/task/ and waits for requests.

Key abstractions

Type File Purpose
manager.Manager cmd/containerd-shim-runc-v2/manager/ Implements shim.Manager from pkg/shim; handles Start/Stop of the shim process itself
task.Service cmd/containerd-shim-runc-v2/task/service.go TaskService ttrpc implementation (Create, Start, Exec, Kill, Delete, Wait)
process.Init / process.Exec cmd/containerd-shim-runc-v2/process/ The state machine for the container's init process and exec'd processes
runc.NewRunc cmd/containerd-shim-runc-v2/runc/ Wraps github.com/containerd/go-runc with sane defaults

Why a separate binary

  • Static, no gRPC: built with CGO_ENABLED=0 and BUILDTAGS=no_grpc (see Makefile) so it has no shared-library dependencies and no HTTP/2 stack.
  • Daemon restart safety: the shim outlives the daemon. After a daemon restart, the daemon re-attaches via the runtime v2 plugin's reconnect path.
  • Per-container isolation: shim crashes are contained — only one container fails, and the daemon notices via the closed ttrpc connection.

Stdio

Three modes exist:

  1. Fifo: stdio is plumbed through named pipes under --state/.../<id>/. Default for ctr run.
  2. TTY: a pseudo-terminal is allocated; stdin/stdout/stderr go through it.
  3. Streaming: stdio is multiplexed through the daemon's streaming service. The CRI plugin uses this for exec/attach. Implementation: internal/cri/streaming/ and core/streaming.

Failure paths

  • If the shim fails to spawn, the daemon receives the error from the start invocation and surfaces it as a Task creation error.
  • If the shim is killed mid-flight, the daemon's runtime v2 manager (core/runtime/v2/manager.go) detects the broken ttrpc connection and emits TaskExit with ExitCode: 137.
  • If runc fails, the shim translates the error into the appropriate errdefs sentinel (ErrNotFound, ErrFailedPrecondition, …).

Entry points for modification

  • New runc options: cmd/containerd-shim-runc-v2/runc/.
  • Different stdio strategy: cmd/containerd-shim-runc-v2/process/io.go and the streaming integration in internal/cri/.
  • Different process state machine: the process.Init/process.Exec types are designed to be replaced for non-runc runtimes — see core/runtime/v2/runc/v2/ for an alternative example shim built into containerd's source tree.

For the daemon-side counterpart, see runtime v2 system.

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

containerd-shim-runc-v2 – containerd wiki | Factory