Merge pull request #4462 from omame/omame/cpu_cfs_period

Add support for specifying cpu_cfs_period in the Docker driver
This commit is contained in:
Michael Schurter 2018-07-25 09:34:38 -07:00 committed by GitHub
commit ddf948001e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 44 additions and 6 deletions

View file

@ -235,6 +235,7 @@ type DockerDriverConfig struct {
ReadonlyRootfs bool `mapstructure:"readonly_rootfs"` // Mount the containers root filesystem as read only ReadonlyRootfs bool `mapstructure:"readonly_rootfs"` // Mount the containers root filesystem as read only
AdvertiseIPv6Address bool `mapstructure:"advertise_ipv6_address"` // Flag to use the GlobalIPv6Address from the container as the detected IP AdvertiseIPv6Address bool `mapstructure:"advertise_ipv6_address"` // Flag to use the GlobalIPv6Address from the container as the detected IP
CPUHardLimit bool `mapstructure:"cpu_hard_limit"` // Enforce CPU hard limit. CPUHardLimit bool `mapstructure:"cpu_hard_limit"` // Enforce CPU hard limit.
CPUCFSPeriod int64 `mapstructure:"cpu_cfs_period"` // Set the period for the CFS scheduler for the cgroup.
PidsLimit int64 `mapstructure:"pids_limit"` // Enforce Docker Pids limit PidsLimit int64 `mapstructure:"pids_limit"` // Enforce Docker Pids limit
} }
@ -741,6 +742,9 @@ func (d *DockerDriver) Validate(config map[string]interface{}) error {
"cpu_hard_limit": { "cpu_hard_limit": {
Type: fields.TypeBool, Type: fields.TypeBool,
}, },
"cpu_cfs_period": {
Type: fields.TypeInt,
},
"pids_limit": { "pids_limit": {
Type: fields.TypeInt, Type: fields.TypeInt,
}, },
@ -1238,7 +1242,14 @@ func (d *DockerDriver) createContainerConfig(ctx *ExecContext, task *structs.Tas
if driverConfig.CPUHardLimit { if driverConfig.CPUHardLimit {
numCores := runtime.NumCPU() numCores := runtime.NumCPU()
percentTicks := float64(task.Resources.CPU) / float64(d.node.Resources.CPU) percentTicks := float64(task.Resources.CPU) / float64(d.node.Resources.CPU)
hostConfig.CPUQuota = int64(percentTicks*defaultCFSPeriodUS) * int64(numCores) if driverConfig.CPUCFSPeriod < 0 || driverConfig.CPUCFSPeriod > 1000000 {
return c, fmt.Errorf("invalid value for cpu_cfs_period")
}
if driverConfig.CPUCFSPeriod == 0 {
driverConfig.CPUCFSPeriod = defaultCFSPeriodUS
}
hostConfig.CPUPeriod = driverConfig.CPUCFSPeriod
hostConfig.CPUQuota = int64(percentTicks*float64(driverConfig.CPUCFSPeriod)) * int64(numCores)
} }
// Windows does not support MemorySwap/MemorySwappiness #2193 // Windows does not support MemorySwap/MemorySwappiness #2193

View file

@ -2524,3 +2524,25 @@ func TestDockerImageRef(t *testing.T) {
}) })
} }
} }
func TestDockerDriver_CPUCFSPeriod(t *testing.T) {
if !tu.IsTravis() {
t.Parallel()
}
if !testutil.DockerIsConnected(t) {
t.Skip("Docker not connected")
}
task, _, _ := dockerTask(t)
task.Config["cpu_hard_limit"] = true
task.Config["cpu_cfs_period"] = 1000000
client, handle, cleanup := dockerSetup(t, task)
defer cleanup()
waitForExist(t, client, handle)
container, err := client.InspectContainer(handle.ContainerID())
assert.Nil(t, err, "Error inspecting container: %v", err)
assert.Equal(t, int64(1000000), container.HostConfig.CPUPeriod, "cpu_cfs_period option incorrectly set")
}

View file

@ -361,6 +361,11 @@ The `docker` driver supports the following configuration in the job spec. Only
soft limiting is used and containers are able to burst above their CPU limit soft limiting is used and containers are able to burst above their CPU limit
when there is idle capacity. when there is idle capacity.
* `cpu_cfs_period` - (Optional) An integer value that specifies the duration in microseconds of the period
during which the CPU usage quota is measured. The default is 100000 (0.1 second) and the maximum allowed
value is 1000000 (1 second). See [here](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/resource_management_guide/sec-cpu#sect-cfs)
for more details.
* `advertise_ipv6_address` - (Optional) `true` or `false` (default). Use the container's * `advertise_ipv6_address` - (Optional) `true` or `false` (default). Use the container's
IPv6 address (GlobalIPv6Address in Docker) when registering services and checks. IPv6 address (GlobalIPv6Address in Docker) when registering services and checks.
See [IPv6 Docker containers](/docs/job-specification/service.html#IPv6 Docker containers) for details. See [IPv6 Docker containers](/docs/job-specification/service.html#IPv6 Docker containers) for details.