Skip to content

Commit

Permalink
containerd: add option to set parent cgroup
Browse files Browse the repository at this point in the history
Using the "runc.v2" runtime, it is possible to configure containerd to start
runc with the "systemd_cgroup" flag. This will cause runc to use systemd to
manage the container cgroups. For this configuration to work, runc needs the
cgroup name to be of a special form: "<systemd.slice>:<parent>:<name>".
This is already implemented in the containerd runtime package, provided that
a parent cgroup of the form "<systemd.slice>:<parent>:" is set.

This commit adds the option to configure such a parent cgroup for the
containerd worker. By default, it will still use an empty string as cgroup
parent, keeping existing behaviour.

Using a configuration like:

  [worker.containerd]
  defaultCgroupParent = "system.slice:buildkit:"
  [worker.containerd.runtime]
    name = "io.containerd.runc.v2"
    [worker.containerd.runtime.options]
      SystemdCgroup = true

a user is able to have their container cgroups managed by systemd. This makes
it possible to set global resource constraints on a per-container basis using
systemd drop-in configuration. When using the example above, the following file
restricts every container spawned by buildkit to use only 1 CPU and 1G of RAM:

  $ cat /etc/systemd/system/buildkit-.scope.d/limits.conf
  [Scope]
  CPUQuota=100%
  MemoryMax=1G

Signed-off-by: Moritz "WanzenBug" Wanzenböck <[email protected]>
  • Loading branch information
WanzenBug committed Jun 14, 2024
1 parent 313a611 commit 5cb8618
Show file tree
Hide file tree
Showing 5 changed files with 10 additions and 5 deletions.
2 changes: 2 additions & 0 deletions cmd/buildkitd/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ type ContainerdConfig struct {

MaxParallelism int `toml:"max-parallelism"`

DefaultCgroupParent string `toml:"defaultCgroupParent"`

Rootless bool `toml:"rootless"`
}

Expand Down
2 changes: 1 addition & 1 deletion cmd/buildkitd/main_containerd_worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ func containerdWorkerInitializer(c *cli.Context, common workerInitializerOpt) ([
Options: opts,
}
}
opt, err := containerd.NewWorkerOpt(common.config.Root, cfg.Address, snapshotter, cfg.Namespace, cfg.Rootless, cfg.Labels, dns, nc, common.config.Workers.Containerd.ApparmorProfile, common.config.Workers.Containerd.SELinux, parallelismSem, common.traceSocket, runtime, ctd.WithTimeout(60*time.Second))
opt, err := containerd.NewWorkerOpt(common.config.Root, cfg.Address, snapshotter, cfg.Namespace, cfg.DefaultCgroupParent, cfg.Rootless, cfg.Labels, dns, nc, common.config.Workers.Containerd.ApparmorProfile, common.config.Workers.Containerd.SELinux, parallelismSem, common.traceSocket, runtime, ctd.WithTimeout(60*time.Second))
if err != nil {
return nil, err
}
Expand Down
2 changes: 2 additions & 0 deletions docs/buildkitd.toml.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ insecure-entitlements = [ "network.host", "security.insecure" ]
# maintain a pool of reusable CNI network namespaces to amortize the overhead
# of allocating and releasing the namespaces
cniPoolSize = 16
# defaultCgroupParent sets the parent cgroup of all containers.
defaultCgroupParent = "buildkit"

[worker.containerd.labels]
"foo" = "bar"
Expand Down
7 changes: 4 additions & 3 deletions worker/containerd/containerd.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ type RuntimeInfo = containerdexecutor.RuntimeInfo
// NewWorkerOpt creates a WorkerOpt.
func NewWorkerOpt(
root string,
address, snapshotterName, ns string,
address, snapshotterName, ns, cgroupParent string,
rootless bool,
labels map[string]string,
dns *oci.DNSConfig,
Expand Down Expand Up @@ -62,6 +62,7 @@ func NewWorkerOpt(
client,
snapshotterName,
ns,
cgroupParent,
rootless,
labels,
dns,
Expand All @@ -74,7 +75,7 @@ func NewWorkerOpt(
)
}

func newContainerd(root string, client *containerd.Client, snapshotterName, ns string, rootless bool, labels map[string]string, dns *oci.DNSConfig, nopt netproviders.Opt, apparmorProfile string, selinux bool, parallelismSem *semaphore.Weighted, traceSocket string, runtime *RuntimeInfo) (base.WorkerOpt, error) {
func newContainerd(root string, client *containerd.Client, snapshotterName, ns, cgroupParent string, rootless bool, labels map[string]string, dns *oci.DNSConfig, nopt netproviders.Opt, apparmorProfile string, selinux bool, parallelismSem *semaphore.Weighted, traceSocket string, runtime *RuntimeInfo) (base.WorkerOpt, error) {
if strings.Contains(snapshotterName, "/") {
return base.WorkerOpt{}, errors.Errorf("bad snapshotter name: %q", snapshotterName)
}
Expand Down Expand Up @@ -176,7 +177,7 @@ func newContainerd(root string, client *containerd.Client, snapshotterName, ns s
Labels: xlabels,
MetadataStore: md,
NetworkProviders: np,
Executor: containerdexecutor.New(client, root, "", np, dns, apparmorProfile, selinux, traceSocket, rootless, runtime),
Executor: containerdexecutor.New(client, root, cgroupParent, np, dns, apparmorProfile, selinux, traceSocket, rootless, runtime),
Snapshotter: snap,
ContentStore: cs,
Applier: winlayers.NewFileSystemApplierWithWindows(cs, df),
Expand Down
2 changes: 1 addition & 1 deletion worker/containerd/containerd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func TestContainerdWorkerIntegration(t *testing.T) {
func newWorkerOpt(t *testing.T, addr string) base.WorkerOpt {
tmpdir := t.TempDir()
rootless := false
workerOpt, err := NewWorkerOpt(tmpdir, addr, "overlayfs", "buildkit-test", rootless, nil, nil, netproviders.Opt{Mode: "host"}, "", false, nil, "", nil)
workerOpt, err := NewWorkerOpt(tmpdir, addr, "overlayfs", "buildkit-test", "", rootless, nil, nil, netproviders.Opt{Mode: "host"}, "", false, nil, "", nil)
require.NoError(t, err)
return workerOpt
}
Expand Down

0 comments on commit 5cb8618

Please sign in to comment.