Add cpuset_cpus to docker driver.

This commit is contained in:
Shishir Mahajan 2020-06-25 09:30:16 -07:00
parent f1d53584bc
commit c30fea5cd3
4 changed files with 65 additions and 0 deletions

View file

@ -300,6 +300,7 @@ var (
"cap_add": hclspec.NewAttr("cap_add", "list(string)", false),
"cap_drop": hclspec.NewAttr("cap_drop", "list(string)", false),
"command": hclspec.NewAttr("command", "string", false),
"cpuset_cpus": hclspec.NewAttr("cpuset_cpus", "string", false),
"cpu_hard_limit": hclspec.NewAttr("cpu_hard_limit", "bool", false),
"cpu_cfs_period": hclspec.NewDefault(
hclspec.NewAttr("cpu_cfs_period", "number", false),
@ -407,6 +408,7 @@ type TaskConfig struct {
Command string `codec:"command"`
CPUCFSPeriod int64 `codec:"cpu_cfs_period"`
CPUHardLimit bool `codec:"cpu_hard_limit"`
CPUSetCPUs string `codec:"cpuset_cpus"`
Devices []DockerDevice `codec:"devices"`
DNSSearchDomains []string `codec:"dns_search_domains"`
DNSOptions []string `codec:"dns_options"`

View file

@ -823,6 +823,13 @@ func (d *Driver) createContainerConfig(task *drivers.TaskConfig, driverConfig *T
Runtime: containerRuntime,
}
// This translates to docker create/run --cpuset-cpus option.
// --cpuset-cpus limit the specific CPUs or cores a container can use.
if driverConfig.CPUSetCPUs != "" {
logger.Debug(fmt.Sprintf("Setting CPUSetCPUs to %s", driverConfig.CPUSetCPUs))
hostConfig.CPUSetCPUs = driverConfig.CPUSetCPUs
}
// Calculate CPU Quota
// cfs_quota_us is the time per core, so we must
// multiply the time by the number of cores available

View file

@ -1381,6 +1381,53 @@ func TestDockerDriver_DNS(t *testing.T) {
}
func TestDockerDriver_CPUSetCPUs(t *testing.T) {
if !tu.IsCI() {
t.Parallel()
}
testutil.DockerCompatible(t)
if runtime.GOOS == "windows" {
t.Skip("Windows does not support CPUSetCPUs.")
}
testCases := []struct {
Name string
CPUSetCPUs string
}{
{
Name: "Single CPU",
CPUSetCPUs: "0",
},
{
Name: "Comma separated list of CPUs",
CPUSetCPUs: "0,1,2",
},
{
Name: "Range of CPUs",
CPUSetCPUs: "0-3",
},
}
for _, testCase := range testCases {
t.Run(testCase.Name, func(t *testing.T) {
task, cfg, ports := dockerTask(t)
defer freeport.Return(ports)
cfg.CPUSetCPUs = testCase.CPUSetCPUs
require.NoError(t, task.EncodeConcreteDriverConfig(cfg))
client, d, handle, cleanup := dockerSetup(t, task, nil)
defer cleanup()
require.NoError(t, d.WaitUntilStarted(task.ID, 5*time.Second))
container, err := client.InspectContainer(handle.containerID)
require.NoError(t, err)
require.Equal(t, cfg.CPUSetCPUs, container.HostConfig.CPUSetCPUs)
})
}
}
func TestDockerDriver_MemoryHardLimit(t *testing.T) {
if !tu.IsCI() {
t.Parallel()

View file

@ -77,6 +77,15 @@ The `docker` driver supports the following configuration in the job spec. Only
command = "my-command"
}
```
- `cpuset_cpus` - (Optional) CPUs in which to allow execution (0-3, 0,1).
Limit the specific CPUs or cores a container can use. A comma-separated list or hyphen-separated range of CPUs a container can use, if you have more than one CPU. The first CPU is numbered 0. A valid value might be 0-3 (to use the first, second, third, and fourth CPU) or 1,3 (to use the second and fourth CPU).
```hcl
config {
cpuset_cpus = "0-3"
}
```
- `dns_search_domains` - (Optional) A list of DNS search domains for the container
to use.