Merge pull request #5570 from kolyshkin/cgroup-manager

Add --cgroup-manager, deprecate --systemd-cgroup
This commit is contained in:
Kir Kolyshkin authored and GitHub committed 2026-10-28 06:27:00 +00:00
commit 3b9ee72960
12 files changed
+76 -13

No files matched your search

+7
View File
@@ -12,11 +12,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
says, the destination is a path inside the container, and it is now used
as such. (#5556)
### Added ###
- New `--cgroup-manager` global option, to select the cgroup manager
(`cgroupfs` or `systemd`). This is compatible with crun. (#5570)
### Deprecated ###
- `libcontainer.Stats.Interfaces` and `types.Stats.NetworkInterfaces` (shown
as `network_interfaces` in `runc events --stats` output) are deprecated, as
they are always empty since the removal of veth network strategy in runc
1.0.0-rc6. (#5523)
- The `--systemd-cgroup` global option is deprecated in favor of
`--cgroup-manager=systemd`. It still works, and there are no plans to
remove it. (#5570)
### Changed ###
- A container configuration which uses `--no-pivot` or sets
+6
View File
@@ -228,6 +228,7 @@ _runc_runc() {
--systemd-cgroup
"
local options_with_args="
--cgroup-manager
--log
--log-format
--root
@@ -255,6 +256,11 @@ _runc_runc() {
return
;;
--cgroup-manager)
COMPREPLY=($(compgen -W 'cgroupfs systemd' -- "$cur"))
return
;;
$(__runc_to_extglob "$options_with_args"))
return
;;
+2 -2
View File
@@ -28,7 +28,7 @@ Kernel older than 5.2 is not recommended due to lack of freezer.
Notably, kernel older than 4.15 MUST NOT be used (unless you are running containers with user namespaces), as it lacks support for controlling permissions of devices.
### Systemd
On cgroup v2 hosts, it is highly recommended to run runc with the systemd cgroup driver (`runc --systemd-cgroup`), though not mandatory.
On cgroup v2 hosts, it is highly recommended to run runc with the systemd cgroup driver (`runc --cgroup-manager=systemd`), though not mandatory.
The recommended systemd version is 244 or later. Older systemd does not support delegation of `cpuset` controller.
@@ -45,7 +45,7 @@ On cgroup v2 hosts, rootless runc can talk to systemd to get cgroup permissions
```bash
runc spec --rootless
jq '.linux.cgroupsPath="user.slice:runc:foo"' config.json | sponge config.json
runc --systemd-cgroup run foo
runc --cgroup-manager=systemd run foo
```
The container processes are executed in a cgroup like `/user.slice/user-$(id -u).slice/user@$(id -u).service/user.slice/runc-foo.scope`.
+3 -3
View File
@@ -1,9 +1,9 @@
## systemd cgroup driver
By default, runc creates cgroups and sets cgroup limits on its own (this mode
is known as fs cgroup driver). When `--systemd-cgroup` global option is given
(as in e.g. `runc --systemd-cgroup run ...`), runc switches to systemd cgroup
driver. This document describes its features and peculiarities.
is known as fs cgroup driver). When `--cgroup-manager=systemd` global option is
given (as in e.g. `runc --cgroup-manager=systemd run ...`), runc switches to
systemd cgroup driver. This document describes its features and peculiarities.
### systemd unit name and placement
+9 -1
View File
@@ -123,9 +123,14 @@ func main() {
Value: root,
Usage: "root directory for storage of container state (this should be located in tmpfs)",
},
&cli.StringFlag{
Name: "cgroup-manager",
Value: "cgroupfs",
Usage: "cgroup manager to use ('cgroupfs' or 'systemd'); the latter expects cgroupsPath to be of form \"slice:prefix:name\" for e.g. \"system.slice:runc:434234\"",
},
&cli.BoolFlag{
Name: "systemd-cgroup",
Usage: "enable systemd cgroup support, expects cgroupsPath to be of form \"slice:prefix:name\" for e.g. \"system.slice:runc:434234\"",
Usage: "same as --cgroup-manager=systemd (deprecated)",
},
&cli.StringFlag{
Name: "rootless",
@@ -169,6 +174,9 @@ func main() {
if err := reviseRootDir(cmd); err != nil {
return ctx, err
}
if err := reviseCgroupManager(cmd); err != nil {
return ctx, err
}
if err := configLogrus(cmd); err != nil {
return ctx, err
+6 -3
View File
@@ -106,10 +106,13 @@ These options can be used with any command, and must precede the **command**.
located on tmpfs. Default is */run/runc*, or *$XDG_RUNTIME_DIR/runc* for
rootless containers.
**--cgroup-manager** **cgroupfs**|**systemd**
: Set the cgroup manager to use (default is **cgroupfs**). With **systemd**,
the container spec (_config.json_) is expected to have **cgroupsPath** value
in the *slice:prefix:name* form (e.g. **system.slice:runc:434234**).
**--systemd-cgroup**
: Enable systemd cgroup support. If this is set, the container spec
(_config.json_) is expected to have **cgroupsPath** value in the
*slice:prefix:name* form (e.g. **system.slice:runc:434234**).
: Same as **--cgroup-manager=systemd**. Deprecated.
**--rootless** **true**|**false**|**auto**
: Enable or disable rootless mode. Default is **auto**, meaning to auto-detect
+1 -1
View File
@@ -37,7 +37,7 @@ func shouldUseRootlessCgroupManager(cmd *cli.Command) (bool, error) {
//
// On error, we assume we are root. An error may happen during shelling out to `busctl` CLI,
// mostly when $DBUS_SESSION_BUS_ADDRESS is unset.
if cmd.Bool("systemd-cgroup") {
if cmd.String("cgroup-manager") == "systemd" {
ownerUID, err := systemd.DetectUID()
if err != nil {
logrus.WithError(err).Debug("failed to get the OwnerUID value, assuming the value to be 0")
+1 -1
View File
@@ -71,7 +71,7 @@ dnf clean all
# Setup rootless user.
"$SCRIPTDIR"/setup_rootless.sh
# Delegate all cgroup v2 controllers to rootless user via --systemd-cgroup
# Delegate all cgroup v2 controllers to rootless user via --cgroup-manager=systemd
if [ -e /sys/fs/cgroup/cgroup.controllers ]; then
mkdir -p /etc/systemd/system/user@.service.d
cat >/etc/systemd/system/user@.service.d/delegate.conf <<'EOF'
+1 -1
View File
@@ -11,7 +11,7 @@
set -u -e
opts=()
[ -v RUNC_USE_SYSTEMD ] && opts+=("--systemd-cgroup")
[ -v RUNC_USE_SYSTEMD ] && opts+=("--cgroup-manager=systemd")
[ -n "${ROOT:-}" ] && opts+=("--root" "$ROOT/state")
exec "$RUNC" "${opts[@]}" "$@"
+21
View File
@@ -15,6 +15,27 @@ function setup() {
run -0 runc run -d --console-socket "$CONSOLE_SOCKET" test_cgroups_permissions
}
@test "runc --cgroup-manager with an invalid value fails" {
run -1 runc --cgroup-manager=foo list
assert_output --partial 'invalid --cgroup-manager value'
}
@test "runc --systemd-cgroup conflicts with --cgroup-manager=cgroupfs" {
run -1 runc --systemd-cgroup --cgroup-manager=cgroupfs list
assert_output --partial "--systemd-cgroup conflicts with --cgroup-manager=cgroupfs"
}
@test "runc --systemd-cgroup is the same as --cgroup-manager=systemd" {
requires systemd
[ $EUID -ne 0 ] && requires rootless_cgroup
set_cgroups_path
# Not using the runc wrapper, as it adds --cgroup-manager=systemd.
run -0 "$RUNC" --root "$ROOT/state" --systemd-cgroup run -d --console-socket "$CONSOLE_SOCKET" test_cgroups_systemd
check_systemd_value "ActiveState" "active"
}
@test "runc create (rootless + no limits + cgrouppath + no permission) fails with permission error" {
requires rootless rootless_no_cgroup
+18
View File
@@ -121,6 +121,24 @@ func reviseRootDir(cmd *cli.Command) error {
return cmd.Set("root", root)
}
// reviseCgroupManager checks the --cgroup-manager option argument, and
// converts the deprecated --systemd-cgroup option to --cgroup-manager=systemd.
func reviseCgroupManager(cmd *cli.Command) error {
manager := cmd.String("cgroup-manager")
switch manager {
case "cgroupfs", "systemd":
default:
return fmt.Errorf("invalid --cgroup-manager value %q (must be 'cgroupfs' or 'systemd')", manager)
}
if !cmd.Bool("systemd-cgroup") {
return nil
}
if cmd.IsSet("cgroup-manager") && manager != "systemd" {
return fmt.Errorf("--systemd-cgroup conflicts with --cgroup-manager=%s", manager)
}
return cmd.Set("cgroup-manager", "systemd")
}
// parseBoolOrAuto returns (nil, nil) if s is empty or "auto"
func parseBoolOrAuto(s string) (*bool, error) {
if s == "" || strings.ToLower(s) == "auto" {
+1 -1
View File
@@ -188,7 +188,7 @@ func createContainer(cmd *cli.Command, id string, spec *specs.Spec) (*libcontain
}
config, err := specconv.CreateLibcontainerConfig(&specconv.CreateOpts{
CgroupName: id,
UseSystemdCgroup: cmd.Bool("systemd-cgroup"),
UseSystemdCgroup: cmd.String("cgroup-manager") == "systemd",
NoPivotRoot: cmd.Bool("no-pivot"),
NoNewKeyring: cmd.Bool("no-new-keyring"),
Spec: spec,