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

Merge pull request #14579 from hqhq/hq_add_softlimit

Add support for memory reservation
This commit is contained in:
Jess Frazelle 2015-09-24 12:11:36 -07:00
commit 84b53c8d87
18 changed files with 260 additions and 140 deletions

View file

@ -1151,6 +1151,7 @@ _docker_run() {
--memory -m --memory -m
--memory-swap --memory-swap
--memory-swappiness --memory-swappiness
--memory-reservation
--name --name
--net --net
--pid --pid

View file

@ -272,18 +272,19 @@ func populateCommand(c *Container, env []string) error {
} }
resources := &execdriver.Resources{ resources := &execdriver.Resources{
Memory: c.hostConfig.Memory, Memory: c.hostConfig.Memory,
MemorySwap: c.hostConfig.MemorySwap, MemorySwap: c.hostConfig.MemorySwap,
KernelMemory: c.hostConfig.KernelMemory, MemoryReservation: c.hostConfig.MemoryReservation,
CPUShares: c.hostConfig.CPUShares, KernelMemory: c.hostConfig.KernelMemory,
CpusetCpus: c.hostConfig.CpusetCpus, CPUShares: c.hostConfig.CPUShares,
CpusetMems: c.hostConfig.CpusetMems, CpusetCpus: c.hostConfig.CpusetCpus,
CPUPeriod: c.hostConfig.CPUPeriod, CpusetMems: c.hostConfig.CpusetMems,
CPUQuota: c.hostConfig.CPUQuota, CPUPeriod: c.hostConfig.CPUPeriod,
BlkioWeight: c.hostConfig.BlkioWeight, CPUQuota: c.hostConfig.CPUQuota,
Rlimits: rlimits, BlkioWeight: c.hostConfig.BlkioWeight,
OomKillDisable: c.hostConfig.OomKillDisable, Rlimits: rlimits,
MemorySwappiness: -1, OomKillDisable: c.hostConfig.OomKillDisable,
MemorySwappiness: -1,
} }
if c.hostConfig.MemorySwappiness != nil { if c.hostConfig.MemorySwappiness != nil {

View file

@ -110,6 +110,9 @@ func (daemon *Daemon) adaptContainerSettings(hostConfig *runconfig.HostConfig, a
// By default, MemorySwap is set to twice the size of Memory. // By default, MemorySwap is set to twice the size of Memory.
hostConfig.MemorySwap = hostConfig.Memory * 2 hostConfig.MemorySwap = hostConfig.Memory * 2
} }
if hostConfig.MemoryReservation == 0 && hostConfig.Memory > 0 {
hostConfig.MemoryReservation = hostConfig.Memory
}
} }
// verifyPlatformContainerSettings performs platform-specific validation of the // verifyPlatformContainerSettings performs platform-specific validation of the
@ -154,6 +157,14 @@ func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *runconfig.HostC
return warnings, fmt.Errorf("Invalid value: %v, valid memory swappiness range is 0-100.", swappiness) return warnings, fmt.Errorf("Invalid value: %v, valid memory swappiness range is 0-100.", swappiness)
} }
} }
if hostConfig.MemoryReservation > 0 && !sysInfo.MemoryReservation {
warnings = append(warnings, "Your kernel does not support memory soft limit capabilities. Limitation discarded.")
logrus.Warnf("Your kernel does not support memory soft limit capabilities. Limitation discarded.")
hostConfig.MemoryReservation = 0
}
if hostConfig.Memory > 0 && hostConfig.MemoryReservation > 0 && hostConfig.Memory < hostConfig.MemoryReservation {
return warnings, fmt.Errorf("Minimum memory limit should be larger than memory reservation limit, see usage.")
}
if hostConfig.KernelMemory > 0 && !sysInfo.KernelMemory { if hostConfig.KernelMemory > 0 && !sysInfo.KernelMemory {
warnings = append(warnings, "Your kernel does not support kernel memory limit capabilities. Limitation discarded.") warnings = append(warnings, "Your kernel does not support kernel memory limit capabilities. Limitation discarded.")
logrus.Warnf("Your kernel does not support kernel memory limit capabilities. Limitation discarded.") logrus.Warnf("Your kernel does not support kernel memory limit capabilities. Limitation discarded.")

View file

@ -141,18 +141,19 @@ type UTS struct {
// Currently these are all for cgroup configs. // Currently these are all for cgroup configs.
// TODO Windows: Factor out ulimit.Rlimit // TODO Windows: Factor out ulimit.Rlimit
type Resources struct { type Resources struct {
Memory int64 `json:"memory"` Memory int64 `json:"memory"`
MemorySwap int64 `json:"memory_swap"` MemorySwap int64 `json:"memory_swap"`
KernelMemory int64 `json:"kernel_memory"` MemoryReservation int64 `json:"memory_reservation"`
CPUShares int64 `json:"cpu_shares"` KernelMemory int64 `json:"kernel_memory"`
CpusetCpus string `json:"cpuset_cpus"` CPUShares int64 `json:"cpu_shares"`
CpusetMems string `json:"cpuset_mems"` CpusetCpus string `json:"cpuset_cpus"`
CPUPeriod int64 `json:"cpu_period"` CpusetMems string `json:"cpuset_mems"`
CPUQuota int64 `json:"cpu_quota"` CPUPeriod int64 `json:"cpu_period"`
BlkioWeight int64 `json:"blkio_weight"` CPUQuota int64 `json:"cpu_quota"`
Rlimits []*ulimit.Rlimit `json:"rlimits"` BlkioWeight int64 `json:"blkio_weight"`
OomKillDisable bool `json:"oom_kill_disable"` Rlimits []*ulimit.Rlimit `json:"rlimits"`
MemorySwappiness int64 `json:"memory_swappiness"` OomKillDisable bool `json:"oom_kill_disable"`
MemorySwappiness int64 `json:"memory_swappiness"`
} }
// ResourceStats contains information about resource usage by a container. // ResourceStats contains information about resource usage by a container.

View file

@ -64,7 +64,7 @@ func SetupCgroups(container *configs.Config, c *Command) error {
if c.Resources != nil { if c.Resources != nil {
container.Cgroups.CpuShares = c.Resources.CPUShares container.Cgroups.CpuShares = c.Resources.CPUShares
container.Cgroups.Memory = c.Resources.Memory container.Cgroups.Memory = c.Resources.Memory
container.Cgroups.MemoryReservation = c.Resources.Memory container.Cgroups.MemoryReservation = c.Resources.MemoryReservation
container.Cgroups.MemorySwap = c.Resources.MemorySwap container.Cgroups.MemorySwap = c.Resources.MemorySwap
container.Cgroups.CpusetCpus = c.Resources.CpusetCpus container.Cgroups.CpusetCpus = c.Resources.CpusetCpus
container.Cgroups.CpusetMems = c.Resources.CpusetMems container.Cgroups.CpusetMems = c.Resources.CpusetMems

View file

@ -91,11 +91,13 @@ lxc.mount.entry = {{$value.Source}} {{escapeFstabSpaces $ROOTFS}}/{{escapeFstabS
{{if .Resources}} {{if .Resources}}
{{if .Resources.Memory}} {{if .Resources.Memory}}
lxc.cgroup.memory.limit_in_bytes = {{.Resources.Memory}} lxc.cgroup.memory.limit_in_bytes = {{.Resources.Memory}}
lxc.cgroup.memory.soft_limit_in_bytes = {{.Resources.Memory}}
{{with $memSwap := getMemorySwap .Resources}} {{with $memSwap := getMemorySwap .Resources}}
lxc.cgroup.memory.memsw.limit_in_bytes = {{$memSwap}} lxc.cgroup.memory.memsw.limit_in_bytes = {{$memSwap}}
{{end}} {{end}}
{{end}} {{end}}
{{if gt .Resources.MemoryReservation 0}}
lxc.cgroup.memory.soft_limit_in_bytes = {{.Resources.MemoryReservation}}
{{end}}
{{if gt .Resources.KernelMemory 0}} {{if gt .Resources.KernelMemory 0}}
lxc.cgroup.memory.kmem.limit_in_bytes = {{.Resources.KernelMemory}} lxc.cgroup.memory.kmem.limit_in_bytes = {{.Resources.KernelMemory}}
{{end}} {{end}}

View file

@ -173,6 +173,7 @@ Create a container
"LxcConf": {"lxc.utsname":"docker"}, "LxcConf": {"lxc.utsname":"docker"},
"Memory": 0, "Memory": 0,
"MemorySwap": 0, "MemorySwap": 0,
"MemoryReservation": 0,
"KernelMemory": 0, "KernelMemory": 0,
"CpuShares": 512, "CpuShares": 512,
"CpuPeriod": 100000, "CpuPeriod": 100000,
@ -223,6 +224,7 @@ Json Parameters:
- **Memory** - Memory limit in bytes. - **Memory** - Memory limit in bytes.
- **MemorySwap** - Total memory limit (memory + swap); set `-1` to disable swap - **MemorySwap** - Total memory limit (memory + swap); set `-1` to disable swap
You must use this with `memory` and make the swap value larger than `memory`. You must use this with `memory` and make the swap value larger than `memory`.
- **MemoryReservation** - Memory soft limit in bytes.
- **KernelMemory** - Kernel memory limit in bytes. - **KernelMemory** - Kernel memory limit in bytes.
- **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).
@ -398,6 +400,7 @@ Return low-level information on the container `id`
"LxcConf": [], "LxcConf": [],
"Memory": 0, "Memory": 0,
"MemorySwap": 0, "MemorySwap": 0,
"MemoryReservation": 0,
"KernelMemory": 0, "KernelMemory": 0,
"OomKillDisable": false, "OomKillDisable": false,
"NetworkMode": "bridge", "NetworkMode": "bridge",

View file

@ -50,6 +50,7 @@ Creates a new container.
--lxc-conf=[] Add custom lxc options --lxc-conf=[] Add custom lxc options
-m, --memory="" Memory limit -m, --memory="" Memory limit
--mac-address="" Container MAC address (e.g. 92:d0:c6:0a:29:33) --mac-address="" Container MAC address (e.g. 92:d0:c6:0a:29:33)
--memory-reservation="" Memory soft limit
--memory-swap="" Total memory (memory + swap), '-1' to disable swap --memory-swap="" Total memory (memory + swap), '-1' to disable swap
--memory-swappiness="" Tune a container's memory swappiness behavior. Accepts an integer between 0 and 100. --memory-swappiness="" Tune a container's memory swappiness behavior. Accepts an integer between 0 and 100.
--name="" Assign a name to the container --name="" Assign a name to the container

View file

@ -50,6 +50,7 @@ weight=1
--lxc-conf=[] Add custom lxc options --lxc-conf=[] Add custom lxc options
-m, --memory="" Memory limit -m, --memory="" Memory limit
--mac-address="" Container MAC address (e.g. 92:d0:c6:0a:29:33) --mac-address="" Container MAC address (e.g. 92:d0:c6:0a:29:33)
--memory-reservation="" Memory soft limit
--memory-swap="" Total memory (memory + swap), '-1' to disable swap --memory-swap="" Total memory (memory + swap), '-1' to disable swap
--memory-swappiness="" Tune a container's memory swappiness behavior. Accepts an integer between 0 and 100. --memory-swappiness="" Tune a container's memory swappiness behavior. Accepts an integer between 0 and 100.
--name="" Assign a name to the container --name="" Assign a name to the container

View file

@ -544,6 +544,7 @@ container:
|----------------------------|---------------------------------------------------------------------------------------------| |----------------------------|---------------------------------------------------------------------------------------------|
| `-m`, `--memory="" ` | Memory limit (format: `<number>[<unit>]`, where unit = b, k, m or g) | | `-m`, `--memory="" ` | Memory limit (format: `<number>[<unit>]`, where unit = b, k, m or g) |
| `--memory-swap=""` | Total memory limit (memory + swap, format: `<number>[<unit>]`, where unit = b, k, m or g) | | `--memory-swap=""` | Total memory limit (memory + swap, format: `<number>[<unit>]`, where unit = b, k, m or g) |
| `--memory-reservation=""` | Memory soft limit (format: `<number>[<unit>]`, where unit = b, k, m or g) |
| `--kernel-memory=""` | Kernel memory limit (format: `<number>[<unit>]`, where unit = b, k, m or g) | | `--kernel-memory=""` | Kernel memory limit (format: `<number>[<unit>]`, where unit = b, k, m or g) |
| `-c`, `--cpu-shares=0` | CPU shares (relative weight) | | `-c`, `--cpu-shares=0` | CPU shares (relative weight) |
| `--cpu-period=0` | Limit the CPU CFS (Completely Fair Scheduler) period | | `--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.
We set both memory and swap memory, so the processes in the container can use We set both memory and swap memory, so the processes in the container can use
300M memory and 700M swap memory. 300M memory and 700M swap memory.
Memory reservation is a kind of memory soft limit that allows for greater
sharing of memory. Under normal circumstances, containers can use as much of
the memory as needed and are constrained only by the hard limits set with the
`-m`/`--memory` option. When memory reservation is set, Docker detects memory
contention or low memory and forces containers to restrict their consumption to
a reservation limit.
Always set the memory reservation value below the hard limit, otherwise the hard
limit takes precedence. A reservation of 0 is the same as setting no
reservation. By default (without reservation set), memory reservation is the
same as the hard memory limit.
Memory reservation is a soft-limit feature and does not guarantee the limit
won't be exceeded. Instead, the feature attempts to ensure that, when memory is
heavily contended for, memory is allocated based on the reservation hints/setup.
The following example limits the memory (`-m`) to 500M and sets the memory
reservation to 200M.
```bash
$ docker run -ti -m 500M --memory-reservation 200M ubuntu:14.04 /bin/bash
```
Under this configuration, when the container consumes memory more than 200M and
less than 500M, the next system memory reclaim attempts to shrink container
memory below 200M.
The following example set memory reservation to 1G without a hard memory limit.
```bash
$ docker run -ti --memory-reservation 1G ubuntu:14.04 /bin/bash
```
The container can use as much memory as it needs. The memory reservation setting
ensures the container doesn't consume too much memory for long time, because
every memory reclaim shrinks the container's consumption to the reservation.
By default, kernel kills processes in a container if an out-of-memory (OOM) By default, kernel kills processes in a container if an out-of-memory (OOM)
error occurs. To change this behaviour, use the `--oom-kill-disable` option. error occurs. To change this behaviour, use the `--oom-kill-disable` option.
Only disable the OOM killer on containers where you have also set the Only disable the OOM killer on containers where you have also set the

View file

@ -327,6 +327,22 @@ func (s *DockerSuite) TestRunWithSwappinessInvalid(c *check.C) {
} }
} }
func (s *DockerSuite) TestRunWithMemoryReservation(c *check.C) {
testRequires(c, memoryReservationSupport)
dockerCmd(c, "run", "--memory-reservation", "200M", "busybox", "true")
}
func (s *DockerSuite) TestRunWithMemoryReservationInvalid(c *check.C) {
testRequires(c, memoryLimitSupport)
testRequires(c, memoryReservationSupport)
out, _, err := dockerCmdWithError("run", "-m", "500M", "--memory-reservation", "800M", "busybox", "true")
c.Assert(err, check.NotNil)
expected := "Minimum memory limit should be larger than memory reservation limit"
if !strings.Contains(strings.TrimSpace(out), expected) {
c.Fatalf("run container should fail with invalid memory reservation, output: %q", out)
}
}
func (s *DockerSuite) TestStopContainerSignal(c *check.C) { func (s *DockerSuite) TestStopContainerSignal(c *check.C) {
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`) 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`)
containerID := strings.TrimSpace(out) containerID := strings.TrimSpace(out)

View file

@ -45,6 +45,12 @@ var (
}, },
"Test requires an environment that supports cgroup memory limit.", "Test requires an environment that supports cgroup memory limit.",
} }
memoryReservationSupport = testRequirement{
func() bool {
return SysInfo.MemoryReservation
},
"Test requires an environment that supports cgroup memory reservation.",
}
swapMemorySupport = testRequirement{ swapMemorySupport = testRequirement{
func() bool { func() bool {
return SysInfo.SwapLimit return SysInfo.SwapLimit

View file

@ -40,6 +40,7 @@ docker-create - Create a new container
[**--lxc-conf**[=*[]*]] [**--lxc-conf**[=*[]*]]
[**-m**|**--memory**[=*MEMORY*]] [**-m**|**--memory**[=*MEMORY*]]
[**--mac-address**[=*MAC-ADDRESS*]] [**--mac-address**[=*MAC-ADDRESS*]]
[**--memory-reservation**[=*MEMORY-RESERVATION*]]
[**--memory-swap**[=*MEMORY-SWAP*]] [**--memory-swap**[=*MEMORY-SWAP*]]
[**--memory-swappiness**[=*MEMORY-SWAPPINESS*]] [**--memory-swappiness**[=*MEMORY-SWAPPINESS*]]
[**--name**[=*NAME*]] [**--name**[=*NAME*]]
@ -196,6 +197,15 @@ system's page size (the value would be very large, that's millions of trillions)
**--mac-address**="" **--mac-address**=""
Container MAC address (e.g. 92:d0:c6:0a:29:33) Container MAC address (e.g. 92:d0:c6:0a:29:33)
**--memory-reservation**=""
Memory soft limit (format: <number>[<unit>], where unit = b, k, m or g)
After setting memory reservation, when the system detects memory contention
or low memory, containers are forced to restrict their consumption to their
reservation. So you should always set the value below **--memory**, otherwise the
hard limit will take precedence. By default, memory reservation will be the same
as memory limit.
**--memory-swap**="" **--memory-swap**=""
Total memory limit (memory + swap) Total memory limit (memory + swap)

View file

@ -41,6 +41,7 @@ docker-run - Run a command in a new container
[**--lxc-conf**[=*[]*]] [**--lxc-conf**[=*[]*]]
[**-m**|**--memory**[=*MEMORY*]] [**-m**|**--memory**[=*MEMORY*]]
[**--mac-address**[=*MAC-ADDRESS*]] [**--mac-address**[=*MAC-ADDRESS*]]
[**--memory-reservation**[=*MEMORY-RESERVATION*]]
[**--memory-swap**[=*MEMORY-SWAP*]] [**--memory-swap**[=*MEMORY-SWAP*]]
[**--memory-swappiness**[=*MEMORY-SWAPPINESS*]] [**--memory-swappiness**[=*MEMORY-SWAPPINESS*]]
[**--name**[=*NAME*]] [**--name**[=*NAME*]]
@ -290,6 +291,15 @@ RAM. If a limit of 0 is specified (not using **-m**), the container's memory is
not limited. The actual limit may be rounded up to a multiple of the operating not limited. The actual limit may be rounded up to a multiple of the operating
system's page size (the value would be very large, that's millions of trillions). system's page size (the value would be very large, that's millions of trillions).
**--memory-reservation**=""
Memory soft limit (format: <number>[<unit>], where unit = b, k, m or g)
After setting memory reservation, when the system detects memory contention
or low memory, containers are forced to restrict their consumption to their
reservation. So you should always set the value below **--memory**, otherwise the
hard limit will take precedence. By default, memory reservation will be the same
as memory limit.
**--memory-swap**="" **--memory-swap**=""
Total memory limit (memory + swap) Total memory limit (memory + swap)

View file

@ -31,6 +31,9 @@ type cgroupMemInfo struct {
// Whether swap limit is supported or not // Whether swap limit is supported or not
SwapLimit bool SwapLimit bool
// Whether soft limit is supported or not
MemoryReservation bool
// Whether OOM killer disalbe is supported or not // Whether OOM killer disalbe is supported or not
OomKillDisable bool OomKillDisable bool

View file

@ -49,6 +49,10 @@ func checkCgroupMem(quiet bool) cgroupMemInfo {
if !quiet && !swapLimit { if !quiet && !swapLimit {
logrus.Warn("Your kernel does not support swap memory limit.") logrus.Warn("Your kernel does not support swap memory limit.")
} }
memoryReservation := cgroupEnabled(mountPoint, "memory.soft_limit_in_bytes")
if !quiet && !memoryReservation {
logrus.Warn("Your kernel does not support memory reservation.")
}
oomKillDisable := cgroupEnabled(mountPoint, "memory.oom_control") oomKillDisable := cgroupEnabled(mountPoint, "memory.oom_control")
if !quiet && !oomKillDisable { if !quiet && !oomKillDisable {
logrus.Warnf("Your kernel does not support oom control.") logrus.Warnf("Your kernel does not support oom control.")
@ -63,11 +67,12 @@ func checkCgroupMem(quiet bool) cgroupMemInfo {
} }
return cgroupMemInfo{ return cgroupMemInfo{
MemoryLimit: true, MemoryLimit: true,
SwapLimit: swapLimit, SwapLimit: swapLimit,
OomKillDisable: oomKillDisable, MemoryReservation: memoryReservation,
MemorySwappiness: memorySwappiness, OomKillDisable: oomKillDisable,
KernelMemory: kernelMemory, MemorySwappiness: memorySwappiness,
KernelMemory: kernelMemory,
} }
} }

View file

@ -214,45 +214,46 @@ func NewLxcConfig(values []KeyValuePair) *LxcConfig {
// Here, "non-portable" means "dependent of the host we are running on". // Here, "non-portable" means "dependent of the host we are running on".
// Portable information *should* appear in Config. // Portable information *should* appear in Config.
type HostConfig struct { type HostConfig struct {
Binds []string // List of volume bindings for this container Binds []string // List of volume bindings for this container
ContainerIDFile string // File (path) where the containerId is written ContainerIDFile string // File (path) where the containerId is written
LxcConf *LxcConfig // Additional lxc configuration LxcConf *LxcConfig // Additional lxc configuration
Memory int64 // Memory limit (in bytes) Memory int64 // Memory limit (in bytes)
MemorySwap int64 // Total memory usage (memory + swap); set `-1` to disable swap MemoryReservation int64 // Memory soft limit (in bytes)
KernelMemory int64 // Kernel memory limit (in bytes) MemorySwap int64 // Total memory usage (memory + swap); set `-1` to disable swap
CPUShares int64 `json:"CpuShares"` // CPU shares (relative weight vs. other containers) KernelMemory int64 // Kernel memory limit (in bytes)
CPUPeriod int64 `json:"CpuPeriod"` // CPU CFS (Completely Fair Scheduler) period CPUShares int64 `json:"CpuShares"` // CPU shares (relative weight vs. other containers)
CpusetCpus string // CpusetCpus 0-2, 0,1 CPUPeriod int64 `json:"CpuPeriod"` // CPU CFS (Completely Fair Scheduler) period
CpusetMems string // CpusetMems 0-2, 0,1 CpusetCpus string // CpusetCpus 0-2, 0,1
CPUQuota int64 `json:"CpuQuota"` // CPU CFS (Completely Fair Scheduler) quota CpusetMems string // CpusetMems 0-2, 0,1
BlkioWeight int64 // Block IO weight (relative weight vs. other containers) CPUQuota int64 `json:"CpuQuota"` // CPU CFS (Completely Fair Scheduler) quota
OomKillDisable bool // Whether to disable OOM Killer or not BlkioWeight int64 // Block IO weight (relative weight vs. other containers)
MemorySwappiness *int64 // Tuning container memory swappiness behaviour OomKillDisable bool // Whether to disable OOM Killer or not
Privileged bool // Is the container in privileged mode MemorySwappiness *int64 // Tuning container memory swappiness behaviour
PortBindings nat.PortMap // Port mapping between the exposed port (container) and the host Privileged bool // Is the container in privileged mode
Links []string // List of links (in the name:alias form) PortBindings nat.PortMap // Port mapping between the exposed port (container) and the host
PublishAllPorts bool // Should docker publish all exposed port for the container Links []string // List of links (in the name:alias form)
DNS []string `json:"Dns"` // List of DNS server to lookup PublishAllPorts bool // Should docker publish all exposed port for the container
DNSOptions []string `json:"DnsOptions"` // List of DNSOption to look for DNS []string `json:"Dns"` // List of DNS server to lookup
DNSSearch []string `json:"DnsSearch"` // List of DNSSearch to look for DNSOptions []string `json:"DnsOptions"` // List of DNSOption to look for
ExtraHosts []string // List of extra hosts DNSSearch []string `json:"DnsSearch"` // List of DNSSearch to look for
VolumesFrom []string // List of volumes to take from other container ExtraHosts []string // List of extra hosts
Devices []DeviceMapping // List of devices to map inside the container VolumesFrom []string // List of volumes to take from other container
NetworkMode NetworkMode // Network namespace to use for the container Devices []DeviceMapping // List of devices to map inside the container
IpcMode IpcMode // IPC namespace to use for the container NetworkMode NetworkMode // Network namespace to use for the container
PidMode PidMode // PID namespace to use for the container IpcMode IpcMode // IPC namespace to use for the container
UTSMode UTSMode // UTS namespace to use for the container PidMode PidMode // PID namespace to use for the container
CapAdd *stringutils.StrSlice // List of kernel capabilities to add to the container UTSMode UTSMode // UTS namespace to use for the container
CapDrop *stringutils.StrSlice // List of kernel capabilities to remove from the container CapAdd *stringutils.StrSlice // List of kernel capabilities to add to the container
GroupAdd []string // List of additional groups that the container process will run as CapDrop *stringutils.StrSlice // List of kernel capabilities to remove from the container
RestartPolicy RestartPolicy // Restart policy to be used for the container GroupAdd []string // List of additional groups that the container process will run as
SecurityOpt []string // List of string values to customize labels for MLS systems, such as SELinux. RestartPolicy RestartPolicy // Restart policy to be used for the container
ReadonlyRootfs bool // Is the container root filesystem in read-only SecurityOpt []string // List of string values to customize labels for MLS systems, such as SELinux.
Ulimits []*ulimit.Ulimit // List of ulimits to be set in the container ReadonlyRootfs bool // Is the container root filesystem in read-only
LogConfig LogConfig // Configuration of the logs for this container Ulimits []*ulimit.Ulimit // List of ulimits to be set in the container
CgroupParent string // Parent cgroup. LogConfig LogConfig // Configuration of the logs for this container
ConsoleSize [2]int // Initial console size on Windows CgroupParent string // Parent cgroup.
VolumeDriver string // Name of the volume driver used to mount volumes ConsoleSize [2]int // Initial console size on Windows
VolumeDriver string // Name of the volume driver used to mount volumes
} }
// DecodeHostConfig creates a HostConfig based on the specified Reader. // DecodeHostConfig creates a HostConfig based on the specified Reader.

View file

@ -64,38 +64,39 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
flLabelsFile = opts.NewListOpts(nil) flLabelsFile = opts.NewListOpts(nil)
flLoggingOpts = opts.NewListOpts(nil) flLoggingOpts = opts.NewListOpts(nil)
flNetwork = cmd.Bool([]string{"#n", "#-networking"}, true, "Enable networking for this container") flNetwork = cmd.Bool([]string{"#n", "#-networking"}, true, "Enable networking for this container")
flPrivileged = cmd.Bool([]string{"#privileged", "-privileged"}, false, "Give extended privileges to this container") flPrivileged = cmd.Bool([]string{"#privileged", "-privileged"}, false, "Give extended privileges to this container")
flPidMode = cmd.String([]string{"-pid"}, "", "PID namespace to use") flPidMode = cmd.String([]string{"-pid"}, "", "PID namespace to use")
flUTSMode = cmd.String([]string{"-uts"}, "", "UTS namespace to use") flUTSMode = cmd.String([]string{"-uts"}, "", "UTS namespace to use")
flPublishAll = cmd.Bool([]string{"P", "-publish-all"}, false, "Publish all exposed ports to random ports") flPublishAll = cmd.Bool([]string{"P", "-publish-all"}, false, "Publish all exposed ports to random ports")
flStdin = cmd.Bool([]string{"i", "-interactive"}, false, "Keep STDIN open even if not attached") flStdin = cmd.Bool([]string{"i", "-interactive"}, false, "Keep STDIN open even if not attached")
flTty = cmd.Bool([]string{"t", "-tty"}, false, "Allocate a pseudo-TTY") flTty = cmd.Bool([]string{"t", "-tty"}, false, "Allocate a pseudo-TTY")
flOomKillDisable = cmd.Bool([]string{"-oom-kill-disable"}, false, "Disable OOM Killer") flOomKillDisable = cmd.Bool([]string{"-oom-kill-disable"}, false, "Disable OOM Killer")
flContainerIDFile = cmd.String([]string{"#cidfile", "-cidfile"}, "", "Write the container ID to the file") flContainerIDFile = cmd.String([]string{"#cidfile", "-cidfile"}, "", "Write the container ID to the file")
flEntrypoint = cmd.String([]string{"#entrypoint", "-entrypoint"}, "", "Overwrite the default ENTRYPOINT of the image") flEntrypoint = cmd.String([]string{"#entrypoint", "-entrypoint"}, "", "Overwrite the default ENTRYPOINT of the image")
flHostname = cmd.String([]string{"h", "-hostname"}, "", "Container host name") flHostname = cmd.String([]string{"h", "-hostname"}, "", "Container host name")
flMemoryString = cmd.String([]string{"m", "-memory"}, "", "Memory limit") flMemoryString = cmd.String([]string{"m", "-memory"}, "", "Memory limit")
flMemorySwap = cmd.String([]string{"-memory-swap"}, "", "Total memory (memory + swap), '-1' to disable swap") flMemoryReservation = cmd.String([]string{"-memory-reservation"}, "", "Memory soft limit")
flKernelMemory = cmd.String([]string{"-kernel-memory"}, "", "Kernel memory limit") flMemorySwap = cmd.String([]string{"-memory-swap"}, "", "Total memory (memory + swap), '-1' to disable swap")
flUser = cmd.String([]string{"u", "-user"}, "", "Username or UID (format: <name|uid>[:<group|gid>])") flKernelMemory = cmd.String([]string{"-kernel-memory"}, "", "Kernel memory limit")
flWorkingDir = cmd.String([]string{"w", "-workdir"}, "", "Working directory inside the container") flUser = cmd.String([]string{"u", "-user"}, "", "Username or UID (format: <name|uid>[:<group|gid>])")
flCPUShares = cmd.Int64([]string{"#c", "-cpu-shares"}, 0, "CPU shares (relative weight)") flWorkingDir = cmd.String([]string{"w", "-workdir"}, "", "Working directory inside the container")
flCPUPeriod = cmd.Int64([]string{"-cpu-period"}, 0, "Limit CPU CFS (Completely Fair Scheduler) period") flCPUShares = cmd.Int64([]string{"#c", "-cpu-shares"}, 0, "CPU shares (relative weight)")
flCPUQuota = cmd.Int64([]string{"-cpu-quota"}, 0, "Limit CPU CFS (Completely Fair Scheduler) quota") flCPUPeriod = cmd.Int64([]string{"-cpu-period"}, 0, "Limit CPU CFS (Completely Fair Scheduler) period")
flCpusetCpus = cmd.String([]string{"#-cpuset", "-cpuset-cpus"}, "", "CPUs in which to allow execution (0-3, 0,1)") flCPUQuota = cmd.Int64([]string{"-cpu-quota"}, 0, "Limit CPU CFS (Completely Fair Scheduler) quota")
flCpusetMems = cmd.String([]string{"-cpuset-mems"}, "", "MEMs in which to allow execution (0-3, 0,1)") flCpusetCpus = cmd.String([]string{"#-cpuset", "-cpuset-cpus"}, "", "CPUs in which to allow execution (0-3, 0,1)")
flBlkioWeight = cmd.Int64([]string{"-blkio-weight"}, 0, "Block IO (relative weight), between 10 and 1000") flCpusetMems = cmd.String([]string{"-cpuset-mems"}, "", "MEMs in which to allow execution (0-3, 0,1)")
flSwappiness = cmd.Int64([]string{"-memory-swappiness"}, -1, "Tuning container memory swappiness (0 to 100)") flBlkioWeight = cmd.Int64([]string{"-blkio-weight"}, 0, "Block IO (relative weight), between 10 and 1000")
flNetMode = cmd.String([]string{"-net"}, "default", "Set the Network mode for the container") flSwappiness = cmd.Int64([]string{"-memory-swappiness"}, -1, "Tuning container memory swappiness (0 to 100)")
flMacAddress = cmd.String([]string{"-mac-address"}, "", "Container MAC address (e.g. 92:d0:c6:0a:29:33)") flNetMode = cmd.String([]string{"-net"}, "default", "Set the Network mode for the container")
flIpcMode = cmd.String([]string{"-ipc"}, "", "IPC namespace to use") flMacAddress = cmd.String([]string{"-mac-address"}, "", "Container MAC address (e.g. 92:d0:c6:0a:29:33)")
flRestartPolicy = cmd.String([]string{"-restart"}, "no", "Restart policy to apply when a container exits") flIpcMode = cmd.String([]string{"-ipc"}, "", "IPC namespace to use")
flReadonlyRootfs = cmd.Bool([]string{"-read-only"}, false, "Mount the container's root filesystem as read only") flRestartPolicy = cmd.String([]string{"-restart"}, "no", "Restart policy to apply when a container exits")
flLoggingDriver = cmd.String([]string{"-log-driver"}, "", "Logging driver for container") flReadonlyRootfs = cmd.Bool([]string{"-read-only"}, false, "Mount the container's root filesystem as read only")
flCgroupParent = cmd.String([]string{"-cgroup-parent"}, "", "Optional parent cgroup for the container") flLoggingDriver = cmd.String([]string{"-log-driver"}, "", "Logging driver for container")
flVolumeDriver = cmd.String([]string{"-volume-driver"}, "", "Optional volume driver for the container") flCgroupParent = cmd.String([]string{"-cgroup-parent"}, "", "Optional parent cgroup for the container")
flStopSignal = cmd.String([]string{"-stop-signal"}, signal.DefaultStopSignal, fmt.Sprintf("Signal to stop a container, %v by default", signal.DefaultStopSignal)) flVolumeDriver = cmd.String([]string{"-volume-driver"}, "", "Optional volume driver for the container")
flStopSignal = cmd.String([]string{"-stop-signal"}, signal.DefaultStopSignal, fmt.Sprintf("Signal to stop a container, %v by default", signal.DefaultStopSignal))
) )
cmd.Var(&flAttach, []string{"a", "-attach"}, "Attach to STDIN, STDOUT or STDERR") 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
} }
} }
var MemoryReservation int64
if *flMemoryReservation != "" {
MemoryReservation, err = units.RAMInBytes(*flMemoryReservation)
if err != nil {
return nil, nil, cmd, err
}
}
var memorySwap int64 var memorySwap int64
if *flMemorySwap != "" { if *flMemorySwap != "" {
if *flMemorySwap == "-1" { if *flMemorySwap == "-1" {
@ -329,44 +338,45 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
} }
hostConfig := &HostConfig{ hostConfig := &HostConfig{
Binds: binds, Binds: binds,
ContainerIDFile: *flContainerIDFile, ContainerIDFile: *flContainerIDFile,
LxcConf: lxcConf, LxcConf: lxcConf,
Memory: flMemory, Memory: flMemory,
MemorySwap: memorySwap, MemoryReservation: MemoryReservation,
KernelMemory: KernelMemory, MemorySwap: memorySwap,
CPUShares: *flCPUShares, KernelMemory: KernelMemory,
CPUPeriod: *flCPUPeriod, CPUShares: *flCPUShares,
CpusetCpus: *flCpusetCpus, CPUPeriod: *flCPUPeriod,
CpusetMems: *flCpusetMems, CpusetCpus: *flCpusetCpus,
CPUQuota: *flCPUQuota, CpusetMems: *flCpusetMems,
BlkioWeight: *flBlkioWeight, CPUQuota: *flCPUQuota,
OomKillDisable: *flOomKillDisable, BlkioWeight: *flBlkioWeight,
MemorySwappiness: flSwappiness, OomKillDisable: *flOomKillDisable,
Privileged: *flPrivileged, MemorySwappiness: flSwappiness,
PortBindings: portBindings, Privileged: *flPrivileged,
Links: flLinks.GetAll(), PortBindings: portBindings,
PublishAllPorts: *flPublishAll, Links: flLinks.GetAll(),
DNS: flDNS.GetAll(), PublishAllPorts: *flPublishAll,
DNSSearch: flDNSSearch.GetAll(), DNS: flDNS.GetAll(),
DNSOptions: flDNSOptions.GetAll(), DNSSearch: flDNSSearch.GetAll(),
ExtraHosts: flExtraHosts.GetAll(), DNSOptions: flDNSOptions.GetAll(),
VolumesFrom: flVolumesFrom.GetAll(), ExtraHosts: flExtraHosts.GetAll(),
NetworkMode: NetworkMode(*flNetMode), VolumesFrom: flVolumesFrom.GetAll(),
IpcMode: ipcMode, NetworkMode: NetworkMode(*flNetMode),
PidMode: pidMode, IpcMode: ipcMode,
UTSMode: utsMode, PidMode: pidMode,
Devices: deviceMappings, UTSMode: utsMode,
CapAdd: stringutils.NewStrSlice(flCapAdd.GetAll()...), Devices: deviceMappings,
CapDrop: stringutils.NewStrSlice(flCapDrop.GetAll()...), CapAdd: stringutils.NewStrSlice(flCapAdd.GetAll()...),
GroupAdd: flGroupAdd.GetAll(), CapDrop: stringutils.NewStrSlice(flCapDrop.GetAll()...),
RestartPolicy: restartPolicy, GroupAdd: flGroupAdd.GetAll(),
SecurityOpt: flSecurityOpt.GetAll(), RestartPolicy: restartPolicy,
ReadonlyRootfs: *flReadonlyRootfs, SecurityOpt: flSecurityOpt.GetAll(),
Ulimits: flUlimits.GetList(), ReadonlyRootfs: *flReadonlyRootfs,
LogConfig: LogConfig{Type: *flLoggingDriver, Config: loggingOpts}, Ulimits: flUlimits.GetList(),
CgroupParent: *flCgroupParent, LogConfig: LogConfig{Type: *flLoggingDriver, Config: loggingOpts},
VolumeDriver: *flVolumeDriver, CgroupParent: *flCgroupParent,
VolumeDriver: *flVolumeDriver,
} }
applyExperimentalFlags(expFlags, config, hostConfig) applyExperimentalFlags(expFlags, config, hostConfig)