expose NOMAD_MEMORY_MAX_LIMIT env var (#10514)

Follow up to memory oversubscription - expose an env-var to indicate when memory oversubscription is enabled and what the limit is.

This will be helpful for setting hints to app for memory management.

Co-authored-by: Seth Hoenig <shoenig@hashicorp.com>
This commit is contained in:
Mahmood Ali
2021-05-05 12:09:56 -04:00
committed by GitHub
parent e15d50451b
commit fcfa5782d2
4 changed files with 39 additions and 11 deletions

View File

@@ -34,6 +34,9 @@ const (
// MemLimit is the environment variable with the tasks memory limit in MBs.
MemLimit = "NOMAD_MEMORY_LIMIT"
// MemMaxLimit is the environment variable with the tasks maximum memory limit in MBs.
MemMaxLimit = "NOMAD_MEMORY_MAX_LIMIT"
// CpuLimit is the environment variable with the tasks CPU limit in MHz.
CpuLimit = "NOMAD_CPU_LIMIT"
@@ -393,6 +396,7 @@ type Builder struct {
cpuLimit int64
memLimit int64
memMaxLimit int64
taskName string
allocIndex int
datacenter string
@@ -479,6 +483,9 @@ func (b *Builder) buildEnv(allocDir, localDir, secretsDir string,
if b.memLimit != 0 {
envMap[MemLimit] = strconv.FormatInt(b.memLimit, 10)
}
if b.memMaxLimit != 0 {
envMap[MemMaxLimit] = strconv.FormatInt(b.memMaxLimit, 10)
}
if b.cpuLimit != 0 {
envMap[CpuLimit] = strconv.FormatInt(b.cpuLimit, 10)
}
@@ -667,9 +674,11 @@ func (b *Builder) setTask(task *structs.Task) *Builder {
// COMPAT(0.11): Remove in 0.11
if task.Resources == nil {
b.memLimit = 0
b.memMaxLimit = 0
b.cpuLimit = 0
} else {
b.memLimit = int64(task.Resources.MemoryMB)
b.memMaxLimit = int64(task.Resources.MemoryMaxMB)
b.cpuLimit = int64(task.Resources.CPU)
}
return b
@@ -722,6 +731,7 @@ func (b *Builder) setAlloc(alloc *structs.Allocation) *Builder {
if tr, ok := alloc.AllocatedResources.Tasks[b.taskName]; ok {
b.cpuLimit = tr.Cpu.CpuShares
b.memLimit = tr.Memory.MemoryMB
b.memMaxLimit = tr.Memory.MemoryMaxMB
// Copy networks to prevent sharing
b.networks = make([]*structs.NetworkResource, len(tr.Networks))

View File

@@ -143,13 +143,21 @@ func TestEnvironment_AsList(t *testing.T) {
}
a := mock.Alloc()
a.Job.ParentID = fmt.Sprintf("mock-parent-service-%s", uuid.Generate())
a.AllocatedResources.Tasks["web"].Networks[0] = &structs.NetworkResource{
Device: "eth0",
IP: "127.0.0.1",
ReservedPorts: []structs.Port{{Label: "https", Value: 8080}},
MBits: 50,
DynamicPorts: []structs.Port{{Label: "http", Value: 80}},
a.AllocatedResources.Tasks["web"] = &structs.AllocatedTaskResources{
Cpu: structs.AllocatedCpuResources{CpuShares: 500},
Memory: structs.AllocatedMemoryResources{
MemoryMB: 256,
MemoryMaxMB: 512,
},
Networks: []*structs.NetworkResource{{
Device: "eth0",
IP: "127.0.0.1",
ReservedPorts: []structs.Port{{Label: "https", Value: 8080}},
MBits: 50,
DynamicPorts: []structs.Port{{Label: "http", Value: 80}},
}},
}
a.AllocatedResources.Tasks["ssh"] = &structs.AllocatedTaskResources{
Networks: []*structs.NetworkResource{
{
@@ -196,6 +204,7 @@ func TestEnvironment_AsList(t *testing.T) {
"NOMAD_NAMESPACE=not-default",
"NOMAD_REGION=global",
"NOMAD_MEMORY_LIMIT=256",
"NOMAD_MEMORY_MAX_LIMIT=512",
"NOMAD_META_ELB_CHECK_INTERVAL=30s",
"NOMAD_META_ELB_CHECK_MIN=3",
"NOMAD_META_ELB_CHECK_TYPE=http",

View File

@@ -37,11 +37,11 @@ tell you which resources have been allocated after evaluation and placement.
### CPU and Memory
Nomad will pass CPU and memory limits to your job as `NOMAD_CPU_LIMIT` and
`NOMAD_MEMORY_LIMIT`. Your task should use these values to adapt its behavior to
fit inside the resource allocation that nomad provides. For example, you can use
the memory limit to inform how large your in-process cache should be, or to
decide when to flush buffers to disk.
Nomad will pass CPU and memory limits to your job as `NOMAD_CPU_LIMIT`,
`NOMAD_MEMORY_LIMIT`, and `NOMAD_MEMORY_MAX_LIMIT`. Your task should use these
values to adapt its behavior to fit inside the resource allocation that nomad
provides. For example, you can use the memory limit to inform how large your
in-process cache should be, or to decide when to flush buffers to disk.
Both CPU and memory are presented as integers. The unit for CPU limit is
`1024 = 1GHz`. The unit for memory is `1 = 1 megabyte`.

View File

@@ -41,6 +41,15 @@
</td>
<td>Memory limit in MB for the task</td>
</tr>
<tr>
<td>
<code>NOMAD_MEMORY_MAX_LIMIT</code>
</td>
<td>
The maximum memory limit the task may use if client has excess memory
capacity, in MB. Omitted if task isn't configured with memory oversubscription.
</td>
</tr>
<tr>
<td>
<code>NOMAD_CPU_LIMIT</code>