Skip to content

Week 6 - CRI: kubelet ↔ Runtime

6.1 Conceptual Core

  • The kubelet does not run containers itself; it talks gRPC to a CRI implementation (containerd, CRI-O). The CRI provides RuntimeService (containers + sandboxes) and ImageService (pull/list/remove).
  • Every Pod is a sandbox (a network namespace + the "pause" container) plus N containers sharing it.

6.2 Mechanical Detail

  • The CRI proto: cri-api/pkg/apis/runtime/v1/api.proto. The most relevant calls: RunPodSandbox, CreateContainer, StartContainer, StopContainer, RemovePodSandbox, Exec, Attach, PortForward, PullImage.
  • The pause container is a tiny binary (it just calls pause(2)); it holds open the network namespace so the application containers can come and go.
  • crictl is the CLI for talking to a CRI directly. crictl ps, crictl inspect, crictl exec. Different from `kubectl - talks straight to kubelet's runtime, bypassing the API server.
  • Runtime classes: RuntimeClass objects bind a name (gvisor, kata) to a runtime handler. Pods reference via spec.runtimeClassName.

6.3 Lab-"CRI Direct"

  1. From a node, crictl pull alpine; crictl runp pod-config.json; crictl create <pod-id> ctr-config.json img-config.json; crictl start <ctr-id>. You've launched a pod-equivalent without the apiserver.
  2. Compare with kubectl deploying the same: trace each CRI call in the kubelet log.
  3. Configure containerd with multiple runtimes (runc + runsc); register both as RuntimeClasses; deploy Pods against each.

6.4 Hardening Drill

  • Configure containerd to default to a non-root user, drop default capabilities, apply default seccomp. The same hardening from the Container curriculum, applied at the daemon level.

6.5 Operations Slice

  • Monitor container_runtime_* metrics from cAdvisor (built into kubelet). Alert on container-restart rate spikes.

Comments