Skip to content

Commit

Permalink
Use soft docker memory limit instead of hard one
Browse files Browse the repository at this point in the history
  • Loading branch information
Andrei Burd committed Jul 26, 2017
1 parent c0ce263 commit 9abdb01
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ IMPROVEMENTS:
* driver/docker: Add `driver.docker.bridge_ip` node attribute [GH-2797]
* driver/docker: Allow setting container IP with user defined networks
[GH-2535]
* driver/docker: Allow using soft memory limit instead of hard one [GH-2771]
* driver/rkt: Support `no_overlay` [GH-2702]
* driver/rkt: Support `insecure_options` list [GH-2695]
* server: Allow tuning of node heartbeat TTLs [GH-2859]
Expand Down
18 changes: 16 additions & 2 deletions client/driver/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ type DockerDriverConfig struct {
ForcePull bool `mapstructure:"force_pull"` // Always force pull before running image, useful if your tags are mutable
MacAddress string `mapstructure:"mac_address"` // Pin mac address to container
SecurityOpt []string `mapstructure:"security_opt"` // Flags to pass directly to security-opt
MemLimitDisable bool `mapstructure:"mem_limit_disable"` // Use soft memory limit instead of hard
}

// Validate validates a docker driver config
Expand Down Expand Up @@ -458,6 +459,9 @@ func (d *DockerDriver) Validate(config map[string]interface{}) error {
"security_opt": &fields.FieldSchema{
Type: fields.TypeArray,
},
"mem_limit_disable": &fields.FieldSchema{
Type: fields.TypeBool,
},
},
}

Expand Down Expand Up @@ -870,7 +874,15 @@ func (d *DockerDriver) createContainerConfig(ctx *ExecContext, task *structs.Tas
config.WorkingDir = driverConfig.WorkDir
}

memLimit := int64(task.Resources.MemoryMB) * 1024 * 1024
var memLimit, memReservation int64

taskMemReserved := int64(task.Resources.MemoryMB) * 1024 * 1024

if driverConfig.MemLimitDisable {
memReservation = taskMemReserved
} else {
memLimit = taskMemReserved
}

if len(driverConfig.Logging) == 0 {
if runtime.GOOS != "darwin" {
Expand All @@ -885,7 +897,9 @@ func (d *DockerDriver) createContainerConfig(ctx *ExecContext, task *structs.Tas

hostConfig := &docker.HostConfig{
// Convert MB to bytes. This is an absolute value.
Memory: memLimit,

Memory: memLimit,
MemoryReservation: memReservation,
// Convert Mhz to shares. This is a relative value.
CPUShares: int64(task.Resources.CPU),

Expand Down
39 changes: 39 additions & 0 deletions client/driver/docker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -797,6 +797,45 @@ func TestDockerDriver_Labels(t *testing.T) {
}
}

func TestDockerDriver_MemLimitDisable_IsInvalidConfig(t *testing.T) {
task, _, _ := dockerTask()
task.Config["mem_limit_disable"] = "nothing"

ctx := testDockerDriverContexts(t, task)
defer ctx.AllocDir.Destroy()
driver := NewDockerDriver(ctx.DriverCtx)

if _, err := driver.Prestart(ctx.ExecCtx, task); err == nil {
t.Fatalf("error expected in prestart")
}
}

func TestDockerDriver_MemLimitDisable(t *testing.T) {
task, _, _ := dockerTask()
task.Config["mem_limit_disable"] = "true"

client, handle, cleanup := dockerSetup(t, task)
defer cleanup()

waitForExist(t, client, handle.(*DockerHandle))

container, err := client.InspectContainer(handle.(*DockerHandle).ContainerID())
if err != nil {
t.Fatalf("err: %v", err)
}

actualMemory := container.HostConfig.Memory
actualMemoryReservation := container.HostConfig.MemoryReservation

if actualMemory != 0 {
t.Fatalf("Got Memory Limit %q; want 0", actualMemory)
}

if actualMemoryReservation == 0 {
t.Fatalf("Got Memory Reservation 0; want %q", actualMemoryReservation)
}
}

func TestDockerDriver_ForcePull_IsInvalidConfig(t *testing.T) {
if !tu.IsTravis() {
t.Parallel()
Expand Down
2 changes: 2 additions & 0 deletions website/source/docs/drivers/docker.html.md
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,8 @@ The `docker` driver supports the following configuration in the job spec. Only

* `work_dir` - (Optional) The working directory inside the container.

* `mem_limit_disable` - (Optional) `true` or `false` (default). Run docker container with soft memory limit instead of hard limit.

### Container Name

Nomad creates a container after pulling an image. Containers are named
Expand Down

0 comments on commit 9abdb01

Please sign in to comment.