Skip to content

Commit ead37eb

Browse files
committed
Merge pull request #2239 from adnxn/coveord-allow-unbounded-ram-tasks-windows
2 parents 6989a51 + 541f0d5 commit ead37eb

File tree

6 files changed

+86
-3
lines changed

6 files changed

+86
-3
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ additional details on each available environment variable.
170170
| `ECS_CGROUP_PATH` | `/sys/fs/cgroup` | The root cgroup path that is expected by the ECS agent. This is the path that accessible from the agent mount. | `/sys/fs/cgroup` | Not applicable |
171171
| `ECS_CGROUP_CPU_PERIOD` | `10ms` | CGroups CPU period for task level limits. This value should be between 8ms to 100ms | `100ms` | Not applicable |
172172
| `ECS_ENABLE_CPU_UNBOUNDED_WINDOWS_WORKAROUND` | `true` | When `true`, ECS will allow CPU unbounded(CPU=`0`) tasks to run along with CPU bounded tasks in Windows. | Not applicable | `false` |
173+
| `ECS_ENABLE_MEMORY_UNBOUNDED_WINDOWS_WORKAROUND` | `true` | When `true`, ECS will ignore the memory reservation parameter (soft limit) to run along with memory bounded tasks in Windows. To run a memory unbounded task, omit the memory hard limit and set any memory reservation, it will be ignored. | Not applicable | `false` |
173174
| `ECS_TASK_METADATA_RPS_LIMIT` | `100,150` | Comma separated integer values for steady state and burst throttle limits for task metadata endpoint | `40,60` | `40,60` |
174175
| `ECS_SHARED_VOLUME_MATCH_FULL_CONFIG` | `true` | When `true`, ECS Agent will compare name, driver options, and labels to make sure volumes are identical. When `false`, Agent will short circuit shared volume comparison if the names match. This is the default Docker behavior. If a volume is shared across instances, this should be set to `false`. | `false` | `false`|
175176
| `ECS_CONTAINER_INSTANCE_PROPAGATE_TAGS_FROM` | `ec2_instance` | If `ec2_instance` is specified, existing tags defined on the container instance will be registered to Amazon ECS and will be discoverable using the `ListTagsForResource` API. Using this requires that the IAM role associated with the container instance have the `ec2:DescribeTags` action allowed. | `none` | `none` |

agent/api/task/task_windows.go

+12-1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ type PlatformFields struct {
4242
// CpuUnbounded determines whether a mix of unbounded and bounded CPU tasks
4343
// are allowed to run in the instance
4444
CpuUnbounded bool `json:"cpuUnbounded"`
45+
// MemoryUnbounded determines whether a mix of unbounded and bounded Memory tasks
46+
// are allowed to run in the instance
47+
MemoryUnbounded bool `json:"memoryUnbounded"`
4548
}
4649

4750
var cpuShareScaleFactor = runtime.NumCPU() * cpuSharesPerCore
@@ -50,7 +53,8 @@ var cpuShareScaleFactor = runtime.NumCPU() * cpuSharesPerCore
5053
func (task *Task) adjustForPlatform(cfg *config.Config) {
5154
task.downcaseAllVolumePaths()
5255
platformFields := PlatformFields{
53-
CpuUnbounded: cfg.PlatformVariables.CPUUnbounded,
56+
CpuUnbounded: cfg.PlatformVariables.CPUUnbounded,
57+
MemoryUnbounded: cfg.PlatformVariables.MemoryUnbounded,
5458
}
5559
task.PlatformFields = platformFields
5660
}
@@ -119,6 +123,13 @@ func (task *Task) platformHostConfigOverride(hostConfig *dockercontainer.HostCon
119123
hostConfig.CPUPercent = minimumCPUPercent
120124
}
121125
hostConfig.CPUShares = 0
126+
127+
if hostConfig.Memory <= 0 && task.PlatformFields.MemoryUnbounded {
128+
// As of version 17.06.2-ee-6 of docker. MemoryReservation is not supported on windows. This ensures that
129+
// this parameter is not passed, allowing to launch a container without a hard limit.
130+
hostConfig.MemoryReservation = 0
131+
}
132+
122133
return nil
123134
}
124135

agent/api/task/task_windows_test.go

+47
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ import (
3535

3636
const (
3737
minDockerClientAPIVersion = dockerclient.Version_1_24
38+
39+
nonZeroMemoryReservationValue = 1
40+
expectedMemoryReservationValue = 0
3841
)
3942

4043
func TestPostUnmarshalWindowsCanonicalPaths(t *testing.T) {
@@ -254,6 +257,50 @@ func TestCPUPercentBasedOnUnboundedEnabled(t *testing.T) {
254257
}
255258
}
256259

260+
func TestWindowsMemoryReservationOption(t *testing.T) {
261+
// Testing sending a task to windows overriding MemoryReservation value
262+
rawHostConfigInput := dockercontainer.HostConfig{
263+
Resources: dockercontainer.Resources{
264+
MemoryReservation: nonZeroMemoryReservationValue,
265+
},
266+
}
267+
268+
rawHostConfig, err := json.Marshal(&rawHostConfigInput)
269+
if err != nil {
270+
t.Fatal(err)
271+
}
272+
273+
testTask := &Task{
274+
Arn: "arn:aws:ecs:us-east-1:012345678910:task/c09f0188-7f87-4b0f-bfc3-16296622b6fe",
275+
Family: "myFamily",
276+
Version: "1",
277+
Containers: []*apicontainer.Container{
278+
{
279+
Name: "c1",
280+
DockerConfig: apicontainer.DockerConfig{
281+
HostConfig: strptr(string(rawHostConfig)),
282+
},
283+
},
284+
},
285+
PlatformFields: PlatformFields{
286+
MemoryUnbounded: false,
287+
},
288+
}
289+
290+
// With MemoryUnbounded set to false, MemoryReservation is not overridden
291+
config, configErr := testTask.DockerHostConfig(testTask.Containers[0], dockerMap(testTask), defaultDockerClientAPIVersion)
292+
293+
assert.Nil(t, configErr)
294+
assert.EqualValues(t, nonZeroMemoryReservationValue, config.MemoryReservation)
295+
296+
// With MemoryUnbounded set to true, tasks with no memory hard limit will have their memory reservation set to zero
297+
testTask.PlatformFields.MemoryUnbounded = true
298+
config, configErr = testTask.DockerHostConfig(testTask.Containers[0], dockerMap(testTask), defaultDockerClientAPIVersion)
299+
300+
assert.Nil(t, configErr)
301+
assert.EqualValues(t, expectedMemoryReservationValue, config.MemoryReservation)
302+
}
303+
257304
func TestGetCanonicalPath(t *testing.T) {
258305
testcases := []struct {
259306
name string

agent/config/config_windows.go

+6-2
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ func DefaultConfig() Config {
5858
ecsRoot := filepath.Join(programData, "Amazon", "ECS")
5959
dataDir := filepath.Join(ecsRoot, "data")
6060
platformVariables := PlatformVariables{
61-
CPUUnbounded: false,
61+
CPUUnbounded: false,
62+
MemoryUnbounded: false,
6263
}
6364
return Config{
6465
DockerEndpoint: "npipe:////./pipe/docker_engine",
@@ -118,8 +119,11 @@ func (cfg *Config) platformOverrides() {
118119
cfg.TaskCPUMemLimit = ExplicitlyDisabled
119120

120121
cpuUnbounded := utils.ParseBool(os.Getenv("ECS_ENABLE_CPU_UNBOUNDED_WINDOWS_WORKAROUND"), false)
122+
memoryUnbounded := utils.ParseBool(os.Getenv("ECS_ENABLE_MEMORY_UNBOUNDED_WINDOWS_WORKAROUND"), false)
123+
121124
platformVariables := PlatformVariables{
122-
CPUUnbounded: cpuUnbounded,
125+
CPUUnbounded: cpuUnbounded,
126+
MemoryUnbounded: memoryUnbounded,
123127
}
124128
cfg.PlatformVariables = platformVariables
125129
}

agent/config/config_windows_test.go

+17
Original file line numberDiff line numberDiff line change
@@ -113,3 +113,20 @@ func TestCPUUnboundedWindowsDisabled(t *testing.T) {
113113
assert.NoError(t, err)
114114
assert.False(t, cfg.PlatformVariables.CPUUnbounded)
115115
}
116+
117+
func TestMemoryUnboundedSet(t *testing.T) {
118+
defer setTestRegion()()
119+
defer setTestEnv("ECS_ENABLE_MEMORY_UNBOUNDED_WINDOWS_WORKAROUND", "true")()
120+
cfg, err := NewConfig(ec2.NewBlackholeEC2MetadataClient())
121+
cfg.platformOverrides()
122+
assert.NoError(t, err)
123+
assert.True(t, cfg.PlatformVariables.MemoryUnbounded)
124+
}
125+
126+
func TestMemoryUnboundedWindowsDisabled(t *testing.T) {
127+
defer setTestRegion()()
128+
cfg, err := NewConfig(ec2.NewBlackholeEC2MetadataClient())
129+
cfg.platformOverrides()
130+
assert.NoError(t, err)
131+
assert.False(t, cfg.PlatformVariables.MemoryUnbounded)
132+
}

agent/config/types_windows.go

+3
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,7 @@ type PlatformVariables struct {
1919
// CPUUnbounded specifies if agent can run a mix of CPU bounded and
2020
// unbounded tasks for windows
2121
CPUUnbounded bool
22+
// MemoryUnbounded specifies if agent can run a mix of Memory bounded and
23+
// unbounded tasks for windows
24+
MemoryUnbounded bool
2225
}

0 commit comments

Comments
 (0)