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
Родитель a7e8f3616c aa1780997f
Коммит 84b53c8d87
18 изменённых файлов: 260 добавлений и 140 удалений

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

@ -110,6 +110,9 @@ func (daemon *Daemon) adaptContainerSettings(hostConfig *runconfig.HostConfig, a
// By default, MemorySwap is set to twice the size of Memory.
hostConfig.MemorySwap = hostConfig.Memory * 2
}
if hostConfig.MemoryReservation == 0 && hostConfig.Memory > 0 {
hostConfig.MemoryReservation = hostConfig.Memory
}
}
// 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)
}
}
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 {
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.")

Просмотреть файл

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

Просмотреть файл

@ -64,7 +64,7 @@ func SetupCgroups(container *configs.Config, c *Command) error {
if c.Resources != nil {
container.Cgroups.CpuShares = c.Resources.CPUShares
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.CpusetCpus = c.Resources.CpusetCpus
container.Cgroups.CpusetMems = c.Resources.CpusetMems

Просмотреть файл

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

Просмотреть файл

@ -173,6 +173,7 @@ Create a container
"LxcConf": {"lxc.utsname":"docker"},
"Memory": 0,
"MemorySwap": 0,
"MemoryReservation": 0,
"KernelMemory": 0,
"CpuShares": 512,
"CpuPeriod": 100000,
@ -223,6 +224,7 @@ Json Parameters:
- **Memory** - Memory limit in bytes.
- **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`.
- **MemoryReservation** - Memory soft limit in bytes.
- **KernelMemory** - Kernel memory limit in bytes.
- **CpuShares** - An integer value containing the container's CPU Shares
(ie. the relative weight vs other containers).
@ -398,6 +400,7 @@ Return low-level information on the container `id`
"LxcConf": [],
"Memory": 0,
"MemorySwap": 0,
"MemoryReservation": 0,
"KernelMemory": 0,
"OomKillDisable": false,
"NetworkMode": "bridge",

Просмотреть файл

@ -50,6 +50,7 @@ Creates a new container.
--lxc-conf=[] Add custom lxc options
-m, --memory="" Memory limit
--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-swappiness="" Tune a container's memory swappiness behavior. Accepts an integer between 0 and 100.
--name="" Assign a name to the container

Просмотреть файл

@ -50,6 +50,7 @@ weight=1
--lxc-conf=[] Add custom lxc options
-m, --memory="" Memory limit
--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-swappiness="" Tune a container's memory swappiness behavior. Accepts an integer between 0 and 100.
--name="" Assign a name to the container

Просмотреть файл

@ -544,6 +544,7 @@ container:
|----------------------------|---------------------------------------------------------------------------------------------|
| `-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-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) |
| `-c`, `--cpu-shares=0` | CPU shares (relative weight) |
| `--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
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)
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

Просмотреть файл

@ -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) {
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)

Просмотреть файл

@ -45,6 +45,12 @@ var (
},
"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{
func() bool {
return SysInfo.SwapLimit

Просмотреть файл

@ -40,6 +40,7 @@ docker-create - Create a new container
[**--lxc-conf**[=*[]*]]
[**-m**|**--memory**[=*MEMORY*]]
[**--mac-address**[=*MAC-ADDRESS*]]
[**--memory-reservation**[=*MEMORY-RESERVATION*]]
[**--memory-swap**[=*MEMORY-SWAP*]]
[**--memory-swappiness**[=*MEMORY-SWAPPINESS*]]
[**--name**[=*NAME*]]
@ -196,6 +197,15 @@ system's page size (the value would be very large, that's millions of trillions)
**--mac-address**=""
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**=""
Total memory limit (memory + swap)

Просмотреть файл

@ -41,6 +41,7 @@ docker-run - Run a command in a new container
[**--lxc-conf**[=*[]*]]
[**-m**|**--memory**[=*MEMORY*]]
[**--mac-address**[=*MAC-ADDRESS*]]
[**--memory-reservation**[=*MEMORY-RESERVATION*]]
[**--memory-swap**[=*MEMORY-SWAP*]]
[**--memory-swappiness**[=*MEMORY-SWAPPINESS*]]
[**--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
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**=""
Total memory limit (memory + swap)

Просмотреть файл

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

Просмотреть файл

@ -49,6 +49,10 @@ func checkCgroupMem(quiet bool) cgroupMemInfo {
if !quiet && !swapLimit {
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")
if !quiet && !oomKillDisable {
logrus.Warnf("Your kernel does not support oom control.")
@ -63,11 +67,12 @@ func checkCgroupMem(quiet bool) cgroupMemInfo {
}
return cgroupMemInfo{
MemoryLimit: true,
SwapLimit: swapLimit,
OomKillDisable: oomKillDisable,
MemorySwappiness: memorySwappiness,
KernelMemory: kernelMemory,
MemoryLimit: true,
SwapLimit: swapLimit,
MemoryReservation: memoryReservation,
OomKillDisable: oomKillDisable,
MemorySwappiness: memorySwappiness,
KernelMemory: kernelMemory,
}
}

Просмотреть файл

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

Просмотреть файл

@ -64,38 +64,39 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
flLabelsFile = opts.NewListOpts(nil)
flLoggingOpts = opts.NewListOpts(nil)
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")
flPidMode = cmd.String([]string{"-pid"}, "", "PID 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")
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")
flOomKillDisable = cmd.Bool([]string{"-oom-kill-disable"}, false, "Disable OOM Killer")
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")
flHostname = cmd.String([]string{"h", "-hostname"}, "", "Container host name")
flMemoryString = cmd.String([]string{"m", "-memory"}, "", "Memory limit")
flMemorySwap = cmd.String([]string{"-memory-swap"}, "", "Total memory (memory + swap), '-1' to disable swap")
flKernelMemory = cmd.String([]string{"-kernel-memory"}, "", "Kernel memory limit")
flUser = cmd.String([]string{"u", "-user"}, "", "Username or UID (format: <name|uid>[:<group|gid>])")
flWorkingDir = cmd.String([]string{"w", "-workdir"}, "", "Working directory inside the container")
flCPUShares = cmd.Int64([]string{"#c", "-cpu-shares"}, 0, "CPU shares (relative weight)")
flCPUPeriod = cmd.Int64([]string{"-cpu-period"}, 0, "Limit CPU CFS (Completely Fair Scheduler) period")
flCPUQuota = cmd.Int64([]string{"-cpu-quota"}, 0, "Limit CPU CFS (Completely Fair Scheduler) quota")
flCpusetCpus = cmd.String([]string{"#-cpuset", "-cpuset-cpus"}, "", "CPUs in which to allow execution (0-3, 0,1)")
flCpusetMems = cmd.String([]string{"-cpuset-mems"}, "", "MEMs in which to allow execution (0-3, 0,1)")
flBlkioWeight = cmd.Int64([]string{"-blkio-weight"}, 0, "Block IO (relative weight), between 10 and 1000")
flSwappiness = cmd.Int64([]string{"-memory-swappiness"}, -1, "Tuning container memory swappiness (0 to 100)")
flNetMode = cmd.String([]string{"-net"}, "default", "Set the Network mode for the container")
flMacAddress = cmd.String([]string{"-mac-address"}, "", "Container MAC address (e.g. 92:d0:c6:0a:29:33)")
flIpcMode = cmd.String([]string{"-ipc"}, "", "IPC namespace to use")
flRestartPolicy = cmd.String([]string{"-restart"}, "no", "Restart policy to apply when a container exits")
flReadonlyRootfs = cmd.Bool([]string{"-read-only"}, false, "Mount the container's root filesystem as read only")
flLoggingDriver = cmd.String([]string{"-log-driver"}, "", "Logging driver for container")
flCgroupParent = cmd.String([]string{"-cgroup-parent"}, "", "Optional parent cgroup for the container")
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))
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")
flPidMode = cmd.String([]string{"-pid"}, "", "PID 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")
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")
flOomKillDisable = cmd.Bool([]string{"-oom-kill-disable"}, false, "Disable OOM Killer")
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")
flHostname = cmd.String([]string{"h", "-hostname"}, "", "Container host name")
flMemoryString = cmd.String([]string{"m", "-memory"}, "", "Memory limit")
flMemoryReservation = cmd.String([]string{"-memory-reservation"}, "", "Memory soft limit")
flMemorySwap = cmd.String([]string{"-memory-swap"}, "", "Total memory (memory + swap), '-1' to disable swap")
flKernelMemory = cmd.String([]string{"-kernel-memory"}, "", "Kernel memory limit")
flUser = cmd.String([]string{"u", "-user"}, "", "Username or UID (format: <name|uid>[:<group|gid>])")
flWorkingDir = cmd.String([]string{"w", "-workdir"}, "", "Working directory inside the container")
flCPUShares = cmd.Int64([]string{"#c", "-cpu-shares"}, 0, "CPU shares (relative weight)")
flCPUPeriod = cmd.Int64([]string{"-cpu-period"}, 0, "Limit CPU CFS (Completely Fair Scheduler) period")
flCPUQuota = cmd.Int64([]string{"-cpu-quota"}, 0, "Limit CPU CFS (Completely Fair Scheduler) quota")
flCpusetCpus = cmd.String([]string{"#-cpuset", "-cpuset-cpus"}, "", "CPUs in which to allow execution (0-3, 0,1)")
flCpusetMems = cmd.String([]string{"-cpuset-mems"}, "", "MEMs in which to allow execution (0-3, 0,1)")
flBlkioWeight = cmd.Int64([]string{"-blkio-weight"}, 0, "Block IO (relative weight), between 10 and 1000")
flSwappiness = cmd.Int64([]string{"-memory-swappiness"}, -1, "Tuning container memory swappiness (0 to 100)")
flNetMode = cmd.String([]string{"-net"}, "default", "Set the Network mode for the container")
flMacAddress = cmd.String([]string{"-mac-address"}, "", "Container MAC address (e.g. 92:d0:c6:0a:29:33)")
flIpcMode = cmd.String([]string{"-ipc"}, "", "IPC namespace to use")
flRestartPolicy = cmd.String([]string{"-restart"}, "no", "Restart policy to apply when a container exits")
flReadonlyRootfs = cmd.Bool([]string{"-read-only"}, false, "Mount the container's root filesystem as read only")
flLoggingDriver = cmd.String([]string{"-log-driver"}, "", "Logging driver for container")
flCgroupParent = cmd.String([]string{"-cgroup-parent"}, "", "Optional parent cgroup for the container")
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")
@ -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
if *flMemorySwap != "" {
if *flMemorySwap == "-1" {
@ -329,44 +338,45 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
}
hostConfig := &HostConfig{
Binds: binds,
ContainerIDFile: *flContainerIDFile,
LxcConf: lxcConf,
Memory: flMemory,
MemorySwap: memorySwap,
KernelMemory: KernelMemory,
CPUShares: *flCPUShares,
CPUPeriod: *flCPUPeriod,
CpusetCpus: *flCpusetCpus,
CpusetMems: *flCpusetMems,
CPUQuota: *flCPUQuota,
BlkioWeight: *flBlkioWeight,
OomKillDisable: *flOomKillDisable,
MemorySwappiness: flSwappiness,
Privileged: *flPrivileged,
PortBindings: portBindings,
Links: flLinks.GetAll(),
PublishAllPorts: *flPublishAll,
DNS: flDNS.GetAll(),
DNSSearch: flDNSSearch.GetAll(),
DNSOptions: flDNSOptions.GetAll(),
ExtraHosts: flExtraHosts.GetAll(),
VolumesFrom: flVolumesFrom.GetAll(),
NetworkMode: NetworkMode(*flNetMode),
IpcMode: ipcMode,
PidMode: pidMode,
UTSMode: utsMode,
Devices: deviceMappings,
CapAdd: stringutils.NewStrSlice(flCapAdd.GetAll()...),
CapDrop: stringutils.NewStrSlice(flCapDrop.GetAll()...),
GroupAdd: flGroupAdd.GetAll(),
RestartPolicy: restartPolicy,
SecurityOpt: flSecurityOpt.GetAll(),
ReadonlyRootfs: *flReadonlyRootfs,
Ulimits: flUlimits.GetList(),
LogConfig: LogConfig{Type: *flLoggingDriver, Config: loggingOpts},
CgroupParent: *flCgroupParent,
VolumeDriver: *flVolumeDriver,
Binds: binds,
ContainerIDFile: *flContainerIDFile,
LxcConf: lxcConf,
Memory: flMemory,
MemoryReservation: MemoryReservation,
MemorySwap: memorySwap,
KernelMemory: KernelMemory,
CPUShares: *flCPUShares,
CPUPeriod: *flCPUPeriod,
CpusetCpus: *flCpusetCpus,
CpusetMems: *flCpusetMems,
CPUQuota: *flCPUQuota,
BlkioWeight: *flBlkioWeight,
OomKillDisable: *flOomKillDisable,
MemorySwappiness: flSwappiness,
Privileged: *flPrivileged,
PortBindings: portBindings,
Links: flLinks.GetAll(),
PublishAllPorts: *flPublishAll,
DNS: flDNS.GetAll(),
DNSSearch: flDNSSearch.GetAll(),
DNSOptions: flDNSOptions.GetAll(),
ExtraHosts: flExtraHosts.GetAll(),
VolumesFrom: flVolumesFrom.GetAll(),
NetworkMode: NetworkMode(*flNetMode),
IpcMode: ipcMode,
PidMode: pidMode,
UTSMode: utsMode,
Devices: deviceMappings,
CapAdd: stringutils.NewStrSlice(flCapAdd.GetAll()...),
CapDrop: stringutils.NewStrSlice(flCapDrop.GetAll()...),
GroupAdd: flGroupAdd.GetAll(),
RestartPolicy: restartPolicy,
SecurityOpt: flSecurityOpt.GetAll(),
ReadonlyRootfs: *flReadonlyRootfs,
Ulimits: flUlimits.GetList(),
LogConfig: LogConfig{Type: *flLoggingDriver, Config: loggingOpts},
CgroupParent: *flCgroupParent,
VolumeDriver: *flVolumeDriver,
}
applyExperimentalFlags(expFlags, config, hostConfig)