Skip to content

Commit

Permalink
driver: set cpuset when using cgroups v2
Browse files Browse the repository at this point in the history
This PR makes it so that the Podman driver will now respect the task
config resources.cores value. When set, the task will be assigned the
specified number of CPU cores to be allowed to run on.

Note: unlike the docker/exec drivers, podman tasks will not be also allowed
to make use of the "shared" set of cpu cores (ones that have not yet been
reserved specifically for a task). Most likely that feature will be removed
in the near future (~Nomad 1.7) anyway.
  • Loading branch information
shoenig committed Jun 12, 2023
1 parent e789604 commit c88697c
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 2 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ this plugin to Nomad!
* Monitor the memory consumption
* Monitor CPU usage
* Task config cpu value is used to populate podman CpuShares
* Task config cores value is used to populate podman Cpuset
* Container log is forwarded to [Nomad logger](https://www.nomadproject.io/docs/commands/alloc/logs.html)
* Utilize podmans --init feature
* Set username or UID used for the specified command within the container (podman --user option).
Expand Down
9 changes: 7 additions & 2 deletions driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -525,7 +525,7 @@ func (d *Driver) StartTask(cfg *drivers.TaskConfig) (*drivers.TaskHandle, *drive
}

// Set the nomad slice as cgroup parent
d.setupCgroup(createOpts)
d.setupCgroup(&createOpts)

// Resources config options
createOpts.ContainerResourceConfig.ResourceLimits = &spec.LinuxResources{
Expand Down Expand Up @@ -769,7 +769,7 @@ func (d *Driver) StartTask(cfg *drivers.TaskConfig) (*drivers.TaskHandle, *drive
}

// setupCgroup customizes where the cgroup lives (v2 only)
func (d *Driver) setupCgroup(opts api.SpecGenerator) {
func (d *Driver) setupCgroup(opts *api.SpecGenerator) {
if d.cgroupV2 {
opts.ContainerCgroupConfig.CgroupParent = "nomad.slice"
}
Expand Down Expand Up @@ -804,6 +804,11 @@ func memoryLimits(r drivers.MemoryResources, reservation string) (hard, soft *in
}

func setCPUResources(cfg TaskConfig, systemResources *drivers.LinuxResources, taskCPU *spec.LinuxCPU) error {
// always assign cpuset
taskCPU.Cpus = systemResources.CpusetCpus

// only set bandwidth if hard limit is enabled
// currently only docker and podman drivers provide this ability
if !cfg.CPUHardLimit {
return nil
}
Expand Down
22 changes: 22 additions & 0 deletions driver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2123,6 +2123,28 @@ func createInspectImage(t *testing.T, image, reference string) {
must.Eq(t, idRef, idTest)
}

func Test_setTaskCpuset(t *testing.T) {
ci.Parallel(t)

t.Run("empty", func(t *testing.T) {
sysResources := &drivers.LinuxResources{CpusetCpus: ""}
taskCPU := new(spec.LinuxCPU)
cfg := TaskConfig{}
err := setCPUResources(cfg, sysResources, taskCPU)
must.NoError(t, err)
must.Eq(t, "", taskCPU.Cpus)
})

t.Run("non-empty", func(t *testing.T) {
sysResources := &drivers.LinuxResources{CpusetCpus: "2,5-8"}
taskCPU := new(spec.LinuxCPU)
cfg := TaskConfig{}
err := setCPUResources(cfg, sysResources, taskCPU)
must.NoError(t, err)
must.Eq(t, "2,5-8", taskCPU.Cpus)
})
}

func Test_cpuLimits(t *testing.T) {
ci.Parallel(t)

Expand Down

0 comments on commit c88697c

Please sign in to comment.