google / google/gvisor

Sandboxed cgroupfs only exposes cgroup v1 on a cgroup v2 host

Open
#13,007 7 comments 0 reactions 1 assignee Claimed by @shailend-g View on GitHub
Dominant language
Go
Stars
19.3k
Forks
2k
Avg merge
3d 5h
Merged PRs (30d)
264

Description

### Description

On a host running the unified cgroup v2 hierarchy (`systemd.unified_cgroup_hierarchy=1`, `/sys/fs/cgroup` mounted as `cgroup2fs`), a container started with `runsc` still sees a cgroup **v1** layout inside the sandbox. Applications that probe for v2 by checking `/sys/fs/cgroup/cgroup.controllers` fall back to (or break on) v1 code paths.

From inside a `runtimeClassName: gvisor` pod:

```
irb(main):001> File.exist?("/sys/fs/cgroup/cgroup.controllers")
=> false
irb(main):002> File.read("/sys/fs/cgroup/memory/memory.usage_in_bytes")
=> "69672960\n"
```

### Expected

On a v2 host, the sentry's cgroupfs should expose the unified hierarchy (`/sys/fs/cgroup` as `cgroup2fs`, with `cgroup.controllers`, `cgroup.subtree_control`, `memory.max`, `cpu.max`, etc.), matching what the guest would see under `runc` on the same host. Alternatively, provide a runsc/runtime config knob to opt into v2 inside the sandbox.

### Actual

The sentry's synthetic cgroupfs (`pkg/sentry/fsimpl/cgroupfs`) is v1-only, so containers always see per-controller legacy mounts regardless of the host mode. This is independent of `--systemd-cgroup`, which correctly drives the host-side v2 placement.

### Impact

- Language runtimes and libraries that gate on `cgroup.controllers` (container-aware JDK 15+, recent Go runtime memory limits, `libcgroup`, cadvisor-style probes, ruby/python cgroup helpers) fall back to v1 paths, which in some cases are missing or report different semantics.
- `systemd` inside a container boots in legacy mode.
- Node-local container introspection tools that assume the host's cgroup mode is mirrored inside the sandbox give incorrect results.

### Environment

- runsc: `release-20260316.0` (plus local patches for #12686 and #12688; issue reproduces identically on stock releases)
- Host: Ubuntu 22.04, kernel 6.x, EKS worker, cgroup v2 unified (`stat -fc %T /sys/fs/cgroup` → `cgroup2fs`)
- Kubernetes 1.34 / containerd 2.x, runtime class `gvisor` → `runsc`
- `runsc.toml`: `net-raw = "true"`, `systemd-cgroup = "true"`

### Reproduce

1. Boot a host with `systemd.unified_cgroup_hierarchy=1` (Ubuntu 22.04 default, or verify with `stat -fc %T /sys/fs/cgroup` → `cgroup2fs`).
2. Install `runsc` and register it with containerd (`io.containerd.runsc.v1`).
3. Run any container with `runtimeClassName: gvisor`:
```
$ ls /sys/fs/cgroup/cgroup.controllers 2>&1
ls: cannot access '/sys/fs/cgroup/cgroup.controllers': No such file or directory
$ stat -fc %T /sys/fs/cgroup
tmpfs
$ cat /sys/fs/cgroup/memory/memory.usage_in_bytes
69672960
```
4. Same container under `runc` shows `cgroup2fs` with `cgroup.controllers` populated.

### Related

- #3481 (host-side v2 support — resolved; this is the in-sandbox counterpart)
- #9580 (v2 + systemd limit detection on the host)

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.