1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Merge pull request #23430 from erikstmartin/realtime-threads

Implementing support for --cpu-rt-period and --cpu-rt-runtime
This commit is contained in:
Vincent Demeester 2016-10-27 00:22:06 +02:00 committed by GitHub
commit 80d6d2e129
25 changed files with 404 additions and 115 deletions

View file

@ -243,8 +243,10 @@ type Resources struct {
BlkioDeviceWriteBps []*blkiodev.ThrottleDevice BlkioDeviceWriteBps []*blkiodev.ThrottleDevice
BlkioDeviceReadIOps []*blkiodev.ThrottleDevice BlkioDeviceReadIOps []*blkiodev.ThrottleDevice
BlkioDeviceWriteIOps []*blkiodev.ThrottleDevice BlkioDeviceWriteIOps []*blkiodev.ThrottleDevice
CPUPeriod int64 `json:"CpuPeriod"` // CPU CFS (Completely Fair Scheduler) period CPUPeriod int64 `json:"CpuPeriod"` // CPU CFS (Completely Fair Scheduler) period
CPUQuota int64 `json:"CpuQuota"` // CPU CFS (Completely Fair Scheduler) quota CPUQuota int64 `json:"CpuQuota"` // CPU CFS (Completely Fair Scheduler) quota
CPURealtimePeriod int64 `json:"CpuRealtimePeriod"` // CPU real-time period
CPURealtimeRuntime int64 `json:"CpuRealtimeRuntime"` // CPU real-time runtime
CpusetCpus string // CpusetCpus 0-2, 0,1 CpusetCpus string // CpusetCpus 0-2, 0,1
CpusetMems string // CpusetMems 0-2, 0,1 CpusetMems string // CpusetMems 0-2, 0,1
Devices []DeviceMapping // List of devices to map inside the container Devices []DeviceMapping // List of devices to map inside the container

View file

@ -15,17 +15,19 @@ import (
) )
type updateOptions struct { type updateOptions struct {
blkioWeight uint16 blkioWeight uint16
cpuPeriod int64 cpuPeriod int64
cpuQuota int64 cpuQuota int64
cpusetCpus string cpuRealtimePeriod int64
cpusetMems string cpuRealtimeRuntime int64
cpuShares int64 cpusetCpus string
memoryString string cpusetMems string
memoryReservation string cpuShares int64
memorySwap string memoryString string
kernelMemory string memoryReservation string
restartPolicy string memorySwap string
kernelMemory string
restartPolicy string
nFlag int nFlag int
@ -51,6 +53,8 @@ func NewUpdateCommand(dockerCli *command.DockerCli) *cobra.Command {
flags.Uint16Var(&opts.blkioWeight, "blkio-weight", 0, "Block IO (relative weight), between 10 and 1000") flags.Uint16Var(&opts.blkioWeight, "blkio-weight", 0, "Block IO (relative weight), between 10 and 1000")
flags.Int64Var(&opts.cpuPeriod, "cpu-period", 0, "Limit CPU CFS (Completely Fair Scheduler) period") flags.Int64Var(&opts.cpuPeriod, "cpu-period", 0, "Limit CPU CFS (Completely Fair Scheduler) period")
flags.Int64Var(&opts.cpuQuota, "cpu-quota", 0, "Limit CPU CFS (Completely Fair Scheduler) quota") flags.Int64Var(&opts.cpuQuota, "cpu-quota", 0, "Limit CPU CFS (Completely Fair Scheduler) quota")
flags.Int64Var(&opts.cpuRealtimePeriod, "cpu-rt-period", 0, "Limit the CPU real-time period in microseconds")
flags.Int64Var(&opts.cpuRealtimeRuntime, "cpu-rt-runtime", 0, "Limit the CPU real-time runtime in microseconds")
flags.StringVar(&opts.cpusetCpus, "cpuset-cpus", "", "CPUs in which to allow execution (0-3, 0,1)") flags.StringVar(&opts.cpusetCpus, "cpuset-cpus", "", "CPUs in which to allow execution (0-3, 0,1)")
flags.StringVar(&opts.cpusetMems, "cpuset-mems", "", "MEMs in which to allow execution (0-3, 0,1)") flags.StringVar(&opts.cpusetMems, "cpuset-mems", "", "MEMs in which to allow execution (0-3, 0,1)")
flags.Int64VarP(&opts.cpuShares, "cpu-shares", "c", 0, "CPU shares (relative weight)") flags.Int64VarP(&opts.cpuShares, "cpu-shares", "c", 0, "CPU shares (relative weight)")
@ -115,16 +119,18 @@ func runUpdate(dockerCli *command.DockerCli, opts *updateOptions) error {
} }
resources := containertypes.Resources{ resources := containertypes.Resources{
BlkioWeight: opts.blkioWeight, BlkioWeight: opts.blkioWeight,
CpusetCpus: opts.cpusetCpus, CpusetCpus: opts.cpusetCpus,
CpusetMems: opts.cpusetMems, CpusetMems: opts.cpusetMems,
CPUShares: opts.cpuShares, CPUShares: opts.cpuShares,
Memory: memory, Memory: memory,
MemoryReservation: memoryReservation, MemoryReservation: memoryReservation,
MemorySwap: memorySwap, MemorySwap: memorySwap,
KernelMemory: kernelMemory, KernelMemory: kernelMemory,
CPUPeriod: opts.cpuPeriod, CPUPeriod: opts.cpuPeriod,
CPUQuota: opts.cpuQuota, CPUQuota: opts.cpuQuota,
CPURealtimePeriod: opts.cpuRealtimePeriod,
CPURealtimeRuntime: opts.cpuRealtimeRuntime,
} }
updateConfig := containertypes.UpdateConfig{ updateConfig := containertypes.UpdateConfig{

View file

@ -1316,6 +1316,8 @@ _docker_container_run() {
--cidfile --cidfile
--cpu-period --cpu-period
--cpu-quota --cpu-quota
--cpu-rt-period
--cpu-rt-runtime
--cpuset-cpus --cpuset-cpus
--cpuset-mems --cpuset-mems
--cpu-shares -c --cpu-shares -c
@ -1667,6 +1669,8 @@ _docker_container_update() {
--blkio-weight --blkio-weight
--cpu-period --cpu-period
--cpu-quota --cpu-quota
--cpu-rt-period
--cpu-rt-runtime
--cpuset-cpus --cpuset-cpus
--cpuset-mems --cpuset-mems
--cpu-shares -c --cpu-shares -c

View file

@ -1433,6 +1433,8 @@ __docker_subcommand() {
"($help -c --cpu-shares)"{-c=,--cpu-shares=}"[CPU shares (relative weight)]:CPU shares:(0 10 100 200 500 800 1000)" "($help -c --cpu-shares)"{-c=,--cpu-shares=}"[CPU shares (relative weight)]:CPU shares:(0 10 100 200 500 800 1000)"
"($help)--cpu-period=[Limit the CPU CFS (Completely Fair Scheduler) period]:CPU period: " "($help)--cpu-period=[Limit the CPU CFS (Completely Fair Scheduler) period]:CPU period: "
"($help)--cpu-quota=[Limit the CPU CFS (Completely Fair Scheduler) quota]:CPU quota: " "($help)--cpu-quota=[Limit the CPU CFS (Completely Fair Scheduler) quota]:CPU quota: "
"($help)--cpu-rt-period=[Limit the CPU real-time period]:CPU real-time period in microseconds: "
"($help)--cpu-rt-runtime=[Limit the CPU real-time runtime]:CPU real-time runtime in microseconds: "
"($help)--cpuset-cpus=[CPUs in which to allow execution]:CPUs: " "($help)--cpuset-cpus=[CPUs in which to allow execution]:CPUs: "
"($help)--cpuset-mems=[MEMs in which to allow execution]:MEMs: " "($help)--cpuset-mems=[MEMs in which to allow execution]:MEMs: "
"($help -m --memory)"{-m=,--memory=}"[Memory limit]:Memory limit: " "($help -m --memory)"{-m=,--memory=}"[Memory limit]:Memory limit: "

View file

@ -34,6 +34,8 @@ type Config struct {
Ulimits map[string]*units.Ulimit `json:"default-ulimits,omitempty"` Ulimits map[string]*units.Ulimit `json:"default-ulimits,omitempty"`
Runtimes map[string]types.Runtime `json:"runtimes,omitempty"` Runtimes map[string]types.Runtime `json:"runtimes,omitempty"`
DefaultRuntime string `json:"default-runtime,omitempty"` DefaultRuntime string `json:"default-runtime,omitempty"`
CPURealtimePeriod int64 `json:"cpu-rt-period,omitempty"`
CPURealtimeRuntime int64 `json:"cpu-rt-runtime,omitempty"`
OOMScoreAdjust int `json:"oom-score-adjust,omitempty"` OOMScoreAdjust int `json:"oom-score-adjust,omitempty"`
Init bool `json:"init,omitempty"` Init bool `json:"init,omitempty"`
InitPath string `json:"init-path,omitempty"` InitPath string `json:"init-path,omitempty"`
@ -97,6 +99,8 @@ func (config *Config) InstallFlags(flags *pflag.FlagSet) {
flags.IntVar(&config.OOMScoreAdjust, "oom-score-adjust", -500, "Set the oom_score_adj for the daemon") flags.IntVar(&config.OOMScoreAdjust, "oom-score-adjust", -500, "Set the oom_score_adj for the daemon")
flags.BoolVar(&config.Init, "init", false, "Run an init in the container to forward signals and reap processes") flags.BoolVar(&config.Init, "init", false, "Run an init in the container to forward signals and reap processes")
flags.StringVar(&config.InitPath, "init-path", "", "Path to the docker-init binary") flags.StringVar(&config.InitPath, "init-path", "", "Path to the docker-init binary")
flags.Int64Var(&config.CPURealtimePeriod, "cpu-rt-period", 0, "Limit the CPU real-time period in microseconds")
flags.Int64Var(&config.CPURealtimeRuntime, "cpu-rt-runtime", 0, "Limit the CPU real-time runtime in microseconds")
config.attachExperimentalFlags(flags) config.attachExperimentalFlags(flags)
} }

View file

@ -36,10 +36,11 @@ import (
"github.com/docker/libnetwork/options" "github.com/docker/libnetwork/options"
lntypes "github.com/docker/libnetwork/types" lntypes "github.com/docker/libnetwork/types"
"github.com/golang/protobuf/ptypes" "github.com/golang/protobuf/ptypes"
"github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/label" "github.com/opencontainers/runc/libcontainer/label"
rsystem "github.com/opencontainers/runc/libcontainer/system" rsystem "github.com/opencontainers/runc/libcontainer/system"
"github.com/opencontainers/runc/libcontainer/user" "github.com/opencontainers/runc/libcontainer/user"
"github.com/opencontainers/runtime-spec/specs-go" specs "github.com/opencontainers/runtime-spec/specs-go"
"github.com/vishvananda/netlink" "github.com/vishvananda/netlink"
) )
@ -118,6 +119,16 @@ func getCPUResources(config containertypes.Resources) *specs.CPU {
cpu.Quota = &quota cpu.Quota = &quota
} }
if config.CPURealtimePeriod != 0 {
period := uint64(config.CPURealtimePeriod)
cpu.RealtimePeriod = &period
}
if config.CPURealtimeRuntime != 0 {
runtime := uint64(config.CPURealtimeRuntime)
cpu.RealtimeRuntime = &runtime
}
return &cpu return &cpu
} }
@ -1184,3 +1195,34 @@ func setupOOMScoreAdj(score int) error {
f.Close() f.Close()
return err return err
} }
func (daemon *Daemon) initCgroupsPath(path string) error {
if path == "/" || path == "." {
return nil
}
daemon.initCgroupsPath(filepath.Dir(path))
_, root, err := cgroups.FindCgroupMountpointAndRoot("cpu")
if err != nil {
return err
}
path = filepath.Join(root, path)
sysinfo := sysinfo.New(false)
if err := os.MkdirAll(path, 0755); err != nil && !os.IsExist(err) {
return err
}
if sysinfo.CPURealtimePeriod && daemon.configStore.CPURealtimePeriod != 0 {
if err := ioutil.WriteFile(filepath.Join(path, "cpu.rt_period_us"), []byte(strconv.FormatInt(daemon.configStore.CPURealtimePeriod, 10)), 0700); err != nil {
return err
}
}
if sysinfo.CPURealtimeRuntime && daemon.configStore.CPURealtimeRuntime != 0 {
if err := ioutil.WriteFile(filepath.Join(path, "cpu.rt_runtime_us"), []byte(strconv.FormatInt(daemon.configStore.CPURealtimeRuntime, 10)), 0700); err != nil {
return err
}
}
return nil
}

View file

@ -21,9 +21,10 @@ import (
"github.com/docker/docker/pkg/symlink" "github.com/docker/docker/pkg/symlink"
"github.com/docker/docker/volume" "github.com/docker/docker/volume"
"github.com/opencontainers/runc/libcontainer/apparmor" "github.com/opencontainers/runc/libcontainer/apparmor"
"github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/devices" "github.com/opencontainers/runc/libcontainer/devices"
"github.com/opencontainers/runc/libcontainer/user" "github.com/opencontainers/runc/libcontainer/user"
"github.com/opencontainers/runtime-spec/specs-go" specs "github.com/opencontainers/runtime-spec/specs-go"
) )
func setResources(s *specs.Spec, r containertypes.Resources) error { func setResources(s *specs.Spec, r containertypes.Resources) error {
@ -655,6 +656,29 @@ func (daemon *Daemon) createSpec(c *container.Container) (*specs.Spec, error) {
} }
s.Linux.Resources.OOMScoreAdj = &c.HostConfig.OomScoreAdj s.Linux.Resources.OOMScoreAdj = &c.HostConfig.OomScoreAdj
s.Linux.Sysctl = c.HostConfig.Sysctls s.Linux.Sysctl = c.HostConfig.Sysctls
p := *s.Linux.CgroupsPath
if useSystemd {
initPath, err := cgroups.GetInitCgroupDir("cpu")
if err != nil {
return nil, err
}
p, _ = cgroups.GetThisCgroupDir("cpu")
if err != nil {
return nil, err
}
p = filepath.Join(initPath, p)
}
// Clean path to guard against things like ../../../BAD
parentPath := filepath.Dir(p)
if !filepath.IsAbs(parentPath) {
parentPath = filepath.Clean("/" + parentPath)
}
if err := daemon.initCgroupsPath(parentPath); err != nil {
return nil, fmt.Errorf("linux init cgroups path: %v", err)
}
if err := setDevices(&s, c); err != nil { if err := setDevices(&s, c); err != nil {
return nil, fmt.Errorf("linux runtime spec devices: %v", err) return nil, fmt.Errorf("linux runtime spec devices: %v", err)
} }

View file

@ -160,6 +160,7 @@ This section lists each version from latest to oldest. Each listing includes a
* `POST /volumes/prune` prunes unused volumes. * `POST /volumes/prune` prunes unused volumes.
* `POST /networks/prune` prunes unused networks. * `POST /networks/prune` prunes unused networks.
* Every API response now includes a `Docker-Experimental` header specifying if experimental features are enabled (value can be `true` or `false`). * Every API response now includes a `Docker-Experimental` header specifying if experimental features are enabled (value can be `true` or `false`).
* The `hostConfig` option now accepts the fields `CpuRealtimePeriod` and `CpuRtRuntime` to allocate cpu runtime to rt tasks when `CONFIG_RT_GROUP_SCHED` is enabled in the kernel.
### v1.24 API changes ### v1.24 API changes

View file

@ -304,6 +304,8 @@ Create a container
"CpuPercent": 80, "CpuPercent": 80,
"CpuShares": 512, "CpuShares": 512,
"CpuPeriod": 100000, "CpuPeriod": 100000,
"CpuRealtimePeriod": 1000000,
"CpuRealtimeRuntime": 10000,
"CpuQuota": 50000, "CpuQuota": 50000,
"CpusetCpus": "0,1", "CpusetCpus": "0,1",
"CpusetMems": "0,1", "CpusetMems": "0,1",
@ -426,6 +428,8 @@ Create a container
- **CpuShares** - An integer value containing the container's CPU Shares - **CpuShares** - An integer value containing the container's CPU Shares
(ie. the relative weight vs other containers). (ie. the relative weight vs other containers).
- **CpuPeriod** - The length of a CPU period in microseconds. - **CpuPeriod** - The length of a CPU period in microseconds.
- **CpuRealtimePeriod** - The length of a CPU real-time period in microseconds (0=no time allocated for rt tasks)
- **CpuRealtimeRuntime** - The length of a CPU real-time runtime in microseconds (0=no time allocated for rt tasks)
- **CpuQuota** - Microseconds of CPU time that the container can get in a CPU period. - **CpuQuota** - Microseconds of CPU time that the container can get in a CPU period.
- **CpusetCpus** - String value containing the `cgroups CpusetCpus` to use. - **CpusetCpus** - String value containing the `cgroups CpusetCpus` to use.
- **CpusetMems** - Memory nodes (MEMs) in which to allow execution (0-3, 0,1). Only effective on NUMA systems. - **CpusetMems** - Memory nodes (MEMs) in which to allow execution (0-3, 0,1). Only effective on NUMA systems.
@ -615,6 +619,8 @@ Return low-level information on the container `id`
"CpuPercent": 80, "CpuPercent": 80,
"CpuShares": 0, "CpuShares": 0,
"CpuPeriod": 100000, "CpuPeriod": 100000,
"CpuRealtimePeriod": 1000000,
"CpuRealtimeRuntime": 10000,
"Devices": [], "Devices": [],
"Dns": null, "Dns": null,
"DnsOptions": null, "DnsOptions": null,
@ -1191,6 +1197,8 @@ Update configuration of one or more containers.
"BlkioWeight": 300, "BlkioWeight": 300,
"CpuShares": 512, "CpuShares": 512,
"CpuPeriod": 100000, "CpuPeriod": 100000,
"CpuRealtimePeriod": 1000000,
"CpuRealtimeRuntime": 10000,
"CpuQuota": 50000, "CpuQuota": 50000,
"CpusetCpus": "0,1", "CpusetCpus": "0,1",
"CpusetMems": "0", "CpusetMems": "0",

View file

@ -35,6 +35,8 @@ Options:
--cpu-period int Limit CPU CFS (Completely Fair Scheduler) period --cpu-period int Limit CPU CFS (Completely Fair Scheduler) period
--cpu-quota int Limit CPU CFS (Completely Fair Scheduler) quota --cpu-quota int Limit CPU CFS (Completely Fair Scheduler) quota
-c, --cpu-shares int CPU shares (relative weight) -c, --cpu-shares int CPU shares (relative weight)
--cpu-rt-period int Limit the CPU real-time period in microseconds
--cpu-rt-runtime int Limit the CPU real-time runtime in microseconds
--cpuset-cpus string CPUs in which to allow execution (0-3, 0,1) --cpuset-cpus string CPUs in which to allow execution (0-3, 0,1)
--cpuset-mems string MEMs in which to allow execution (0-3, 0,1) --cpuset-mems string MEMs in which to allow execution (0-3, 0,1)
--device value Add a host device to the container (default []) --device value Add a host device to the container (default [])

View file

@ -33,6 +33,8 @@ Options:
--cpu-period int Limit CPU CFS (Completely Fair Scheduler) period --cpu-period int Limit CPU CFS (Completely Fair Scheduler) period
--cpu-quota int Limit CPU CFS (Completely Fair Scheduler) quota --cpu-quota int Limit CPU CFS (Completely Fair Scheduler) quota
-c, --cpu-shares int CPU shares (relative weight) -c, --cpu-shares int CPU shares (relative weight)
--cpu-rt-period int Limit the CPU real-time period in microseconds
--cpu-rt-runtime int Limit the CPU real-time runtime in microseconds
--cpuset-cpus string CPUs in which to allow execution (0-3, 0,1) --cpuset-cpus string CPUs in which to allow execution (0-3, 0,1)
--cpuset-mems string MEMs in which to allow execution (0-3, 0,1) --cpuset-mems string MEMs in which to allow execution (0-3, 0,1)
-d, --detach Run container in background and print container ID -d, --detach Run container in background and print container ID

View file

@ -25,6 +25,8 @@ Options:
--cpu-period int Limit CPU CFS (Completely Fair Scheduler) period --cpu-period int Limit CPU CFS (Completely Fair Scheduler) period
--cpu-quota int Limit CPU CFS (Completely Fair Scheduler) quota --cpu-quota int Limit CPU CFS (Completely Fair Scheduler) quota
-c, --cpu-shares int CPU shares (relative weight) -c, --cpu-shares int CPU shares (relative weight)
--cpu-rt-period int Limit the CPU real-time period in microseconds
--cpu-rt-runtime int Limit the CPU real-time runtime in microseconds
--cpuset-cpus string CPUs in which to allow execution (0-3, 0,1) --cpuset-cpus string CPUs in which to allow execution (0-3, 0,1)
--cpuset-mems string MEMs in which to allow execution (0-3, 0,1) --cpuset-mems string MEMs in which to allow execution (0-3, 0,1)
--help Print usage --help Print usage

View file

@ -690,6 +690,8 @@ container:
| `--cpuset-cpus=""` | CPUs in which to allow execution (0-3, 0,1) | | `--cpuset-cpus=""` | CPUs in which to allow execution (0-3, 0,1) |
| `--cpuset-mems=""` | Memory nodes (MEMs) in which to allow execution (0-3, 0,1). Only effective on NUMA systems. | | `--cpuset-mems=""` | Memory nodes (MEMs) in which to allow execution (0-3, 0,1). Only effective on NUMA systems. |
| `--cpu-quota=0` | Limit the CPU CFS (Completely Fair Scheduler) quota | | `--cpu-quota=0` | Limit the CPU CFS (Completely Fair Scheduler) quota |
| `--cpu-rt-period=0` | Limit the CPU real-time period. In microseconds. Requires parent cgroups be set and cannot be higher than parent. Also check rtprio ulimits. |
| `--cpu-rt-runtime=0` | Limit the CPU real-time runtime. In microseconds. Requires parent cgroups be set and cannot be higher than parent. Also check rtprio ulimits. |
| `--blkio-weight=0` | Block IO weight (relative weight) accepts a weight value between 10 and 1000. | | `--blkio-weight=0` | Block IO weight (relative weight) accepts a weight value between 10 and 1000. |
| `--blkio-weight-device=""` | Block IO weight (relative device weight, format: `DEVICE_NAME:WEIGHT`) | | `--blkio-weight-device=""` | Block IO weight (relative device weight, format: `DEVICE_NAME:WEIGHT`) |
| `--device-read-bps=""` | Limit read rate from a device (format: `<device-path>:<number>[<unit>]`). Number is a positive integer. Unit can be one of `kb`, `mb`, or `gb`. | | `--device-read-bps=""` | Limit read rate from a device (format: `<device-path>:<number>[<unit>]`). Number is a positive integer. Unit can be one of `kb`, `mb`, or `gb`. |

View file

@ -17,6 +17,8 @@ docker-create - Create a new container
[**--cidfile**[=*CIDFILE*]] [**--cidfile**[=*CIDFILE*]]
[**--cpu-period**[=*0*]] [**--cpu-period**[=*0*]]
[**--cpu-quota**[=*0*]] [**--cpu-quota**[=*0*]]
[**--cpu-rt-period**[=*0*]]
[**--cpu-rt-runtime**[=*0*]]
[**--cpuset-cpus**[=*CPUSET-CPUS*]] [**--cpuset-cpus**[=*CPUSET-CPUS*]]
[**--cpuset-mems**[=*CPUSET-MEMS*]] [**--cpuset-mems**[=*CPUSET-MEMS*]]
[**--device**[=*[]*]] [**--device**[=*[]*]]
@ -123,6 +125,8 @@ The initial status of the container created with **docker create** is 'created'.
**--cpu-period**=*0* **--cpu-period**=*0*
Limit the CPU CFS (Completely Fair Scheduler) period Limit the CPU CFS (Completely Fair Scheduler) period
Limit the container's CPU usage. This flag tell the kernel to restrict the container's CPU usage to the period you specify.
**--cpuset-cpus**="" **--cpuset-cpus**=""
CPUs in which to allow execution (0-3, 0,1) CPUs in which to allow execution (0-3, 0,1)
@ -136,6 +140,19 @@ two memory nodes.
**--cpu-quota**=*0* **--cpu-quota**=*0*
Limit the CPU CFS (Completely Fair Scheduler) quota Limit the CPU CFS (Completely Fair Scheduler) quota
**--cpu-rt-period**=0
Limit the CPU real-time period in microseconds
Limit the container's Real Time CPU usage. This flag tell the kernel to restrict the container's Real Time CPU usage to the period you specify.
**--cpu-rt-runtime**=0
Limit the CPU real-time runtime in microseconds
Limit the containers Real Time CPU usage. This flag tells the kernel to limit the amount of time in a given CPU period Real Time tasks may consume. Ex:
Period of 1,000,000us and Runtime of 950,000us means that this container could consume 95% of available CPU and leave the remaining 5% to normal priority tasks.
The sum of all runtimes across containers cannot exceed the amount alotted to the parent cgroup.
**--device**=[] **--device**=[]
Add a host device to the container (e.g. --device=/dev/sdc:/dev/xvdc:rwm) Add a host device to the container (e.g. --device=/dev/sdc:/dev/xvdc:rwm)

View file

@ -17,6 +17,8 @@ docker-run - Run a command in a new container
[**--cidfile**[=*CIDFILE*]] [**--cidfile**[=*CIDFILE*]]
[**--cpu-period**[=*0*]] [**--cpu-period**[=*0*]]
[**--cpu-quota**[=*0*]] [**--cpu-quota**[=*0*]]
[**--cpu-rt-period**[=*0*]]
[**--cpu-rt-runtime**[=*0*]]
[**--cpuset-cpus**[=*CPUSET-CPUS*]] [**--cpuset-cpus**[=*CPUSET-CPUS*]]
[**--cpuset-mems**[=*CPUSET-MEMS*]] [**--cpuset-mems**[=*CPUSET-MEMS*]]
[**-d**|**--detach**] [**-d**|**--detach**]
@ -192,6 +194,19 @@ two memory nodes.
CPU resource. This flag tell the kernel to restrict the container's CPU usage CPU resource. This flag tell the kernel to restrict the container's CPU usage
to the quota you specify. to the quota you specify.
**--cpu-rt-period**=0
Limit the CPU real-time period in microseconds
Limit the container's Real Time CPU usage. This flag tell the kernel to restrict the container's Real Time CPU usage to the period you specify.
**--cpu-rt-runtime**=0
Limit the CPU real-time runtime in microseconds
Limit the containers Real Time CPU usage. This flag tells the kernel to limit the amount of time in a given CPU period Real Time tasks may consume. Ex:
Period of 1,000,000us and Runtime of 950,000us means that this container could consume 95% of available CPU and leave the remaining 5% to normal priority tasks.
The sum of all runtimes across containers cannot exceed the amount alotted to the parent cgroup.
**-d**, **--detach**=*true*|*false* **-d**, **--detach**=*true*|*false*
Detached mode: run the container in the background and print the new container ID. The default is *false*. Detached mode: run the container in the background and print the new container ID. The default is *false*.

View file

@ -10,6 +10,8 @@ docker-update - Update configuration of one or more containers
[**--cpu-shares**[=*0*]] [**--cpu-shares**[=*0*]]
[**--cpu-period**[=*0*]] [**--cpu-period**[=*0*]]
[**--cpu-quota**[=*0*]] [**--cpu-quota**[=*0*]]
[**--cpu-rt-period**[=*0*]]
[**--cpu-rt-runtime**[=*0*]]
[**--cpuset-cpus**[=*CPUSET-CPUS*]] [**--cpuset-cpus**[=*CPUSET-CPUS*]]
[**--cpuset-mems**[=*CPUSET-MEMS*]] [**--cpuset-mems**[=*CPUSET-MEMS*]]
[**--help**] [**--help**]
@ -44,9 +46,24 @@ a running container with kernel memory initialized.
**--cpu-period**=0 **--cpu-period**=0
Limit the CPU CFS (Completely Fair Scheduler) period Limit the CPU CFS (Completely Fair Scheduler) period
Limit the container's CPU usage. This flag tell the kernel to restrict the container's CPU usage to the period you specify.
**--cpu-quota**=0 **--cpu-quota**=0
Limit the CPU CFS (Completely Fair Scheduler) quota Limit the CPU CFS (Completely Fair Scheduler) quota
**--cpu-rt-period**=0
Limit the CPU real-time period in microseconds
Limit the container's Real Time CPU usage. This flag tell the kernel to restrict the container's Real Time CPU usage to the period you specify.
**--cpu-rt-runtime**=0
Limit the CPU real-time runtime in microseconds
Limit the containers Real Time CPU usage. This flag tells the kernel to limit the amount of time in a given CPU period Real Time tasks may consume. Ex:
Period of 1,000,000us and Runtime of 950,000us means that this container could consume 95% of available CPU and leave the remaining 5% to normal priority tasks.
The sum of all runtimes across containers cannot exceed the amount alotted to the parent cgroup.
**--cpuset-cpus**="" **--cpuset-cpus**=""
CPUs in which to allow execution (0-3, 0,1) CPUs in which to allow execution (0-3, 0,1)

View file

@ -58,6 +58,12 @@ type cgroupCPUInfo struct {
// Whether CPU CFS(Completely Fair Scheduler) quota is supported or not // Whether CPU CFS(Completely Fair Scheduler) quota is supported or not
CPUCfsQuota bool CPUCfsQuota bool
// Whether CPU real-time period is supported or not
CPURealtimePeriod bool
// Whether CPU real-time runtime is supported or not
CPURealtimeRuntime bool
} }
type cgroupBlkioInfo struct { type cgroupBlkioInfo struct {

View file

@ -135,10 +135,23 @@ func checkCgroupCPU(cgMounts map[string]string, quiet bool) cgroupCPUInfo {
if !quiet && !cpuCfsQuota { if !quiet && !cpuCfsQuota {
logrus.Warn("Your kernel does not support cgroup cfs quotas") logrus.Warn("Your kernel does not support cgroup cfs quotas")
} }
cpuRealtimePeriod := cgroupEnabled(mountPoint, "cpu.rt_period_us")
if !quiet && !cpuRealtimePeriod {
logrus.Warn("Your kernel does not support cgroup rt period")
}
cpuRealtimeRuntime := cgroupEnabled(mountPoint, "cpu.rt_runtime_us")
if !quiet && !cpuRealtimeRuntime {
logrus.Warn("Your kernel does not support cgroup rt runtime")
}
return cgroupCPUInfo{ return cgroupCPUInfo{
CPUShares: cpuShares, CPUShares: cpuShares,
CPUCfsPeriod: cpuCfsPeriod, CPUCfsPeriod: cpuCfsPeriod,
CPUCfsQuota: cpuCfsQuota, CPUCfsQuota: cpuCfsQuota,
CPURealtimePeriod: cpuRealtimePeriod,
CPURealtimeRuntime: cpuRealtimeRuntime,
} }
} }

View file

@ -77,9 +77,11 @@ func setCgroupMem(quiet bool) cgroupMemInfo {
func setCgroupCPU(quiet bool) cgroupCPUInfo { func setCgroupCPU(quiet bool) cgroupCPUInfo {
return cgroupCPUInfo{ return cgroupCPUInfo{
CPUShares: true, CPUShares: true,
CPUCfsPeriod: false, CPUCfsPeriod: false,
CPUCfsQuota: true, CPUCfsQuota: true,
CPURealtimePeriod: false,
CPURealtimeRuntime: false,
} }
} }

View file

@ -7,6 +7,7 @@ import (
"github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/container"
networktypes "github.com/docker/docker/api/types/network" networktypes "github.com/docker/docker/api/types/network"
"github.com/docker/docker/pkg/sysinfo"
"github.com/docker/docker/volume" "github.com/docker/docker/volume"
) )
@ -68,6 +69,10 @@ func DecodeContainerConfig(src io.Reader) (*container.Config, *container.HostCon
return nil, nil, nil, err return nil, nil, nil, err
} }
// Validate Resources
if err := ValidateResources(hc, sysinfo.New(true)); err != nil {
return nil, nil, nil, err
}
return w.Config, hc, w.NetworkingConfig, nil return w.Config, hc, w.NetworkingConfig, nil
} }

View file

@ -5,6 +5,7 @@ import (
"strings" "strings"
"github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/container"
"github.com/docker/docker/pkg/sysinfo"
) )
// DefaultDaemonNetworkMode returns the default network stack the daemon should // DefaultDaemonNetworkMode returns the default network stack the daemon should
@ -45,3 +46,8 @@ func ValidateIsolation(hc *container.HostConfig) error {
func ValidateQoS(hc *container.HostConfig) error { func ValidateQoS(hc *container.HostConfig) error {
return nil return nil
} }
// ValidateResources performs platform specific validation of the resource settings
func ValidateResources(hc *container.HostConfig, si *sysinfo.SysInfo) error {
return nil
}

View file

@ -9,6 +9,7 @@ import (
"testing" "testing"
"github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/container"
"github.com/docker/docker/pkg/sysinfo"
) )
// TODO Windows: This will need addressing for a Windows daemon. // TODO Windows: This will need addressing for a Windows daemon.
@ -220,3 +221,63 @@ func TestDecodeHostConfig(t *testing.T) {
} }
} }
} }
func TestValidateResources(t *testing.T) {
type resourceTest struct {
ConfigCPURealtimePeriod int64
ConfigCPURealtimeRuntime int64
SysInfoCPURealtimePeriod bool
SysInfoCPURealtimeRuntime bool
ErrorExpected bool
FailureMsg string
}
tests := []resourceTest{
{
ConfigCPURealtimePeriod: 1000,
ConfigCPURealtimeRuntime: 1000,
SysInfoCPURealtimePeriod: true,
SysInfoCPURealtimeRuntime: true,
ErrorExpected: false,
FailureMsg: "Expected valid configuration",
},
{
ConfigCPURealtimePeriod: 5000,
ConfigCPURealtimeRuntime: 5000,
SysInfoCPURealtimePeriod: false,
SysInfoCPURealtimeRuntime: true,
ErrorExpected: true,
FailureMsg: "Expected failure when cpu-rt-period is set but kernel doesn't support it",
},
{
ConfigCPURealtimePeriod: 5000,
ConfigCPURealtimeRuntime: 5000,
SysInfoCPURealtimePeriod: true,
SysInfoCPURealtimeRuntime: false,
ErrorExpected: true,
FailureMsg: "Expected failure when cpu-rt-runtime is set but kernel doesn't support it",
},
{
ConfigCPURealtimePeriod: 5000,
ConfigCPURealtimeRuntime: 10000,
SysInfoCPURealtimePeriod: true,
SysInfoCPURealtimeRuntime: false,
ErrorExpected: true,
FailureMsg: "Expected failure when cpu-rt-runtime is greater than cpu-rt-period",
},
}
for _, rt := range tests {
var hc container.HostConfig
hc.Resources.CPURealtimePeriod = rt.ConfigCPURealtimePeriod
hc.Resources.CPURealtimeRuntime = rt.ConfigCPURealtimeRuntime
var si sysinfo.SysInfo
si.CPURealtimePeriod = rt.SysInfoCPURealtimePeriod
si.CPURealtimeRuntime = rt.SysInfoCPURealtimeRuntime
if err := ValidateResources(&hc, &si); (err != nil) != rt.ErrorExpected {
t.Fatal(rt.FailureMsg, err)
}
}
}

View file

@ -8,6 +8,7 @@ import (
"strings" "strings"
"github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/container"
"github.com/docker/docker/pkg/sysinfo"
) )
// DefaultDaemonNetworkMode returns the default network stack the daemon should // DefaultDaemonNetworkMode returns the default network stack the daemon should
@ -104,3 +105,25 @@ func ValidateQoS(hc *container.HostConfig) error {
} }
return nil return nil
} }
// ValidateResources performs platform specific validation of the resource settings
// cpu-rt-runtime and cpu-rt-period can not be greater than their parent, cpu-rt-runtime requires sys_nice
func ValidateResources(hc *container.HostConfig, si *sysinfo.SysInfo) error {
// We may not be passed a host config, such as in the case of docker commit
if hc == nil {
return nil
}
if hc.Resources.CPURealtimePeriod > 0 && !si.CPURealtimePeriod {
return fmt.Errorf("invalid --cpu-rt-period: Your kernel does not support cgroup rt period")
}
if hc.Resources.CPURealtimeRuntime > 0 && !si.CPURealtimeRuntime {
return fmt.Errorf("invalid --cpu-rt-runtime: Your kernel does not support cgroup rt runtime")
}
if hc.Resources.CPURealtimePeriod != 0 && hc.Resources.CPURealtimeRuntime != 0 && hc.Resources.CPURealtimeRuntime > hc.Resources.CPURealtimePeriod {
return fmt.Errorf("invalid --cpu-rt-runtime: rt runtime cannot be higher than rt period")
}
return nil
}

View file

@ -5,6 +5,7 @@ import (
"strings" "strings"
"github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/container"
"github.com/docker/docker/pkg/sysinfo"
) )
// DefaultDaemonNetworkMode returns the default network stack the daemon should // DefaultDaemonNetworkMode returns the default network stack the daemon should
@ -49,3 +50,19 @@ func ValidateIsolation(hc *container.HostConfig) error {
func ValidateQoS(hc *container.HostConfig) error { func ValidateQoS(hc *container.HostConfig) error {
return nil return nil
} }
// ValidateResources performs platform specific validation of the resource settings
func ValidateResources(hc *container.HostConfig, si *sysinfo.SysInfo) error {
// We may not be passed a host config, such as in the case of docker commit
if hc == nil {
return nil
}
if hc.Resources.CPURealtimePeriod != 0 {
return fmt.Errorf("invalid --cpu-rt-period: Windows does not support this feature")
}
if hc.Resources.CPURealtimeRuntime != 0 {
return fmt.Errorf("invalid --cpu-rt-runtime: Windows does not support this feature")
}
return nil
}

View file

@ -23,90 +23,92 @@ import (
// ContainerOptions is a data object with all the options for creating a container // ContainerOptions is a data object with all the options for creating a container
type ContainerOptions struct { type ContainerOptions struct {
attach opts.ListOpts attach opts.ListOpts
volumes opts.ListOpts volumes opts.ListOpts
tmpfs opts.ListOpts tmpfs opts.ListOpts
blkioWeightDevice WeightdeviceOpt blkioWeightDevice WeightdeviceOpt
deviceReadBps ThrottledeviceOpt deviceReadBps ThrottledeviceOpt
deviceWriteBps ThrottledeviceOpt deviceWriteBps ThrottledeviceOpt
links opts.ListOpts links opts.ListOpts
aliases opts.ListOpts aliases opts.ListOpts
linkLocalIPs opts.ListOpts linkLocalIPs opts.ListOpts
deviceReadIOps ThrottledeviceOpt deviceReadIOps ThrottledeviceOpt
deviceWriteIOps ThrottledeviceOpt deviceWriteIOps ThrottledeviceOpt
env opts.ListOpts env opts.ListOpts
labels opts.ListOpts labels opts.ListOpts
devices opts.ListOpts devices opts.ListOpts
ulimits *UlimitOpt ulimits *UlimitOpt
sysctls *opts.MapOpts sysctls *opts.MapOpts
publish opts.ListOpts publish opts.ListOpts
expose opts.ListOpts expose opts.ListOpts
dns opts.ListOpts dns opts.ListOpts
dnsSearch opts.ListOpts dnsSearch opts.ListOpts
dnsOptions opts.ListOpts dnsOptions opts.ListOpts
extraHosts opts.ListOpts extraHosts opts.ListOpts
volumesFrom opts.ListOpts volumesFrom opts.ListOpts
envFile opts.ListOpts envFile opts.ListOpts
capAdd opts.ListOpts capAdd opts.ListOpts
capDrop opts.ListOpts capDrop opts.ListOpts
groupAdd opts.ListOpts groupAdd opts.ListOpts
securityOpt opts.ListOpts securityOpt opts.ListOpts
storageOpt opts.ListOpts storageOpt opts.ListOpts
labelsFile opts.ListOpts labelsFile opts.ListOpts
loggingOpts opts.ListOpts loggingOpts opts.ListOpts
privileged bool privileged bool
pidMode string pidMode string
utsMode string utsMode string
usernsMode string usernsMode string
publishAll bool publishAll bool
stdin bool stdin bool
tty bool tty bool
oomKillDisable bool oomKillDisable bool
oomScoreAdj int oomScoreAdj int
containerIDFile string containerIDFile string
entrypoint string entrypoint string
hostname string hostname string
memoryString string memoryString string
memoryReservation string memoryReservation string
memorySwap string memorySwap string
kernelMemory string kernelMemory string
user string user string
workingDir string workingDir string
cpuShares int64 cpuShares int64
cpuPercent int64 cpuPercent int64
cpuPeriod int64 cpuPeriod int64
cpuQuota int64 cpuRealtimePeriod int64
cpusetCpus string cpuRealtimeRuntime int64
cpusetMems string cpuQuota int64
blkioWeight uint16 cpusetCpus string
ioMaxBandwidth string cpusetMems string
ioMaxIOps uint64 blkioWeight uint16
swappiness int64 ioMaxBandwidth string
netMode string ioMaxIOps uint64
macAddress string swappiness int64
ipv4Address string netMode string
ipv6Address string macAddress string
ipcMode string ipv4Address string
pidsLimit int64 ipv6Address string
restartPolicy string ipcMode string
readonlyRootfs bool pidsLimit int64
loggingDriver string restartPolicy string
cgroupParent string readonlyRootfs bool
volumeDriver string loggingDriver string
stopSignal string cgroupParent string
stopTimeout int volumeDriver string
isolation string stopSignal string
shmSize string stopTimeout int
noHealthcheck bool isolation string
healthCmd string shmSize string
healthInterval time.Duration noHealthcheck bool
healthTimeout time.Duration healthCmd string
healthRetries int healthInterval time.Duration
runtime string healthTimeout time.Duration
autoRemove bool healthRetries int
init bool runtime string
initPath string autoRemove bool
credentialSpec string init bool
initPath string
credentialSpec string
Image string Image string
Args []string Args []string
@ -225,6 +227,8 @@ func AddFlags(flags *pflag.FlagSet) *ContainerOptions {
flags.Int64Var(&copts.cpuPercent, "cpu-percent", 0, "CPU percent (Windows only)") flags.Int64Var(&copts.cpuPercent, "cpu-percent", 0, "CPU percent (Windows only)")
flags.Int64Var(&copts.cpuPeriod, "cpu-period", 0, "Limit CPU CFS (Completely Fair Scheduler) period") flags.Int64Var(&copts.cpuPeriod, "cpu-period", 0, "Limit CPU CFS (Completely Fair Scheduler) period")
flags.Int64Var(&copts.cpuQuota, "cpu-quota", 0, "Limit CPU CFS (Completely Fair Scheduler) quota") flags.Int64Var(&copts.cpuQuota, "cpu-quota", 0, "Limit CPU CFS (Completely Fair Scheduler) quota")
flags.Int64Var(&copts.cpuRealtimePeriod, "cpu-rt-period", 0, "Limit CPU real-time period in microseconds")
flags.Int64Var(&copts.cpuRealtimeRuntime, "cpu-rt-runtime", 0, "Limit CPU real-time runtime in microseconds")
flags.Int64VarP(&copts.cpuShares, "cpu-shares", "c", 0, "CPU shares (relative weight)") flags.Int64VarP(&copts.cpuShares, "cpu-shares", "c", 0, "CPU shares (relative weight)")
flags.Var(&copts.deviceReadBps, "device-read-bps", "Limit read rate (bytes per second) from a device") flags.Var(&copts.deviceReadBps, "device-read-bps", "Limit read rate (bytes per second) from a device")
flags.Var(&copts.deviceReadIOps, "device-read-iops", "Limit read rate (IO per second) from a device") flags.Var(&copts.deviceReadIOps, "device-read-iops", "Limit read rate (IO per second) from a device")
@ -521,6 +525,8 @@ func Parse(flags *pflag.FlagSet, copts *ContainerOptions) (*container.Config, *c
CpusetCpus: copts.cpusetCpus, CpusetCpus: copts.cpusetCpus,
CpusetMems: copts.cpusetMems, CpusetMems: copts.cpusetMems,
CPUQuota: copts.cpuQuota, CPUQuota: copts.cpuQuota,
CPURealtimePeriod: copts.cpuRealtimePeriod,
CPURealtimeRuntime: copts.cpuRealtimeRuntime,
PidsLimit: copts.pidsLimit, PidsLimit: copts.pidsLimit,
BlkioWeight: copts.blkioWeight, BlkioWeight: copts.blkioWeight,
BlkioWeightDevice: copts.blkioWeightDevice.GetList(), BlkioWeightDevice: copts.blkioWeightDevice.GetList(),