Open-Source Wikis

/

containerd

/

Systems

/

CRI plugin

containerd/containerd

CRI plugin

The CRI plugin implements Kubernetes' Container Runtime Interface so that the kubelet can use containerd directly. It's a built-in plugin loaded from cmd/containerd/builtins/cri.go and lives almost entirely in internal/cri/.

Purpose

  • Implement the RuntimeService and ImageService gRPC contracts defined in k8s.io/cri-api.
  • Translate CRI requests (RunPodSandbox, CreateContainer, ListContainers, …) into containerd Go-client calls.
  • Manage CNI for pod networking.
  • Surface container/sandbox metrics in CRI's expected shape.

Directory layout

internal/cri/
├── annotations/      # Standard annotation keys passed through to OCI
├── bandwidth/        # CNI bandwidth shaping helpers
├── config/           # CRI plugin TOML config
├── constants/        # Shared constants (CRI label keys, default paths)
├── instrument/       # gRPC interceptor for tracing / logging CRI calls
├── io/               # Streaming I/O (exec, attach, port-forward)
├── nri/              # NRI integration on the CRI side
├── opts/             # Container/sandbox option helpers
├── server/           # The CRI gRPC server: one big package, ~150 files
│   ├── service.go
│   ├── container_create.go / start / stop / list / status / ...
│   ├── sandbox_run.go / list / status / stop / portforward / ...
│   ├── streaming.go         # exec/attach/portforward streaming server
│   ├── cni_conf_syncer.go   # watches /etc/cni/net.d for changes
│   ├── stats_collector.go   # background metrics collection
│   ├── images/              # ImageService implementation
│   └── podsandbox/          # The pause-container sandbox controller
├── seutil/           # SELinux helpers
├── sputil/           # Spec utilities (build OCI runtime spec from a CRI request)
├── store/            # In-memory caches over the bbolt metadata
├── systemd/          # Property propagation into systemd-managed cgroups
├── testing/          # Test fakes
└── util/             # Various helpers

plugins/cri/
├── images/           # The CRI Image service plugin registration
└── runtime/          # The CRI Runtime service plugin registration

Key abstractions

Type File Purpose
criService internal/cri/server/service.go The struct that aggregates everything; satisfies RuntimeServiceServer and shares dependencies
criImageService internal/cri/server/images/service.go ImageServiceServer implementation
containerStore / sandboxStore internal/cri/store/ In-memory shadow over the bbolt records, indexed by short id, name, etc.
streamServer internal/cri/server/streaming.go Implements CRI's exec/attach/port-forward over the apiserver-streaming protocol
cniConfSyncer internal/cri/server/cni_conf_syncer.go Watches /etc/cni/net.d and reloads CNI

How a pod is launched

sequenceDiagram
    autonumber
    participant Kubelet
    participant CRI as CRI service
    participant Sandbox as podsandbox.Controller
    participant Image as Image service
    participant Container as containerd Tasks

    Kubelet->>CRI: RunPodSandbox(podCfg)
    CRI->>Sandbox: Create + Start (pause container)
    Sandbox-->>CRI: netns, pid, ip
    Kubelet->>CRI: PullImage(spec)
    CRI->>Image: Pull (transfer service)
    Image-->>CRI: image refs
    Kubelet->>CRI: CreateContainer(podID, container)
    CRI->>Container: client.NewContainer + tasks.Create (join sandbox netns)
    Kubelet->>CRI: StartContainer
    CRI->>Container: tasks.Start
    Container-->>CRI: TaskStart event
    CRI-->>Kubelet: status

The runtime-spec for each container is assembled in internal/cri/server/container_create*.go (Linux/Windows variants). Spec opts are pulled from internal/cri/opts/ and internal/cri/sputil/.

Configuration

The CRI plugin configures runtimes, snapshotter, registry mirrors, sandbox image, and CNI from [plugins."io.containerd.cri.v1.runtime"] and [plugins."io.containerd.cri.v1.images"] sections. The schema is in internal/cri/config/. Common fields:

[plugins."io.containerd.cri.v1.runtime"]
  default_runtime_name = "runc"

[plugins."io.containerd.cri.v1.runtime".containerd.runtimes.runc]
  runtime_type = "io.containerd.runc.v2"
  [plugins."io.containerd.cri.v1.runtime".containerd.runtimes.runc.options]
    SystemdCgroup = true

[plugins."io.containerd.cri.v1.images"]
  snapshotter = "overlayfs"
  [plugins."io.containerd.cri.v1.images".registry]
    config_path = "/etc/containerd/certs.d"

See docs/cri/config.md for the full schema.

CNI integration

The CRI plugin invokes CNI plugins (configured in /etc/cni/net.d/) via github.com/containernetworking/cni. The cni_conf_syncer reloads CNI on config changes; internal/cri/bandwidth/ enforces ingress/egress shaping when annotations request it.

Streaming

internal/cri/server/streaming.go implements an HTTP server that the kubelet redirects clients to for Exec, Attach, and PortForward. The CRI service returns a URL pointing at this server; the kubelet proxies from the kubectl client.

Entry points for modification

  • New CRI feature: extend internal/cri/server/. Many handlers split per-platform via _linux.go, _windows.go, _other.go files.
  • Different sandbox controller: register a new SandboxControllerPlugin. The CRI service picks the controller based on the runtime's sandboxer config.
  • New container option: add to internal/cri/opts/ and internal/cri/sputil/.
  • Test additions: internal/cri/server/*_test.go for unit tests, integration/ for full daemon tests.

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

CRI plugin – containerd wiki | Factory