Signed-off-by: qhuang <qhuang@10.0.2.15>
qhuang authored on 2015/09/23 15:02:45... | ... |
@@ -254,18 +254,19 @@ func populateCommand(c *Container, env []string) error { |
254 | 254 |
} |
255 | 255 |
|
256 | 256 |
resources := &execdriver.Resources{ |
257 |
- Memory: c.hostConfig.Memory, |
|
258 |
- MemorySwap: c.hostConfig.MemorySwap, |
|
259 |
- KernelMemory: c.hostConfig.KernelMemory, |
|
260 |
- CPUShares: c.hostConfig.CPUShares, |
|
261 |
- CpusetCpus: c.hostConfig.CpusetCpus, |
|
262 |
- CpusetMems: c.hostConfig.CpusetMems, |
|
263 |
- CPUPeriod: c.hostConfig.CPUPeriod, |
|
264 |
- CPUQuota: c.hostConfig.CPUQuota, |
|
265 |
- BlkioWeight: c.hostConfig.BlkioWeight, |
|
266 |
- Rlimits: rlimits, |
|
267 |
- OomKillDisable: c.hostConfig.OomKillDisable, |
|
268 |
- MemorySwappiness: -1, |
|
257 |
+ Memory: c.hostConfig.Memory, |
|
258 |
+ MemorySwap: c.hostConfig.MemorySwap, |
|
259 |
+ MemoryReservation: c.hostConfig.MemoryReservation, |
|
260 |
+ KernelMemory: c.hostConfig.KernelMemory, |
|
261 |
+ CPUShares: c.hostConfig.CPUShares, |
|
262 |
+ CpusetCpus: c.hostConfig.CpusetCpus, |
|
263 |
+ CpusetMems: c.hostConfig.CpusetMems, |
|
264 |
+ CPUPeriod: c.hostConfig.CPUPeriod, |
|
265 |
+ CPUQuota: c.hostConfig.CPUQuota, |
|
266 |
+ BlkioWeight: c.hostConfig.BlkioWeight, |
|
267 |
+ Rlimits: rlimits, |
|
268 |
+ OomKillDisable: c.hostConfig.OomKillDisable, |
|
269 |
+ MemorySwappiness: -1, |
|
269 | 270 |
} |
270 | 271 |
|
271 | 272 |
if c.hostConfig.MemorySwappiness != nil { |
... | ... |
@@ -110,6 +110,9 @@ func (daemon *Daemon) adaptContainerSettings(hostConfig *runconfig.HostConfig, a |
110 | 110 |
// By default, MemorySwap is set to twice the size of Memory. |
111 | 111 |
hostConfig.MemorySwap = hostConfig.Memory * 2 |
112 | 112 |
} |
113 |
+ if hostConfig.MemoryReservation == 0 && hostConfig.Memory > 0 { |
|
114 |
+ hostConfig.MemoryReservation = hostConfig.Memory |
|
115 |
+ } |
|
113 | 116 |
} |
114 | 117 |
|
115 | 118 |
// verifyPlatformContainerSettings performs platform-specific validation of the |
... | ... |
@@ -154,6 +157,14 @@ func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *runconfig.HostC |
154 | 154 |
return warnings, fmt.Errorf("Invalid value: %v, valid memory swappiness range is 0-100.", swappiness) |
155 | 155 |
} |
156 | 156 |
} |
157 |
+ if hostConfig.MemoryReservation > 0 && !sysInfo.MemoryReservation { |
|
158 |
+ warnings = append(warnings, "Your kernel does not support memory soft limit capabilities. Limitation discarded.") |
|
159 |
+ logrus.Warnf("Your kernel does not support memory soft limit capabilities. Limitation discarded.") |
|
160 |
+ hostConfig.MemoryReservation = 0 |
|
161 |
+ } |
|
162 |
+ if hostConfig.Memory > 0 && hostConfig.MemoryReservation > 0 && hostConfig.Memory < hostConfig.MemoryReservation { |
|
163 |
+ return warnings, fmt.Errorf("Minimum memory limit should be larger than memory reservation limit, see usage.") |
|
164 |
+ } |
|
157 | 165 |
if hostConfig.KernelMemory > 0 && !sysInfo.KernelMemory { |
158 | 166 |
warnings = append(warnings, "Your kernel does not support kernel memory limit capabilities. Limitation discarded.") |
159 | 167 |
logrus.Warnf("Your kernel does not support kernel memory limit capabilities. Limitation discarded.") |
... | ... |
@@ -141,18 +141,19 @@ type UTS struct { |
141 | 141 |
// Currently these are all for cgroup configs. |
142 | 142 |
// TODO Windows: Factor out ulimit.Rlimit |
143 | 143 |
type Resources struct { |
144 |
- Memory int64 `json:"memory"` |
|
145 |
- MemorySwap int64 `json:"memory_swap"` |
|
146 |
- KernelMemory int64 `json:"kernel_memory"` |
|
147 |
- CPUShares int64 `json:"cpu_shares"` |
|
148 |
- CpusetCpus string `json:"cpuset_cpus"` |
|
149 |
- CpusetMems string `json:"cpuset_mems"` |
|
150 |
- CPUPeriod int64 `json:"cpu_period"` |
|
151 |
- CPUQuota int64 `json:"cpu_quota"` |
|
152 |
- BlkioWeight int64 `json:"blkio_weight"` |
|
153 |
- Rlimits []*ulimit.Rlimit `json:"rlimits"` |
|
154 |
- OomKillDisable bool `json:"oom_kill_disable"` |
|
155 |
- MemorySwappiness int64 `json:"memory_swappiness"` |
|
144 |
+ Memory int64 `json:"memory"` |
|
145 |
+ MemorySwap int64 `json:"memory_swap"` |
|
146 |
+ MemoryReservation int64 `json:"memory_reservation"` |
|
147 |
+ KernelMemory int64 `json:"kernel_memory"` |
|
148 |
+ CPUShares int64 `json:"cpu_shares"` |
|
149 |
+ CpusetCpus string `json:"cpuset_cpus"` |
|
150 |
+ CpusetMems string `json:"cpuset_mems"` |
|
151 |
+ CPUPeriod int64 `json:"cpu_period"` |
|
152 |
+ CPUQuota int64 `json:"cpu_quota"` |
|
153 |
+ BlkioWeight int64 `json:"blkio_weight"` |
|
154 |
+ Rlimits []*ulimit.Rlimit `json:"rlimits"` |
|
155 |
+ OomKillDisable bool `json:"oom_kill_disable"` |
|
156 |
+ MemorySwappiness int64 `json:"memory_swappiness"` |
|
156 | 157 |
} |
157 | 158 |
|
158 | 159 |
// ResourceStats contains information about resource usage by a container. |
... | ... |
@@ -64,7 +64,7 @@ func SetupCgroups(container *configs.Config, c *Command) error { |
64 | 64 |
if c.Resources != nil { |
65 | 65 |
container.Cgroups.CpuShares = c.Resources.CPUShares |
66 | 66 |
container.Cgroups.Memory = c.Resources.Memory |
67 |
- container.Cgroups.MemoryReservation = c.Resources.Memory |
|
67 |
+ container.Cgroups.MemoryReservation = c.Resources.MemoryReservation |
|
68 | 68 |
container.Cgroups.MemorySwap = c.Resources.MemorySwap |
69 | 69 |
container.Cgroups.CpusetCpus = c.Resources.CpusetCpus |
70 | 70 |
container.Cgroups.CpusetMems = c.Resources.CpusetMems |
... | ... |
@@ -91,11 +91,13 @@ lxc.mount.entry = {{$value.Source}} {{escapeFstabSpaces $ROOTFS}}/{{escapeFstabS |
91 | 91 |
{{if .Resources}} |
92 | 92 |
{{if .Resources.Memory}} |
93 | 93 |
lxc.cgroup.memory.limit_in_bytes = {{.Resources.Memory}} |
94 |
-lxc.cgroup.memory.soft_limit_in_bytes = {{.Resources.Memory}} |
|
95 | 94 |
{{with $memSwap := getMemorySwap .Resources}} |
96 | 95 |
lxc.cgroup.memory.memsw.limit_in_bytes = {{$memSwap}} |
97 | 96 |
{{end}} |
98 | 97 |
{{end}} |
98 |
+{{if gt .Resources.MemoryReservation 0}} |
|
99 |
+lxc.cgroup.memory.soft_limit_in_bytes = {{.Resources.MemoryReservation}} |
|
100 |
+{{end}} |
|
99 | 101 |
{{if gt .Resources.KernelMemory 0}} |
100 | 102 |
lxc.cgroup.memory.kmem.limit_in_bytes = {{.Resources.KernelMemory}} |
101 | 103 |
{{end}} |
... | ... |
@@ -173,6 +173,7 @@ Create a container |
173 | 173 |
"LxcConf": {"lxc.utsname":"docker"}, |
174 | 174 |
"Memory": 0, |
175 | 175 |
"MemorySwap": 0, |
176 |
+ "MemoryReservation": 0, |
|
176 | 177 |
"KernelMemory": 0, |
177 | 178 |
"CpuShares": 512, |
178 | 179 |
"CpuPeriod": 100000, |
... | ... |
@@ -223,6 +224,7 @@ Json Parameters: |
223 | 223 |
- **Memory** - Memory limit in bytes. |
224 | 224 |
- **MemorySwap** - Total memory limit (memory + swap); set `-1` to disable swap |
225 | 225 |
You must use this with `memory` and make the swap value larger than `memory`. |
226 |
+- **MemoryReservation** - Memory soft limit in bytes. |
|
226 | 227 |
- **KernelMemory** - Kernel memory limit in bytes. |
227 | 228 |
- **CpuShares** - An integer value containing the container's CPU Shares |
228 | 229 |
(ie. the relative weight vs other containers). |
... | ... |
@@ -398,6 +400,7 @@ Return low-level information on the container `id` |
398 | 398 |
"LxcConf": [], |
399 | 399 |
"Memory": 0, |
400 | 400 |
"MemorySwap": 0, |
401 |
+ "MemoryReservation": 0, |
|
401 | 402 |
"KernelMemory": 0, |
402 | 403 |
"OomKillDisable": false, |
403 | 404 |
"NetworkMode": "bridge", |
... | ... |
@@ -50,6 +50,7 @@ Creates a new container. |
50 | 50 |
--lxc-conf=[] Add custom lxc options |
51 | 51 |
-m, --memory="" Memory limit |
52 | 52 |
--mac-address="" Container MAC address (e.g. 92:d0:c6:0a:29:33) |
53 |
+ --memory-reservation="" Memory soft limit |
|
53 | 54 |
--memory-swap="" Total memory (memory + swap), '-1' to disable swap |
54 | 55 |
--memory-swappiness="" Tune a container's memory swappiness behavior. Accepts an integer between 0 and 100. |
55 | 56 |
--name="" Assign a name to the container |
... | ... |
@@ -50,6 +50,7 @@ weight=1 |
50 | 50 |
--lxc-conf=[] Add custom lxc options |
51 | 51 |
-m, --memory="" Memory limit |
52 | 52 |
--mac-address="" Container MAC address (e.g. 92:d0:c6:0a:29:33) |
53 |
+ --memory-reservation="" Memory soft limit |
|
53 | 54 |
--memory-swap="" Total memory (memory + swap), '-1' to disable swap |
54 | 55 |
--memory-swappiness="" Tune a container's memory swappiness behavior. Accepts an integer between 0 and 100. |
55 | 56 |
--name="" Assign a name to the container |
... | ... |
@@ -544,6 +544,7 @@ container: |
544 | 544 |
|----------------------------|---------------------------------------------------------------------------------------------| |
545 | 545 |
| `-m`, `--memory="" ` | Memory limit (format: `<number>[<unit>]`, where unit = b, k, m or g) | |
546 | 546 |
| `--memory-swap=""` | Total memory limit (memory + swap, format: `<number>[<unit>]`, where unit = b, k, m or g) | |
547 |
+| `--memory-reservation=""` | Memory soft limit (format: `<number>[<unit>]`, where unit = b, k, m or g) | |
|
547 | 548 |
| `--kernel-memory=""` | Kernel memory limit (format: `<number>[<unit>]`, where unit = b, k, m or g) | |
548 | 549 |
| `-c`, `--cpu-shares=0` | CPU shares (relative weight) | |
549 | 550 |
| `--cpu-period=0` | Limit the CPU CFS (Completely Fair Scheduler) period | |
... | ... |
@@ -629,6 +630,43 @@ would be 2*300M, so processes can use 300M swap memory as well. |
629 | 629 |
We set both memory and swap memory, so the processes in the container can use |
630 | 630 |
300M memory and 700M swap memory. |
631 | 631 |
|
632 |
+Memory reservation is a kind of memory soft limit that allows for greater |
|
633 |
+sharing of memory. Under normal circumstances, containers can use as much of |
|
634 |
+the memory as needed and are constrained only by the hard limits set with the |
|
635 |
+`-m`/`--memory` option. When memory reservation is set, Docker detects memory |
|
636 |
+contention or low memory and forces containers to restrict their consumption to |
|
637 |
+a reservation limit. |
|
638 |
+ |
|
639 |
+Always set the memory reservation value below the hard limit, otherwise the hard |
|
640 |
+limit takes precedence. A reservation of 0 is the same as setting no |
|
641 |
+reservation. By default (without reservation set), memory reservation is the |
|
642 |
+same as the hard memory limit. |
|
643 |
+ |
|
644 |
+Memory reservation is a soft-limit feature and does not guarantee the limit |
|
645 |
+won't be exceeded. Instead, the feature attempts to ensure that, when memory is |
|
646 |
+heavily contended for, memory is allocated based on the reservation hints/setup. |
|
647 |
+ |
|
648 |
+The following example limits the memory (`-m`) to 500M and sets the memory |
|
649 |
+reservation to 200M. |
|
650 |
+ |
|
651 |
+```bash |
|
652 |
+$ docker run -ti -m 500M --memory-reservation 200M ubuntu:14.04 /bin/bash |
|
653 |
+``` |
|
654 |
+ |
|
655 |
+Under this configuration, when the container consumes memory more than 200M and |
|
656 |
+less than 500M, the next system memory reclaim attempts to shrink container |
|
657 |
+memory below 200M. |
|
658 |
+ |
|
659 |
+The following example set memory reservation to 1G without a hard memory limit. |
|
660 |
+ |
|
661 |
+```bash |
|
662 |
+$ docker run -ti --memory-reservation 1G ubuntu:14.04 /bin/bash |
|
663 |
+``` |
|
664 |
+ |
|
665 |
+The container can use as much memory as it needs. The memory reservation setting |
|
666 |
+ensures the container doesn't consume too much memory for long time, because |
|
667 |
+every memory reclaim shrinks the container's consumption to the reservation. |
|
668 |
+ |
|
632 | 669 |
By default, kernel kills processes in a container if an out-of-memory (OOM) |
633 | 670 |
error occurs. To change this behaviour, use the `--oom-kill-disable` option. |
634 | 671 |
Only disable the OOM killer on containers where you have also set the |
... | ... |
@@ -323,6 +323,22 @@ func (s *DockerSuite) TestRunWithSwappinessInvalid(c *check.C) { |
323 | 323 |
} |
324 | 324 |
} |
325 | 325 |
|
326 |
+func (s *DockerSuite) TestRunWithMemoryReservation(c *check.C) { |
|
327 |
+ testRequires(c, memoryReservationSupport) |
|
328 |
+ dockerCmd(c, "run", "--memory-reservation", "200M", "busybox", "true") |
|
329 |
+} |
|
330 |
+ |
|
331 |
+func (s *DockerSuite) TestRunWithMemoryReservationInvalid(c *check.C) { |
|
332 |
+ testRequires(c, memoryLimitSupport) |
|
333 |
+ testRequires(c, memoryReservationSupport) |
|
334 |
+ out, _, err := dockerCmdWithError("run", "-m", "500M", "--memory-reservation", "800M", "busybox", "true") |
|
335 |
+ c.Assert(err, check.NotNil) |
|
336 |
+ expected := "Minimum memory limit should be larger than memory reservation limit" |
|
337 |
+ if !strings.Contains(strings.TrimSpace(out), expected) { |
|
338 |
+ c.Fatalf("run container should fail with invalid memory reservation, output: %q", out) |
|
339 |
+ } |
|
340 |
+} |
|
341 |
+ |
|
326 | 342 |
func (s *DockerSuite) TestStopContainerSignal(c *check.C) { |
327 | 343 |
out, _ := dockerCmd(c, "run", "--stop-signal", "SIGUSR1", "-d", "busybox", "/bin/sh", "-c", `trap 'echo "exit trapped"; exit 0' USR1; while true; do sleep 1; done`) |
328 | 344 |
containerID := strings.TrimSpace(out) |
... | ... |
@@ -45,6 +45,12 @@ var ( |
45 | 45 |
}, |
46 | 46 |
"Test requires an environment that supports cgroup memory limit.", |
47 | 47 |
} |
48 |
+ memoryReservationSupport = testRequirement{ |
|
49 |
+ func() bool { |
|
50 |
+ return SysInfo.MemoryReservation |
|
51 |
+ }, |
|
52 |
+ "Test requires an environment that supports cgroup memory reservation.", |
|
53 |
+ } |
|
48 | 54 |
swapMemorySupport = testRequirement{ |
49 | 55 |
func() bool { |
50 | 56 |
return SysInfo.SwapLimit |
... | ... |
@@ -40,6 +40,7 @@ docker-create - Create a new container |
40 | 40 |
[**--lxc-conf**[=*[]*]] |
41 | 41 |
[**-m**|**--memory**[=*MEMORY*]] |
42 | 42 |
[**--mac-address**[=*MAC-ADDRESS*]] |
43 |
+[**--memory-reservation**[=*MEMORY-RESERVATION*]] |
|
43 | 44 |
[**--memory-swap**[=*MEMORY-SWAP*]] |
44 | 45 |
[**--memory-swappiness**[=*MEMORY-SWAPPINESS*]] |
45 | 46 |
[**--name**[=*NAME*]] |
... | ... |
@@ -196,6 +197,15 @@ system's page size (the value would be very large, that's millions of trillions) |
196 | 196 |
**--mac-address**="" |
197 | 197 |
Container MAC address (e.g. 92:d0:c6:0a:29:33) |
198 | 198 |
|
199 |
+**--memory-reservation**="" |
|
200 |
+ Memory soft limit (format: <number>[<unit>], where unit = b, k, m or g) |
|
201 |
+ |
|
202 |
+ After setting memory reservation, when the system detects memory contention |
|
203 |
+or low memory, containers are forced to restrict their consumption to their |
|
204 |
+reservation. So you should always set the value below **--memory**, otherwise the |
|
205 |
+hard limit will take precedence. By default, memory reservation will be the same |
|
206 |
+as memory limit. |
|
207 |
+ |
|
199 | 208 |
**--memory-swap**="" |
200 | 209 |
Total memory limit (memory + swap) |
201 | 210 |
|
... | ... |
@@ -41,6 +41,7 @@ docker-run - Run a command in a new container |
41 | 41 |
[**--lxc-conf**[=*[]*]] |
42 | 42 |
[**-m**|**--memory**[=*MEMORY*]] |
43 | 43 |
[**--mac-address**[=*MAC-ADDRESS*]] |
44 |
+[**--memory-reservation**[=*MEMORY-RESERVATION*]] |
|
44 | 45 |
[**--memory-swap**[=*MEMORY-SWAP*]] |
45 | 46 |
[**--memory-swappiness**[=*MEMORY-SWAPPINESS*]] |
46 | 47 |
[**--name**[=*NAME*]] |
... | ... |
@@ -290,6 +291,15 @@ RAM. If a limit of 0 is specified (not using **-m**), the container's memory is |
290 | 290 |
not limited. The actual limit may be rounded up to a multiple of the operating |
291 | 291 |
system's page size (the value would be very large, that's millions of trillions). |
292 | 292 |
|
293 |
+**--memory-reservation**="" |
|
294 |
+ Memory soft limit (format: <number>[<unit>], where unit = b, k, m or g) |
|
295 |
+ |
|
296 |
+ After setting memory reservation, when the system detects memory contention |
|
297 |
+or low memory, containers are forced to restrict their consumption to their |
|
298 |
+reservation. So you should always set the value below **--memory**, otherwise the |
|
299 |
+hard limit will take precedence. By default, memory reservation will be the same |
|
300 |
+as memory limit. |
|
301 |
+ |
|
293 | 302 |
**--memory-swap**="" |
294 | 303 |
Total memory limit (memory + swap) |
295 | 304 |
|
... | ... |
@@ -49,6 +49,10 @@ func checkCgroupMem(quiet bool) cgroupMemInfo { |
49 | 49 |
if !quiet && !swapLimit { |
50 | 50 |
logrus.Warn("Your kernel does not support swap memory limit.") |
51 | 51 |
} |
52 |
+ memoryReservation := cgroupEnabled(mountPoint, "memory.soft_limit_in_bytes") |
|
53 |
+ if !quiet && !memoryReservation { |
|
54 |
+ logrus.Warn("Your kernel does not support memory reservation.") |
|
55 |
+ } |
|
52 | 56 |
oomKillDisable := cgroupEnabled(mountPoint, "memory.oom_control") |
53 | 57 |
if !quiet && !oomKillDisable { |
54 | 58 |
logrus.Warnf("Your kernel does not support oom control.") |
... | ... |
@@ -63,11 +67,12 @@ func checkCgroupMem(quiet bool) cgroupMemInfo { |
63 | 63 |
} |
64 | 64 |
|
65 | 65 |
return cgroupMemInfo{ |
66 |
- MemoryLimit: true, |
|
67 |
- SwapLimit: swapLimit, |
|
68 |
- OomKillDisable: oomKillDisable, |
|
69 |
- MemorySwappiness: memorySwappiness, |
|
70 |
- KernelMemory: kernelMemory, |
|
66 |
+ MemoryLimit: true, |
|
67 |
+ SwapLimit: swapLimit, |
|
68 |
+ MemoryReservation: memoryReservation, |
|
69 |
+ OomKillDisable: oomKillDisable, |
|
70 |
+ MemorySwappiness: memorySwappiness, |
|
71 |
+ KernelMemory: kernelMemory, |
|
71 | 72 |
} |
72 | 73 |
} |
73 | 74 |
|
... | ... |
@@ -214,45 +214,46 @@ func NewLxcConfig(values []KeyValuePair) *LxcConfig { |
214 | 214 |
// Here, "non-portable" means "dependent of the host we are running on". |
215 | 215 |
// Portable information *should* appear in Config. |
216 | 216 |
type HostConfig struct { |
217 |
- Binds []string // List of volume bindings for this container |
|
218 |
- ContainerIDFile string // File (path) where the containerId is written |
|
219 |
- LxcConf *LxcConfig // Additional lxc configuration |
|
220 |
- Memory int64 // Memory limit (in bytes) |
|
221 |
- MemorySwap int64 // Total memory usage (memory + swap); set `-1` to disable swap |
|
222 |
- KernelMemory int64 // Kernel memory limit (in bytes) |
|
223 |
- CPUShares int64 `json:"CpuShares"` // CPU shares (relative weight vs. other containers) |
|
224 |
- CPUPeriod int64 `json:"CpuPeriod"` // CPU CFS (Completely Fair Scheduler) period |
|
225 |
- CpusetCpus string // CpusetCpus 0-2, 0,1 |
|
226 |
- CpusetMems string // CpusetMems 0-2, 0,1 |
|
227 |
- CPUQuota int64 `json:"CpuQuota"` // CPU CFS (Completely Fair Scheduler) quota |
|
228 |
- BlkioWeight int64 // Block IO weight (relative weight vs. other containers) |
|
229 |
- OomKillDisable bool // Whether to disable OOM Killer or not |
|
230 |
- MemorySwappiness *int64 // Tuning container memory swappiness behaviour |
|
231 |
- Privileged bool // Is the container in privileged mode |
|
232 |
- PortBindings nat.PortMap // Port mapping between the exposed port (container) and the host |
|
233 |
- Links []string // List of links (in the name:alias form) |
|
234 |
- PublishAllPorts bool // Should docker publish all exposed port for the container |
|
235 |
- DNS []string `json:"Dns"` // List of DNS server to lookup |
|
236 |
- DNSOptions []string `json:"DnsOptions"` // List of DNSOption to look for |
|
237 |
- DNSSearch []string `json:"DnsSearch"` // List of DNSSearch to look for |
|
238 |
- ExtraHosts []string // List of extra hosts |
|
239 |
- VolumesFrom []string // List of volumes to take from other container |
|
240 |
- Devices []DeviceMapping // List of devices to map inside the container |
|
241 |
- NetworkMode NetworkMode // Network namespace to use for the container |
|
242 |
- IpcMode IpcMode // IPC namespace to use for the container |
|
243 |
- PidMode PidMode // PID namespace to use for the container |
|
244 |
- UTSMode UTSMode // UTS namespace to use for the container |
|
245 |
- CapAdd *stringutils.StrSlice // List of kernel capabilities to add to the container |
|
246 |
- CapDrop *stringutils.StrSlice // List of kernel capabilities to remove from the container |
|
247 |
- GroupAdd []string // List of additional groups that the container process will run as |
|
248 |
- RestartPolicy RestartPolicy // Restart policy to be used for the container |
|
249 |
- SecurityOpt []string // List of string values to customize labels for MLS systems, such as SELinux. |
|
250 |
- ReadonlyRootfs bool // Is the container root filesystem in read-only |
|
251 |
- Ulimits []*ulimit.Ulimit // List of ulimits to be set in the container |
|
252 |
- LogConfig LogConfig // Configuration of the logs for this container |
|
253 |
- CgroupParent string // Parent cgroup. |
|
254 |
- ConsoleSize [2]int // Initial console size on Windows |
|
255 |
- VolumeDriver string // Name of the volume driver used to mount volumes |
|
217 |
+ Binds []string // List of volume bindings for this container |
|
218 |
+ ContainerIDFile string // File (path) where the containerId is written |
|
219 |
+ LxcConf *LxcConfig // Additional lxc configuration |
|
220 |
+ Memory int64 // Memory limit (in bytes) |
|
221 |
+ MemoryReservation int64 // Memory soft limit (in bytes) |
|
222 |
+ MemorySwap int64 // Total memory usage (memory + swap); set `-1` to disable swap |
|
223 |
+ KernelMemory int64 // Kernel memory limit (in bytes) |
|
224 |
+ CPUShares int64 `json:"CpuShares"` // CPU shares (relative weight vs. other containers) |
|
225 |
+ CPUPeriod int64 `json:"CpuPeriod"` // CPU CFS (Completely Fair Scheduler) period |
|
226 |
+ CpusetCpus string // CpusetCpus 0-2, 0,1 |
|
227 |
+ CpusetMems string // CpusetMems 0-2, 0,1 |
|
228 |
+ CPUQuota int64 `json:"CpuQuota"` // CPU CFS (Completely Fair Scheduler) quota |
|
229 |
+ BlkioWeight int64 // Block IO weight (relative weight vs. other containers) |
|
230 |
+ OomKillDisable bool // Whether to disable OOM Killer or not |
|
231 |
+ MemorySwappiness *int64 // Tuning container memory swappiness behaviour |
|
232 |
+ Privileged bool // Is the container in privileged mode |
|
233 |
+ PortBindings nat.PortMap // Port mapping between the exposed port (container) and the host |
|
234 |
+ Links []string // List of links (in the name:alias form) |
|
235 |
+ PublishAllPorts bool // Should docker publish all exposed port for the container |
|
236 |
+ DNS []string `json:"Dns"` // List of DNS server to lookup |
|
237 |
+ DNSOptions []string `json:"DnsOptions"` // List of DNSOption to look for |
|
238 |
+ DNSSearch []string `json:"DnsSearch"` // List of DNSSearch to look for |
|
239 |
+ ExtraHosts []string // List of extra hosts |
|
240 |
+ VolumesFrom []string // List of volumes to take from other container |
|
241 |
+ Devices []DeviceMapping // List of devices to map inside the container |
|
242 |
+ NetworkMode NetworkMode // Network namespace to use for the container |
|
243 |
+ IpcMode IpcMode // IPC namespace to use for the container |
|
244 |
+ PidMode PidMode // PID namespace to use for the container |
|
245 |
+ UTSMode UTSMode // UTS namespace to use for the container |
|
246 |
+ CapAdd *stringutils.StrSlice // List of kernel capabilities to add to the container |
|
247 |
+ CapDrop *stringutils.StrSlice // List of kernel capabilities to remove from the container |
|
248 |
+ GroupAdd []string // List of additional groups that the container process will run as |
|
249 |
+ RestartPolicy RestartPolicy // Restart policy to be used for the container |
|
250 |
+ SecurityOpt []string // List of string values to customize labels for MLS systems, such as SELinux. |
|
251 |
+ ReadonlyRootfs bool // Is the container root filesystem in read-only |
|
252 |
+ Ulimits []*ulimit.Ulimit // List of ulimits to be set in the container |
|
253 |
+ LogConfig LogConfig // Configuration of the logs for this container |
|
254 |
+ CgroupParent string // Parent cgroup. |
|
255 |
+ ConsoleSize [2]int // Initial console size on Windows |
|
256 |
+ VolumeDriver string // Name of the volume driver used to mount volumes |
|
256 | 257 |
} |
257 | 258 |
|
258 | 259 |
// DecodeHostConfig creates a HostConfig based on the specified Reader. |
... | ... |
@@ -64,38 +64,39 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe |
64 | 64 |
flLabelsFile = opts.NewListOpts(nil) |
65 | 65 |
flLoggingOpts = opts.NewListOpts(nil) |
66 | 66 |
|
67 |
- flNetwork = cmd.Bool([]string{"#n", "#-networking"}, true, "Enable networking for this container") |
|
68 |
- flPrivileged = cmd.Bool([]string{"#privileged", "-privileged"}, false, "Give extended privileges to this container") |
|
69 |
- flPidMode = cmd.String([]string{"-pid"}, "", "PID namespace to use") |
|
70 |
- flUTSMode = cmd.String([]string{"-uts"}, "", "UTS namespace to use") |
|
71 |
- flPublishAll = cmd.Bool([]string{"P", "-publish-all"}, false, "Publish all exposed ports to random ports") |
|
72 |
- flStdin = cmd.Bool([]string{"i", "-interactive"}, false, "Keep STDIN open even if not attached") |
|
73 |
- flTty = cmd.Bool([]string{"t", "-tty"}, false, "Allocate a pseudo-TTY") |
|
74 |
- flOomKillDisable = cmd.Bool([]string{"-oom-kill-disable"}, false, "Disable OOM Killer") |
|
75 |
- flContainerIDFile = cmd.String([]string{"#cidfile", "-cidfile"}, "", "Write the container ID to the file") |
|
76 |
- flEntrypoint = cmd.String([]string{"#entrypoint", "-entrypoint"}, "", "Overwrite the default ENTRYPOINT of the image") |
|
77 |
- flHostname = cmd.String([]string{"h", "-hostname"}, "", "Container host name") |
|
78 |
- flMemoryString = cmd.String([]string{"m", "-memory"}, "", "Memory limit") |
|
79 |
- flMemorySwap = cmd.String([]string{"-memory-swap"}, "", "Total memory (memory + swap), '-1' to disable swap") |
|
80 |
- flKernelMemory = cmd.String([]string{"-kernel-memory"}, "", "Kernel memory limit") |
|
81 |
- flUser = cmd.String([]string{"u", "-user"}, "", "Username or UID (format: <name|uid>[:<group|gid>])") |
|
82 |
- flWorkingDir = cmd.String([]string{"w", "-workdir"}, "", "Working directory inside the container") |
|
83 |
- flCPUShares = cmd.Int64([]string{"#c", "-cpu-shares"}, 0, "CPU shares (relative weight)") |
|
84 |
- flCPUPeriod = cmd.Int64([]string{"-cpu-period"}, 0, "Limit CPU CFS (Completely Fair Scheduler) period") |
|
85 |
- flCPUQuota = cmd.Int64([]string{"-cpu-quota"}, 0, "Limit CPU CFS (Completely Fair Scheduler) quota") |
|
86 |
- flCpusetCpus = cmd.String([]string{"#-cpuset", "-cpuset-cpus"}, "", "CPUs in which to allow execution (0-3, 0,1)") |
|
87 |
- flCpusetMems = cmd.String([]string{"-cpuset-mems"}, "", "MEMs in which to allow execution (0-3, 0,1)") |
|
88 |
- flBlkioWeight = cmd.Int64([]string{"-blkio-weight"}, 0, "Block IO (relative weight), between 10 and 1000") |
|
89 |
- flSwappiness = cmd.Int64([]string{"-memory-swappiness"}, -1, "Tuning container memory swappiness (0 to 100)") |
|
90 |
- flNetMode = cmd.String([]string{"-net"}, "default", "Set the Network mode for the container") |
|
91 |
- flMacAddress = cmd.String([]string{"-mac-address"}, "", "Container MAC address (e.g. 92:d0:c6:0a:29:33)") |
|
92 |
- flIpcMode = cmd.String([]string{"-ipc"}, "", "IPC namespace to use") |
|
93 |
- flRestartPolicy = cmd.String([]string{"-restart"}, "no", "Restart policy to apply when a container exits") |
|
94 |
- flReadonlyRootfs = cmd.Bool([]string{"-read-only"}, false, "Mount the container's root filesystem as read only") |
|
95 |
- flLoggingDriver = cmd.String([]string{"-log-driver"}, "", "Logging driver for container") |
|
96 |
- flCgroupParent = cmd.String([]string{"-cgroup-parent"}, "", "Optional parent cgroup for the container") |
|
97 |
- flVolumeDriver = cmd.String([]string{"-volume-driver"}, "", "Optional volume driver for the container") |
|
98 |
- flStopSignal = cmd.String([]string{"-stop-signal"}, signal.DefaultStopSignal, fmt.Sprintf("Signal to stop a container, %v by default", signal.DefaultStopSignal)) |
|
67 |
+ flNetwork = cmd.Bool([]string{"#n", "#-networking"}, true, "Enable networking for this container") |
|
68 |
+ flPrivileged = cmd.Bool([]string{"#privileged", "-privileged"}, false, "Give extended privileges to this container") |
|
69 |
+ flPidMode = cmd.String([]string{"-pid"}, "", "PID namespace to use") |
|
70 |
+ flUTSMode = cmd.String([]string{"-uts"}, "", "UTS namespace to use") |
|
71 |
+ flPublishAll = cmd.Bool([]string{"P", "-publish-all"}, false, "Publish all exposed ports to random ports") |
|
72 |
+ flStdin = cmd.Bool([]string{"i", "-interactive"}, false, "Keep STDIN open even if not attached") |
|
73 |
+ flTty = cmd.Bool([]string{"t", "-tty"}, false, "Allocate a pseudo-TTY") |
|
74 |
+ flOomKillDisable = cmd.Bool([]string{"-oom-kill-disable"}, false, "Disable OOM Killer") |
|
75 |
+ flContainerIDFile = cmd.String([]string{"#cidfile", "-cidfile"}, "", "Write the container ID to the file") |
|
76 |
+ flEntrypoint = cmd.String([]string{"#entrypoint", "-entrypoint"}, "", "Overwrite the default ENTRYPOINT of the image") |
|
77 |
+ flHostname = cmd.String([]string{"h", "-hostname"}, "", "Container host name") |
|
78 |
+ flMemoryString = cmd.String([]string{"m", "-memory"}, "", "Memory limit") |
|
79 |
+ flMemoryReservation = cmd.String([]string{"-memory-reservation"}, "", "Memory soft limit") |
|
80 |
+ flMemorySwap = cmd.String([]string{"-memory-swap"}, "", "Total memory (memory + swap), '-1' to disable swap") |
|
81 |
+ flKernelMemory = cmd.String([]string{"-kernel-memory"}, "", "Kernel memory limit") |
|
82 |
+ flUser = cmd.String([]string{"u", "-user"}, "", "Username or UID (format: <name|uid>[:<group|gid>])") |
|
83 |
+ flWorkingDir = cmd.String([]string{"w", "-workdir"}, "", "Working directory inside the container") |
|
84 |
+ flCPUShares = cmd.Int64([]string{"#c", "-cpu-shares"}, 0, "CPU shares (relative weight)") |
|
85 |
+ flCPUPeriod = cmd.Int64([]string{"-cpu-period"}, 0, "Limit CPU CFS (Completely Fair Scheduler) period") |
|
86 |
+ flCPUQuota = cmd.Int64([]string{"-cpu-quota"}, 0, "Limit CPU CFS (Completely Fair Scheduler) quota") |
|
87 |
+ flCpusetCpus = cmd.String([]string{"#-cpuset", "-cpuset-cpus"}, "", "CPUs in which to allow execution (0-3, 0,1)") |
|
88 |
+ flCpusetMems = cmd.String([]string{"-cpuset-mems"}, "", "MEMs in which to allow execution (0-3, 0,1)") |
|
89 |
+ flBlkioWeight = cmd.Int64([]string{"-blkio-weight"}, 0, "Block IO (relative weight), between 10 and 1000") |
|
90 |
+ flSwappiness = cmd.Int64([]string{"-memory-swappiness"}, -1, "Tuning container memory swappiness (0 to 100)") |
|
91 |
+ flNetMode = cmd.String([]string{"-net"}, "default", "Set the Network mode for the container") |
|
92 |
+ flMacAddress = cmd.String([]string{"-mac-address"}, "", "Container MAC address (e.g. 92:d0:c6:0a:29:33)") |
|
93 |
+ flIpcMode = cmd.String([]string{"-ipc"}, "", "IPC namespace to use") |
|
94 |
+ flRestartPolicy = cmd.String([]string{"-restart"}, "no", "Restart policy to apply when a container exits") |
|
95 |
+ flReadonlyRootfs = cmd.Bool([]string{"-read-only"}, false, "Mount the container's root filesystem as read only") |
|
96 |
+ flLoggingDriver = cmd.String([]string{"-log-driver"}, "", "Logging driver for container") |
|
97 |
+ flCgroupParent = cmd.String([]string{"-cgroup-parent"}, "", "Optional parent cgroup for the container") |
|
98 |
+ flVolumeDriver = cmd.String([]string{"-volume-driver"}, "", "Optional volume driver for the container") |
|
99 |
+ flStopSignal = cmd.String([]string{"-stop-signal"}, signal.DefaultStopSignal, fmt.Sprintf("Signal to stop a container, %v by default", signal.DefaultStopSignal)) |
|
99 | 100 |
) |
100 | 101 |
|
101 | 102 |
cmd.Var(&flAttach, []string{"a", "-attach"}, "Attach to STDIN, STDOUT or STDERR") |
... | ... |
@@ -160,6 +161,14 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe |
160 | 160 |
} |
161 | 161 |
} |
162 | 162 |
|
163 |
+ var MemoryReservation int64 |
|
164 |
+ if *flMemoryReservation != "" { |
|
165 |
+ MemoryReservation, err = units.RAMInBytes(*flMemoryReservation) |
|
166 |
+ if err != nil { |
|
167 |
+ return nil, nil, cmd, err |
|
168 |
+ } |
|
169 |
+ } |
|
170 |
+ |
|
163 | 171 |
var memorySwap int64 |
164 | 172 |
if *flMemorySwap != "" { |
165 | 173 |
if *flMemorySwap == "-1" { |
... | ... |
@@ -329,44 +338,45 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe |
329 | 329 |
} |
330 | 330 |
|
331 | 331 |
hostConfig := &HostConfig{ |
332 |
- Binds: binds, |
|
333 |
- ContainerIDFile: *flContainerIDFile, |
|
334 |
- LxcConf: lxcConf, |
|
335 |
- Memory: flMemory, |
|
336 |
- MemorySwap: memorySwap, |
|
337 |
- KernelMemory: KernelMemory, |
|
338 |
- CPUShares: *flCPUShares, |
|
339 |
- CPUPeriod: *flCPUPeriod, |
|
340 |
- CpusetCpus: *flCpusetCpus, |
|
341 |
- CpusetMems: *flCpusetMems, |
|
342 |
- CPUQuota: *flCPUQuota, |
|
343 |
- BlkioWeight: *flBlkioWeight, |
|
344 |
- OomKillDisable: *flOomKillDisable, |
|
345 |
- MemorySwappiness: flSwappiness, |
|
346 |
- Privileged: *flPrivileged, |
|
347 |
- PortBindings: portBindings, |
|
348 |
- Links: flLinks.GetAll(), |
|
349 |
- PublishAllPorts: *flPublishAll, |
|
350 |
- DNS: flDNS.GetAll(), |
|
351 |
- DNSSearch: flDNSSearch.GetAll(), |
|
352 |
- DNSOptions: flDNSOptions.GetAll(), |
|
353 |
- ExtraHosts: flExtraHosts.GetAll(), |
|
354 |
- VolumesFrom: flVolumesFrom.GetAll(), |
|
355 |
- NetworkMode: NetworkMode(*flNetMode), |
|
356 |
- IpcMode: ipcMode, |
|
357 |
- PidMode: pidMode, |
|
358 |
- UTSMode: utsMode, |
|
359 |
- Devices: deviceMappings, |
|
360 |
- CapAdd: stringutils.NewStrSlice(flCapAdd.GetAll()...), |
|
361 |
- CapDrop: stringutils.NewStrSlice(flCapDrop.GetAll()...), |
|
362 |
- GroupAdd: flGroupAdd.GetAll(), |
|
363 |
- RestartPolicy: restartPolicy, |
|
364 |
- SecurityOpt: flSecurityOpt.GetAll(), |
|
365 |
- ReadonlyRootfs: *flReadonlyRootfs, |
|
366 |
- Ulimits: flUlimits.GetList(), |
|
367 |
- LogConfig: LogConfig{Type: *flLoggingDriver, Config: loggingOpts}, |
|
368 |
- CgroupParent: *flCgroupParent, |
|
369 |
- VolumeDriver: *flVolumeDriver, |
|
332 |
+ Binds: binds, |
|
333 |
+ ContainerIDFile: *flContainerIDFile, |
|
334 |
+ LxcConf: lxcConf, |
|
335 |
+ Memory: flMemory, |
|
336 |
+ MemoryReservation: MemoryReservation, |
|
337 |
+ MemorySwap: memorySwap, |
|
338 |
+ KernelMemory: KernelMemory, |
|
339 |
+ CPUShares: *flCPUShares, |
|
340 |
+ CPUPeriod: *flCPUPeriod, |
|
341 |
+ CpusetCpus: *flCpusetCpus, |
|
342 |
+ CpusetMems: *flCpusetMems, |
|
343 |
+ CPUQuota: *flCPUQuota, |
|
344 |
+ BlkioWeight: *flBlkioWeight, |
|
345 |
+ OomKillDisable: *flOomKillDisable, |
|
346 |
+ MemorySwappiness: flSwappiness, |
|
347 |
+ Privileged: *flPrivileged, |
|
348 |
+ PortBindings: portBindings, |
|
349 |
+ Links: flLinks.GetAll(), |
|
350 |
+ PublishAllPorts: *flPublishAll, |
|
351 |
+ DNS: flDNS.GetAll(), |
|
352 |
+ DNSSearch: flDNSSearch.GetAll(), |
|
353 |
+ DNSOptions: flDNSOptions.GetAll(), |
|
354 |
+ ExtraHosts: flExtraHosts.GetAll(), |
|
355 |
+ VolumesFrom: flVolumesFrom.GetAll(), |
|
356 |
+ NetworkMode: NetworkMode(*flNetMode), |
|
357 |
+ IpcMode: ipcMode, |
|
358 |
+ PidMode: pidMode, |
|
359 |
+ UTSMode: utsMode, |
|
360 |
+ Devices: deviceMappings, |
|
361 |
+ CapAdd: stringutils.NewStrSlice(flCapAdd.GetAll()...), |
|
362 |
+ CapDrop: stringutils.NewStrSlice(flCapDrop.GetAll()...), |
|
363 |
+ GroupAdd: flGroupAdd.GetAll(), |
|
364 |
+ RestartPolicy: restartPolicy, |
|
365 |
+ SecurityOpt: flSecurityOpt.GetAll(), |
|
366 |
+ ReadonlyRootfs: *flReadonlyRootfs, |
|
367 |
+ Ulimits: flUlimits.GetList(), |
|
368 |
+ LogConfig: LogConfig{Type: *flLoggingDriver, Config: loggingOpts}, |
|
369 |
+ CgroupParent: *flCgroupParent, |
|
370 |
+ VolumeDriver: *flVolumeDriver, |
|
370 | 371 |
} |
371 | 372 |
|
372 | 373 |
applyExperimentalFlags(expFlags, config, hostConfig) |