CubeShim vs containerd-shim-runc-v2

Both CubeShim (containerd-shim-cube-rs) and containerd-shim-runc-v2 are containerd Shim v2 implementations. They behave identically from containerd’s point of view. They diverge in what sits behind the shim.

runc path

containerd → containerd-shim-runc-v2 → runc → runc exec → container process
                                         (fork/namespaces/cgroups)

One shim per container (or per pod). The shim supervises a runc binary, which fork(2)s into a namespaced, cgroup-scoped process. The shim stays resident after runc exits to manage stdio, signals, and status. Everything runs in the host kernel.

CubeShim path

containerd → containerd-shim-cube-rs → Cubelet (gRPC) → cube-hypervisor (HTTP)
                                    └→ cube-agent (ttrpc/vsock) ── inside VM ──►
                                                              rustjail → container

One shim per sandbox. The shim doesn’t fork the container; it asks Cubelet for a VM, waits for that VM to be ready, then talks to the in-VM agent over vsock. The agent runs rustjail inside the VM to actually launch the container process.

Where the models diverge

Process supervision

Stdio

Signals

Teardown

Snapshot path

FreeBSD implications

A FreeBSD port would replace the runc path wholesale — runc is Linux-OCI-specific — but could keep the Shim v2 structure. The interesting questions:

If the FreeBSD port keeps the microVM model, cube-agent stays inside the guest and rustjail stays OCI/Linux — because the guest is Linux. The host-side CubeShim then needs to talk to bhyve instead of cube-hypervisor, which is a swap of the CubeShim/shim/src/hypervisor/ client module, not a rewrite of the shim.