A sandbox shim may exit as soon as it has shut its sandbox down, before
containerd reads the ShutdownSandbox response, in which case the client
sees ttrpc.ErrClosed. The task Shutdown RPC has the same race and
shimTask.Shutdown treats a closed connection as a successful shutdown;
controllerLocal.Shutdown returned it as an error instead, failing
RemovePodSandbox for a sandbox that was already gone.
Signed-off-by: Maksym Pavlenko <pavlenko.maksym@gmail.com>
critest.sh takes SANDBOXER, the sandbox controller of the runtime handler
(podsandbox by default; shim adds disable_pause_image_pull, since a
Sandbox API shim needs no pause image). The Linux integration job runs the
critest suite a second time on the runc.v2 legs, with TEST_RUNTIME_PATH
pointing at containerd-shim-sandboxed-runc-v2 and the shim sandboxer. The
one spec that needs a shared pod PID namespace is skipped by name until
that lands; the user namespace specs skip themselves, since the handler
does not advertise user namespaces.
Signed-off-by: Maksym Pavlenko <pavlenko.maksym@gmail.com>
An experimental runc shim that implements the Sandbox API itself, so
that a pod needs no pause container and no pause image. It serves the
io.containerd.runc.v2 runtime type from a separate binary; a runtime
handler selects it with runtime_path and pairs it with the shim
sandboxer:
[plugins."io.containerd.cri.v1.runtime".containerd.runtimes.runc]
runtime_type = "io.containerd.runc.v2"
runtime_path = "/usr/local/bin/containerd-shim-sandboxed-runc-v2"
sandboxer = "shim"
disable_pause_image_pull = true
The shim is the sandbox. On CreateSandbox a locked thread enters the
network namespace CRI created, unshares the pod IPC and UTS namespaces,
sets the hostname and the pod sysctls from inside them, bind-mounts its
namespace files under the bundle and moves back out; the pins keep the
namespaces alive the way CRI keeps the network namespace alive. The shim
writes the pod shared files and mounts the shm tmpfs under its bundle and
returns them as mounts of the sandbox spec, together with the namespace
paths. StartSandbox reports pid 0. The containers of the pod run through
the task service of containerd-shim-runc-v2, wrapped only so that the
task Shutdown RPC, which containerd sends after every task deletion, does
not end the shim while the pod is alive. StopSandbox and "shim delete"
detach the pins and the shm and remove the files without relying on any
state; ShutdownSandbox ends the shim. The runtime info is the runc shim's
minus the user namespace, which the shim does not support yet.
Not supported yet: a shared pod PID namespace (the containers of such a
pod get their own PID namespaces, with a warning), user namespaces,
user.* sysctls, SELinux labels, cgroup v1 and rootless containerd. The
shim decodes the CRI PodSandboxConfig it receives as options; a
containerd owned configuration message is left as a TODO. The binary is
built and installed with the other Linux commands.
Signed-off-by: Maksym Pavlenko <pavlenko.maksym@gmail.com>
A sandbox controller that reports pid 0 has no process whose
/proc/<pid>/ns entries a container could join and no pause container
whose shared files CRI created. Such a sandbox describes what it holds in
the spec it returns on start.
When the sandbox status reports pid 0, load that spec from the sandbox
store and use it in two places. The pod namespaces come from its
Linux.Namespaces: a namespace listed there is joined by path, one that is
missing is the host namespace when the pod asked for it and an error
otherwise, and a PID namespace entry without a path declares that each
container gets its own. The pod shared files (/etc/hostname, /etc/hosts,
/etc/resolv.conf, /dev/shm) are bind-mounted from the spec mount sources
when nothing exists at the fixed CRI paths, which keep precedence.
Sandboxes with a pid keep the pid derived construction unchanged, and so
do Sandbox API shims that report pid 0 without a Linux section in their
spec, so existing shims see no change.
Signed-off-by: Maksym Pavlenko <pavlenko.maksym@gmail.com>
WithPodNamespaces derives the namespaces a container joins from the pid
of the sandbox process. A sandbox without a process has to name the
namespaces it holds instead.
WithPodNamespacePaths takes the paths explicitly. The network, IPC and
UTS namespaces of a container are always those of its pod, whatever the
container config says, exactly as they were with pause; the pod's
namespace options decide which of them are host namespaces. Every
namespace the pod shares must have a path: a missing one is an error,
never a fallback to a fresh or host namespace, unless the pod asked for
the host namespace, in which case the entry is removed from the spec. A
sandbox may declare that it holds no PID namespace and that each
container gets its own. WithPodNamespaces delegates to it with the pid
derived paths, so pause based pods produce the same specs as before.
Signed-off-by: Maksym Pavlenko <pavlenko.maksym@gmail.com>
The files a pod shares with its containers (hostname, hosts, resolv.conf,
the shm tmpfs) are produced by the podsandbox controller from the pod
config. A sandbox implementation outside the CRI server, such as a
Sandbox API shim, has to produce the same files. Put the pure helpers
(file and mount path constants, hostname and resolv.conf content, the shm
mount data) in a leaf package with no CRI server dependencies so that
both can use them. podsandbox is left unchanged for now.
Signed-off-by: Maksym Pavlenko <pavlenko.maksym@gmail.com>
controllerLocal.Metrics returned the shim's gRPC status error as is,
unlike every other method of the controller. CRI's pod stats listing
tolerates NotFound and Unavailable from a controller but never matched a
status error, so one sandbox whose shim could not report metrics failed
ListPodSandboxStats for every pod on the node.
Signed-off-by: Maksym Pavlenko <pavlenko.maksym@gmail.com>
A runtime handler can name its shim binary with runtime_path. The task
service replaces the runtime name with that path and the podsandbox
controller passes it to the pause task, but the shim sandboxer never saw
it: CRI stored only the runtime type in the sandbox record and the shim
controller started the binary resolved from that type.
Add a RuntimePath create option to the sandbox controller, have the shim
controller start that binary when it is set (the shim manager already
accepts an absolute path in place of a runtime name), and pass it from
CRI. The gRPC proxy cannot carry it, since ControllerCreateRequest has no
field for it, so a remote sandboxer logs a warning instead.
Signed-off-by: Maksym Pavlenko <pavlenko.maksym@gmail.com>
The previous wording was confusing, at least to Claude Opus 5.5,
which said:
At least one maintained branch will still support
it [cgroup v1] after that [May 2029]
Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
Install the pinned release of containerd-runc-shim with cargo install
instead of building the tip of rust-extensions' main, so the Rust legs
run a known shim that does not change underneath the PR. The build no
longer runs inside rust-extensions, whose rust-toolchain.toml used to
pick the toolchain, so pin one here instead.
Building the shim takes a minute or two per Rust leg, and its inputs
are fixed by the pinned crate version, toolchain and runner image, so
keep the installed binary in the actions cache keyed on those and only
run cargo install, and install the toolchain, when it is missing.
CRI only types runtime options for io.containerd.runc.v2, so the Rust
shim got generic options and SystemdCgroup never reached it. Configure
it as the runc runtime's binary through runtime_path instead.
Signed-off-by: Maksym Pavlenko <pavlenko.maksym@gmail.com>
CRI owns the pod SELinux label, so a label returned by the sandbox
controller is ignored. Log a warning when it differs from the one CRI
allocated.
Signed-off-by: Maksym Pavlenko <pavlenko.maksym@gmail.com>
The Rust shim now sets up a PTY's stdin without blocking, so
TestContainerPTY runs again. The CRI suite had no way to leave tests
out; it takes a SKIP pattern now, like FOCUS, and the Rust legs use it
for the user namespace tests, which need idmapped mounts the shim does
not do yet. The checkpoint disable script is skipped for the Rust shim
as well: it has no Checkpoint RPC, so the script's second case, a
checkpoint that must succeed with enable_criu unset, cannot pass with
it. Its integration legs already run with -no-criu.
Signed-off-by: Maksym Pavlenko <pavlenko.maksym@gmail.com>
This reverts commit f078cebbd1.
Propagating State deadline errors causes Get to fail and List to omit
tasks when a shim is temporarily unresponsive, such as during slow
cleanup in Delete. A timeout does not mean the task no longer exists,
and omitting it makes container lifecycle management harder for clients
and CRI.
Restore the previous behavior of returning UNKNOWN on State timeouts,
so tasks remain visible and callers can reconcile their state.
Refs: https://github.com/containerd/containerd/pull/14380#pullrequestreview-5689176711
Signed-off-by: Wei Fu <fuweid89@gmail.com>
The runsc job runs on ubuntu-latest, which is moving to Ubuntu 26.04,
whose sudo (sudo-rs) does not support -E ("preserving the entire
environment is not supported, '-E' is ignored"). critest.sh then fails
on the unset TEST_RUNTIME, the only variable the step did not pass
explicitly.
Pass it on the sudo command line with the others and drop -E.
Signed-off-by: Maksym Pavlenko <pavlenko.maksym@gmail.com>
The `urfave_cli_no_docs` build tag was removed in urfave/cli v3, with doc
generation moved to a separate module.
Remove the obsolete tag and the special handling for gen-manpages, which is
no longer needed after the migration to v3.
updates f72829f36b.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Add the `grpcnotrace` build tag to exclude gRPC's legacy tracing integration
and reduce binary sizes.
This reduces the size of containerd by ~272 KiB, containerd-stress by ~448 KiB,
and ctr by ~512 KiB, saving ~1.2 MiB overall.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
The test tarball from test/build.sh is built on the kubekins image and
run on other distros. A dynamic runc built on Debian trixie needs
GLIBC_2.38 and fails on AL2023 (kubernetes/kubernetes#142987).
Build with `make static` like the runc release binaries. EL has no
libseccomp-static, so the Fedora/EL VMs keep the dynamic build via
RUNC_DYNAMIC=1.
Signed-off-by: Davanum Srinivas <davanum@gmail.com>
Only the Windows listener and dialer take the unix:// scheme.
Assisted-by: OpenCode (claude-sonnet-5-5)
Signed-off-by: Eric Curtin <eric.curtin@docker.com>