Signed-off-by: Darren Stahl <darst@microsoft.com>
Darren Stahl authored on 2016/11/02 05:02:46... | ... |
@@ -27,10 +27,13 @@ import ( |
27 | 27 |
) |
28 | 28 |
|
29 | 29 |
const ( |
30 |
- defaultNetworkSpace = "172.16.0.0/12" |
|
31 |
- platformSupported = true |
|
32 |
- windowsMinCPUShares = 1 |
|
33 |
- windowsMaxCPUShares = 10000 |
|
30 |
+ defaultNetworkSpace = "172.16.0.0/12" |
|
31 |
+ platformSupported = true |
|
32 |
+ windowsMinCPUShares = 1 |
|
33 |
+ windowsMaxCPUShares = 10000 |
|
34 |
+ windowsMinCPUPercent = 1 |
|
35 |
+ windowsMaxCPUPercent = 100 |
|
36 |
+ windowsMinCPUCount = 1 |
|
34 | 37 |
) |
35 | 38 |
|
36 | 39 |
func getBlkioWeightDevices(config *containertypes.HostConfig) ([]blkiodev.WeightDevice, error) { |
... | ... |
@@ -80,6 +83,15 @@ func (daemon *Daemon) adaptContainerSettings(hostConfig *containertypes.HostConf |
80 | 80 |
return nil |
81 | 81 |
} |
82 | 82 |
|
83 |
+ numCPU := int64(sysinfo.NumCPU()) |
|
84 |
+ if hostConfig.CPUCount < 0 { |
|
85 |
+ logrus.Warnf("Changing requested CPUCount of %d to minimum allowed of %d", hostConfig.CPUCount, windowsMinCPUCount) |
|
86 |
+ hostConfig.CPUCount = windowsMinCPUCount |
|
87 |
+ } else if hostConfig.CPUCount > numCPU { |
|
88 |
+ logrus.Warnf("Changing requested CPUCount of %d to current number of processors, %d", hostConfig.CPUCount, numCPU) |
|
89 |
+ hostConfig.CPUCount = numCPU |
|
90 |
+ } |
|
91 |
+ |
|
83 | 92 |
if hostConfig.CPUShares < 0 { |
84 | 93 |
logrus.Warnf("Changing requested CPUShares of %d to minimum allowed of %d", hostConfig.CPUShares, windowsMinCPUShares) |
85 | 94 |
hostConfig.CPUShares = windowsMinCPUShares |
... | ... |
@@ -88,19 +100,42 @@ func (daemon *Daemon) adaptContainerSettings(hostConfig *containertypes.HostConf |
88 | 88 |
hostConfig.CPUShares = windowsMaxCPUShares |
89 | 89 |
} |
90 | 90 |
|
91 |
+ if hostConfig.CPUPercent < 0 { |
|
92 |
+ logrus.Warnf("Changing requested CPUPercent of %d to minimum allowed of %d", hostConfig.CPUPercent, windowsMinCPUPercent) |
|
93 |
+ hostConfig.CPUPercent = windowsMinCPUPercent |
|
94 |
+ } else if hostConfig.CPUPercent > windowsMaxCPUPercent { |
|
95 |
+ logrus.Warnf("Changing requested CPUPercent of %d to maximum allowed of %d", hostConfig.CPUPercent, windowsMaxCPUPercent) |
|
96 |
+ hostConfig.CPUPercent = windowsMaxCPUPercent |
|
97 |
+ } |
|
98 |
+ |
|
91 | 99 |
return nil |
92 | 100 |
} |
93 | 101 |
|
94 |
-func verifyContainerResources(resources *containertypes.Resources, sysInfo *sysinfo.SysInfo) ([]string, error) { |
|
102 |
+func verifyContainerResources(resources *containertypes.Resources, isHyperv bool) ([]string, error) { |
|
95 | 103 |
warnings := []string{} |
96 | 104 |
|
97 |
- // cpu subsystem checks and adjustments |
|
98 |
- if resources.CPUPercent < 0 || resources.CPUPercent > 100 { |
|
99 |
- return warnings, fmt.Errorf("Range of CPU percent is from 1 to 100") |
|
100 |
- } |
|
101 |
- |
|
102 |
- if resources.CPUPercent > 0 && resources.CPUShares > 0 { |
|
103 |
- return warnings, fmt.Errorf("Conflicting options: CPU Shares and CPU Percent cannot both be set") |
|
105 |
+ if !isHyperv { |
|
106 |
+ // The processor resource controls are mutually exclusive on |
|
107 |
+ // Windows Server Containers, the order of precedence is |
|
108 |
+ // CPUCount first, then CPUShares, and CPUPercent last. |
|
109 |
+ if resources.CPUCount > 0 { |
|
110 |
+ if resources.CPUShares > 0 { |
|
111 |
+ warnings = append(warnings, "Conflicting options: CPU count takes priority over CPU shares on Windows Server Containers. CPU shares discarded") |
|
112 |
+ logrus.Warn("Conflicting options: CPU count takes priority over CPU shares on Windows Server Containers. CPU shares discarded") |
|
113 |
+ resources.CPUShares = 0 |
|
114 |
+ } |
|
115 |
+ if resources.CPUPercent > 0 { |
|
116 |
+ warnings = append(warnings, "Conflicting options: CPU count takes priority over CPU percent on Windows Server Containers. CPU percent discarded") |
|
117 |
+ logrus.Warn("Conflicting options: CPU count takes priority over CPU percent on Windows Server Containers. CPU percent discarded") |
|
118 |
+ resources.CPUPercent = 0 |
|
119 |
+ } |
|
120 |
+ } else if resources.CPUShares > 0 { |
|
121 |
+ if resources.CPUPercent > 0 { |
|
122 |
+ warnings = append(warnings, "Conflicting options: CPU shares takes priority over CPU percent on Windows Server Containers. CPU percent discarded") |
|
123 |
+ logrus.Warn("Conflicting options: CPU shares takes priority over CPU percent on Windows Server Containers. CPU percent discarded") |
|
124 |
+ resources.CPUPercent = 0 |
|
125 |
+ } |
|
126 |
+ } |
|
104 | 127 |
} |
105 | 128 |
|
106 | 129 |
if resources.NanoCPUs > 0 && resources.CPUPercent > 0 { |
... | ... |
@@ -154,7 +189,7 @@ func verifyContainerResources(resources *containertypes.Resources, sysInfo *sysi |
154 | 154 |
func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *containertypes.HostConfig, config *containertypes.Config, update bool) ([]string, error) { |
155 | 155 |
warnings := []string{} |
156 | 156 |
|
157 |
- w, err := verifyContainerResources(&hostConfig.Resources, nil) |
|
157 |
+ w, err := verifyContainerResources(&hostConfig.Resources, daemon.runAsHyperVContainer(hostConfig)) |
|
158 | 158 |
warnings = append(warnings, w...) |
159 | 159 |
if err != nil { |
160 | 160 |
return warnings, err |
... | ... |
@@ -388,14 +423,14 @@ func setupDaemonRoot(config *Config, rootDir string, rootUID, rootGID int) error |
388 | 388 |
} |
389 | 389 |
|
390 | 390 |
// runasHyperVContainer returns true if we are going to run as a Hyper-V container |
391 |
-func (daemon *Daemon) runAsHyperVContainer(container *container.Container) bool { |
|
392 |
- if container.HostConfig.Isolation.IsDefault() { |
|
391 |
+func (daemon *Daemon) runAsHyperVContainer(hostConfig *containertypes.HostConfig) bool { |
|
392 |
+ if hostConfig.Isolation.IsDefault() { |
|
393 | 393 |
// Container is set to use the default, so take the default from the daemon configuration |
394 | 394 |
return daemon.defaultIsolation.IsHyperV() |
395 | 395 |
} |
396 | 396 |
|
397 | 397 |
// Container is requesting an isolation mode. Honour it. |
398 |
- return container.HostConfig.Isolation.IsHyperV() |
|
398 |
+ return hostConfig.Isolation.IsHyperV() |
|
399 | 399 |
|
400 | 400 |
} |
401 | 401 |
|
... | ... |
@@ -403,7 +438,7 @@ func (daemon *Daemon) runAsHyperVContainer(container *container.Container) bool |
403 | 403 |
// container start to call mount. |
404 | 404 |
func (daemon *Daemon) conditionalMountOnStart(container *container.Container) error { |
405 | 405 |
// We do not mount if a Hyper-V container |
406 |
- if !daemon.runAsHyperVContainer(container) { |
|
406 |
+ if !daemon.runAsHyperVContainer(container.HostConfig) { |
|
407 | 407 |
return daemon.Mount(container) |
408 | 408 |
} |
409 | 409 |
return nil |
... | ... |
@@ -413,7 +448,7 @@ func (daemon *Daemon) conditionalMountOnStart(container *container.Container) er |
413 | 413 |
// during the cleanup of a container to unmount. |
414 | 414 |
func (daemon *Daemon) conditionalUnmountOnCleanup(container *container.Container) error { |
415 | 415 |
// We do not unmount if a Hyper-V container |
416 |
- if !daemon.runAsHyperVContainer(container) { |
|
416 |
+ if !daemon.runAsHyperVContainer(container.HostConfig) { |
|
417 | 417 |
return daemon.Unmount(container) |
418 | 418 |
} |
419 | 419 |
return nil |
... | ... |
@@ -86,11 +86,13 @@ func (daemon *Daemon) createSpec(c *container.Container) (*specs.Spec, error) { |
86 | 86 |
if c.HostConfig.NanoCPUs > 0 { |
87 | 87 |
cpuPercent = uint8(c.HostConfig.NanoCPUs * 100 / int64(sysinfo.NumCPU()) / 1e9) |
88 | 88 |
} |
89 |
+ cpuCount := uint64(c.HostConfig.CPUCount) |
|
89 | 90 |
memoryLimit := uint64(c.HostConfig.Memory) |
90 | 91 |
s.Windows.Resources = &specs.WindowsResources{ |
91 | 92 |
CPU: &specs.WindowsCPUResources{ |
92 | 93 |
Percent: &cpuPercent, |
93 | 94 |
Shares: &cpuShares, |
95 |
+ Count: &cpuCount, |
|
94 | 96 |
}, |
95 | 97 |
Memory: &specs.WindowsMemoryResources{ |
96 | 98 |
Limit: &memoryLimit, |
... | ... |
@@ -166,6 +166,7 @@ This section lists each version from latest to oldest. Each listing includes a |
166 | 166 |
* `GET /nodes` and `GET /node/(id or name)` now return `Addr` as part of a node's `Status`, which is the address that that node connects to the manager from. |
167 | 167 |
* The `HostConfig` field now includes `NanoCPUs` that represents CPU quota in units of 10<sup>-9</sup> CPUs. |
168 | 168 |
* `GET /info` now returns more structured information about security options. |
169 |
+* The `HostConfig` field now includes `CpuCount` that represents the number of CPUs available for execution by the container. Windows daemon only. |
|
169 | 170 |
|
170 | 171 |
### v1.24 API changes |
171 | 172 |
|
... | ... |
@@ -303,6 +303,7 @@ Create a container |
303 | 303 |
"MemoryReservation": 0, |
304 | 304 |
"KernelMemory": 0, |
305 | 305 |
"NanoCPUs": 500000, |
306 |
+ "CpuCount": 4, |
|
306 | 307 |
"CpuPercent": 80, |
307 | 308 |
"CpuShares": 512, |
308 | 309 |
"CpuPeriod": 100000, |
... | ... |
@@ -427,7 +428,14 @@ Create a container |
427 | 427 |
- **MemoryReservation** - Memory soft limit in bytes. |
428 | 428 |
- **KernelMemory** - Kernel memory limit in bytes. |
429 | 429 |
- **NanoCPUs** - CPU quota in units of 10<sup>-9</sup> CPUs. |
430 |
- - **CpuPercent** - An integer value containing the usable percentage of the available CPUs. (Windows daemon only) |
|
430 |
+ - **CpuCount** - An integer value containing the number of usable CPUs. |
|
431 |
+ Windows daemon only. On Windows Server containers, |
|
432 |
+ the processor resource controls are mutually exclusive, the order of precedence |
|
433 |
+ is CPUCount first, then CPUShares, and CPUPercent last. |
|
434 |
+ - **CpuPercent** - An integer value containing the usable percentage of |
|
435 |
+ the available CPUs. Windows daemon only. On Windows Server containers, |
|
436 |
+ the processor resource controls are mutually exclusive, the order of precedence |
|
437 |
+ is CPUCount first, then CPUShares, and CPUPercent last. |
|
431 | 438 |
- **CpuShares** - An integer value containing the container's CPU Shares |
432 | 439 |
(ie. the relative weight vs other containers). |
433 | 440 |
- **CpuPeriod** - The length of a CPU period in microseconds. |
... | ... |
@@ -623,6 +631,7 @@ Return low-level information on the container `id` |
623 | 623 |
"ContainerIDFile": "", |
624 | 624 |
"CpusetCpus": "", |
625 | 625 |
"CpusetMems": "", |
626 |
+ "CpuCount": 4, |
|
626 | 627 |
"CpuPercent": 80, |
627 | 628 |
"CpuShares": 0, |
628 | 629 |
"CpuPeriod": 100000, |
... | ... |
@@ -31,6 +31,9 @@ Options: |
31 | 31 |
--cap-drop value Drop Linux capabilities (default []) |
32 | 32 |
--cgroup-parent string Optional parent cgroup for the container |
33 | 33 |
--cidfile string Write the container ID to the file |
34 |
+ --cpu-count int The number of CPUs available for execution by the container. |
|
35 |
+ Windows daemon only. On Windows Server containers, this is |
|
36 |
+ approximated as a percentage of total CPU usage. |
|
34 | 37 |
--cpu-percent int CPU percent (Windows only) |
35 | 38 |
--cpu-period int Limit CPU CFS (Completely Fair Scheduler) period |
36 | 39 |
--cpu-quota int Limit CPU CFS (Completely Fair Scheduler) quota |
... | ... |
@@ -29,7 +29,14 @@ Options: |
29 | 29 |
--cap-drop value Drop Linux capabilities (default []) |
30 | 30 |
--cgroup-parent string Optional parent cgroup for the container |
31 | 31 |
--cidfile string Write the container ID to the file |
32 |
- --cpu-percent int CPU percent (Windows only) |
|
32 |
+ --cpu-count int The number of CPUs available for execution by the container. |
|
33 |
+ Windows daemon only. On Windows Server containers, this is |
|
34 |
+ approximated as a percentage of total CPU usage. |
|
35 |
+ --cpu-percent int Limit percentage of CPU available for execution |
|
36 |
+ by the container. Windows daemon only. |
|
37 |
+ The processor resource controls are mutually |
|
38 |
+ exclusive, the order of precedence is CPUCount |
|
39 |
+ first, then CPUShares, and CPUPercent last. |
|
33 | 40 |
--cpu-period int Limit CPU CFS (Completely Fair Scheduler) period |
34 | 41 |
--cpu-quota int Limit CPU CFS (Completely Fair Scheduler) quota |
35 | 42 |
-c, --cpu-shares int CPU shares (relative weight) |
... | ... |
@@ -4766,3 +4766,67 @@ func (s *DockerSuite) TestRunMount(c *check.C) { |
4766 | 4766 |
} |
4767 | 4767 |
} |
4768 | 4768 |
} |
4769 |
+ |
|
4770 |
+func (s *DockerSuite) TestRunWindowsWithCPUCount(c *check.C) { |
|
4771 |
+ testRequires(c, DaemonIsWindows) |
|
4772 |
+ |
|
4773 |
+ out, _ := dockerCmd(c, "run", "--cpu-count=1", "--name", "test", "busybox", "echo", "testing") |
|
4774 |
+ c.Assert(strings.TrimSpace(out), checker.Equals, "testing") |
|
4775 |
+ |
|
4776 |
+ out = inspectField(c, "test", "HostConfig.CPUCount") |
|
4777 |
+ c.Assert(out, check.Equals, "1") |
|
4778 |
+} |
|
4779 |
+ |
|
4780 |
+func (s *DockerSuite) TestRunWindowsWithCPUShares(c *check.C) { |
|
4781 |
+ testRequires(c, DaemonIsWindows) |
|
4782 |
+ |
|
4783 |
+ out, _ := dockerCmd(c, "run", "--cpu-shares=1000", "--name", "test", "busybox", "echo", "testing") |
|
4784 |
+ c.Assert(strings.TrimSpace(out), checker.Equals, "testing") |
|
4785 |
+ |
|
4786 |
+ out = inspectField(c, "test", "HostConfig.CPUShares") |
|
4787 |
+ c.Assert(out, check.Equals, "1000") |
|
4788 |
+} |
|
4789 |
+ |
|
4790 |
+func (s *DockerSuite) TestRunWindowsWithCPUPercent(c *check.C) { |
|
4791 |
+ testRequires(c, DaemonIsWindows) |
|
4792 |
+ |
|
4793 |
+ out, _ := dockerCmd(c, "run", "--cpu-percent=80", "--name", "test", "busybox", "echo", "testing") |
|
4794 |
+ c.Assert(strings.TrimSpace(out), checker.Equals, "testing") |
|
4795 |
+ |
|
4796 |
+ out = inspectField(c, "test", "HostConfig.CPUPercent") |
|
4797 |
+ c.Assert(out, check.Equals, "80") |
|
4798 |
+} |
|
4799 |
+ |
|
4800 |
+func (s *DockerSuite) TestRunProcessIsolationWithCPUCountCPUSharesAndCPUPercent(c *check.C) { |
|
4801 |
+ testRequires(c, DaemonIsWindows, IsolationIsProcess) |
|
4802 |
+ |
|
4803 |
+ out, _ := dockerCmd(c, "run", "--cpu-count=1", "--cpu-shares=1000", "--cpu-percent=80", "--name", "test", "busybox", "echo", "testing") |
|
4804 |
+ c.Assert(strings.TrimSpace(out), checker.Contains, "WARNING: Conflicting options: CPU count takes priority over CPU shares on Windows Server Containers. CPU shares discarded") |
|
4805 |
+ c.Assert(strings.TrimSpace(out), checker.Contains, "WARNING: Conflicting options: CPU count takes priority over CPU percent on Windows Server Containers. CPU percent discarded") |
|
4806 |
+ c.Assert(strings.TrimSpace(out), checker.Contains, "testing") |
|
4807 |
+ |
|
4808 |
+ out = inspectField(c, "test", "HostConfig.CPUCount") |
|
4809 |
+ c.Assert(out, check.Equals, "1") |
|
4810 |
+ |
|
4811 |
+ out = inspectField(c, "test", "HostConfig.CPUShares") |
|
4812 |
+ c.Assert(out, check.Equals, "0") |
|
4813 |
+ |
|
4814 |
+ out = inspectField(c, "test", "HostConfig.CPUPercent") |
|
4815 |
+ c.Assert(out, check.Equals, "0") |
|
4816 |
+} |
|
4817 |
+ |
|
4818 |
+func (s *DockerSuite) TestRunHypervIsolationWithCPUCountCPUSharesAndCPUPercent(c *check.C) { |
|
4819 |
+ testRequires(c, DaemonIsWindows, IsolationIsHyperv) |
|
4820 |
+ |
|
4821 |
+ out, _ := dockerCmd(c, "run", "--cpu-count=1", "--cpu-shares=1000", "--cpu-percent=80", "--name", "test", "busybox", "echo", "testing") |
|
4822 |
+ c.Assert(strings.TrimSpace(out), checker.Contains, "testing") |
|
4823 |
+ |
|
4824 |
+ out = inspectField(c, "test", "HostConfig.CPUCount") |
|
4825 |
+ c.Assert(out, check.Equals, "1") |
|
4826 |
+ |
|
4827 |
+ out = inspectField(c, "test", "HostConfig.CPUShares") |
|
4828 |
+ c.Assert(out, check.Equals, "1000") |
|
4829 |
+ |
|
4830 |
+ out = inspectField(c, "test", "HostConfig.CPUPercent") |
|
4831 |
+ c.Assert(out, check.Equals, "80") |
|
4832 |
+} |
... | ... |
@@ -218,6 +218,18 @@ var ( |
218 | 218 |
}, |
219 | 219 |
"Test requires containers are not pausable.", |
220 | 220 |
} |
221 |
+ IsolationIsHyperv = testRequirement{ |
|
222 |
+ func() bool { |
|
223 |
+ return daemonPlatform == "windows" && isolation == "hyperv" |
|
224 |
+ }, |
|
225 |
+ "Test requires a Windows daemon running default isolation mode of hyperv.", |
|
226 |
+ } |
|
227 |
+ IsolationIsProcess = testRequirement{ |
|
228 |
+ func() bool { |
|
229 |
+ return daemonPlatform == "windows" && isolation == "process" |
|
230 |
+ }, |
|
231 |
+ "Test requires a Windows daemon running default isolation mode of process.", |
|
232 |
+ } |
|
221 | 233 |
) |
222 | 234 |
|
223 | 235 |
// testRequires checks if the environment satisfies the requirements |
... | ... |
@@ -110,6 +110,9 @@ func (clnt *client) Create(containerID string, checkpoint string, checkpointDir |
110 | 110 |
|
111 | 111 |
if spec.Windows.Resources != nil { |
112 | 112 |
if spec.Windows.Resources.CPU != nil { |
113 |
+ if spec.Windows.Resources.CPU.Count != nil { |
|
114 |
+ configuration.ProcessorCount = uint32(*spec.Windows.Resources.CPU.Count) |
|
115 |
+ } |
|
113 | 116 |
if spec.Windows.Resources.CPU.Shares != nil { |
114 | 117 |
configuration.ProcessorWeight = uint64(*spec.Windows.Resources.CPU.Shares) |
115 | 118 |
} |
... | ... |
@@ -15,6 +15,8 @@ docker-create - Create a new container |
15 | 15 |
[**--cap-drop**[=*[]*]] |
16 | 16 |
[**--cgroup-parent**[=*CGROUP-PATH*]] |
17 | 17 |
[**--cidfile**[=*CIDFILE*]] |
18 |
+[**--cpu-count**[=*0*]] |
|
19 |
+[**--cpu-percent**[=*0*]] |
|
18 | 20 |
[**--cpu-period**[=*0*]] |
19 | 21 |
[**--cpu-quota**[=*0*]] |
20 | 22 |
[**--cpu-rt-period**[=*0*]] |
... | ... |
@@ -124,6 +126,18 @@ The initial status of the container created with **docker create** is 'created'. |
124 | 124 |
**--cidfile**="" |
125 | 125 |
Write the container ID to the file |
126 | 126 |
|
127 |
+**--cpu-count**=*0* |
|
128 |
+ Limit the number of CPUs available for execution by the container. |
|
129 |
+ |
|
130 |
+ On Windows Server containers, this is approximated as a percentage of total CPU usage. |
|
131 |
+ |
|
132 |
+ On Windows Server containers, the processor resource controls are mutually exclusive, the order of precedence is CPUCount first, then CPUShares, and CPUPercent last. |
|
133 |
+ |
|
134 |
+**--cpu-percent**=*0* |
|
135 |
+ Limit the percentage of CPU available for execution by a container running on a Windows daemon. |
|
136 |
+ |
|
137 |
+ On Windows Server containers, the processor resource controls are mutually exclusive, the order of precedence is CPUCount first, then CPUShares, and CPUPercent last. |
|
138 |
+ |
|
127 | 139 |
**--cpu-period**=*0* |
128 | 140 |
Limit the CPU CFS (Completely Fair Scheduler) period |
129 | 141 |
|
... | ... |
@@ -15,6 +15,8 @@ docker-run - Run a command in a new container |
15 | 15 |
[**--cap-drop**[=*[]*]] |
16 | 16 |
[**--cgroup-parent**[=*CGROUP-PATH*]] |
17 | 17 |
[**--cidfile**[=*CIDFILE*]] |
18 |
+[**--cpu-count**[=*0*]] |
|
19 |
+[**--cpu-percent**[=*0*]] |
|
18 | 20 |
[**--cpu-period**[=*0*]] |
19 | 21 |
[**--cpu-quota**[=*0*]] |
20 | 22 |
[**--cpu-rt-period**[=*0*]] |
... | ... |
@@ -174,6 +176,18 @@ division of CPU shares: |
174 | 174 |
**--cidfile**="" |
175 | 175 |
Write the container ID to the file |
176 | 176 |
|
177 |
+**--cpu-count**=*0* |
|
178 |
+ Limit the number of CPUs available for execution by the container. |
|
179 |
+ |
|
180 |
+ On Windows Server containers, this is approximated as a percentage of total CPU usage. |
|
181 |
+ |
|
182 |
+ On Windows Server containers, the processor resource controls are mutually exclusive, the order of precedence is CPUCount first, then CPUShares, and CPUPercent last. |
|
183 |
+ |
|
184 |
+**--cpu-percent**=*0* |
|
185 |
+ Limit the percentage of CPU available for execution by a container running on a Windows daemon. |
|
186 |
+ |
|
187 |
+ On Windows Server containers, the processor resource controls are mutually exclusive, the order of precedence is CPUCount first, then CPUShares, and CPUPercent last. |
|
188 |
+ |
|
177 | 189 |
**--cpu-period**=*0* |
178 | 190 |
Limit the CPU CFS (Completely Fair Scheduler) period |
179 | 191 |
|
... | ... |
@@ -73,6 +73,7 @@ type ContainerOptions struct { |
73 | 73 |
kernelMemory string |
74 | 74 |
user string |
75 | 75 |
workingDir string |
76 |
+ cpuCount int64 |
|
76 | 77 |
cpuShares int64 |
77 | 78 |
cpuPercent int64 |
78 | 79 |
cpuPeriod int64 |
... | ... |
@@ -227,6 +228,7 @@ func AddFlags(flags *pflag.FlagSet) *ContainerOptions { |
227 | 227 |
flags.StringVar(&copts.containerIDFile, "cidfile", "", "Write the container ID to the file") |
228 | 228 |
flags.StringVar(&copts.cpusetCpus, "cpuset-cpus", "", "CPUs in which to allow execution (0-3, 0,1)") |
229 | 229 |
flags.StringVar(&copts.cpusetMems, "cpuset-mems", "", "MEMs in which to allow execution (0-3, 0,1)") |
230 |
+ flags.Int64Var(&copts.cpuCount, "cpu-count", 0, "CPU count (Windows only)") |
|
230 | 231 |
flags.Int64Var(&copts.cpuPercent, "cpu-percent", 0, "CPU percent (Windows only)") |
231 | 232 |
flags.Int64Var(&copts.cpuPeriod, "cpu-period", 0, "Limit CPU CFS (Completely Fair Scheduler) period") |
232 | 233 |
flags.Int64Var(&copts.cpuQuota, "cpu-quota", 0, "Limit CPU CFS (Completely Fair Scheduler) quota") |
... | ... |
@@ -529,6 +531,7 @@ func Parse(flags *pflag.FlagSet, copts *ContainerOptions) (*container.Config, *c |
529 | 529 |
KernelMemory: kernelMemory, |
530 | 530 |
OomKillDisable: &copts.oomKillDisable, |
531 | 531 |
NanoCPUs: copts.cpus.Value(), |
532 |
+ CPUCount: copts.cpuCount, |
|
532 | 533 |
CPUPercent: copts.cpuPercent, |
533 | 534 |
CPUShares: copts.cpuShares, |
534 | 535 |
CPUPeriod: copts.cpuPeriod, |