Add memory.kernelTCP support for linux

This fix tries to address the issue raised in 37038 where
there were no memory.kernelTCP support for linux.

This fix add MemoryKernelTCP to HostConfig, and pass
the config to runtime-spec.

Additional test case has been added.

This fix fixes 37038.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
This commit is contained in:
Yong Tang 2018-05-11 19:46:11 +00:00
parent ea3ac621e3
commit f023816608
9 changed files with 69 additions and 0 deletions

View file

@ -429,6 +429,10 @@ definitions:
description: "Kernel memory limit in bytes."
type: "integer"
format: "int64"
KernelMemoryTCP:
description: "Sets hard limit for kernel TCP buffer memory."
type: "integer"
format: "int64"
MemoryReservation:
description: "Memory soft limit in bytes."
type: "integer"

View file

@ -329,6 +329,7 @@ type Resources struct {
DeviceCgroupRules []string // List of rule to be added to the device cgroup
DiskQuota int64 // Disk limit (in bytes)
KernelMemory int64 // Kernel memory limit (in bytes)
KernelMemoryTCP int64 // Sets hard limit for kernel TCP buffer memory
MemoryReservation int64 // Memory soft limit (in bytes)
MemorySwap int64 // Total memory usage (memory + swap); set `-1` to enable unlimited swap
MemorySwappiness *int64 // Tuning container memory swappiness behaviour

View file

@ -158,6 +158,7 @@ type Info struct {
MemoryLimit bool
SwapLimit bool
KernelMemory bool
KernelMemoryTCP bool
CPUCfsPeriod bool `json:"CpuCfsPeriod"`
CPUCfsQuota bool `json:"CpuCfsQuota"`
CPUShares bool

View file

@ -111,6 +111,10 @@ func getMemoryResources(config containertypes.Resources) *specs.LinuxMemory {
memory.Kernel = &config.KernelMemory
}
if config.KernelMemoryTCP != 0 {
memory.KernelTCP = &config.KernelMemoryTCP
}
return &memory
}

View file

@ -20,6 +20,7 @@ func (daemon *Daemon) fillPlatformInfo(v *types.Info, sysInfo *sysinfo.SysInfo)
v.MemoryLimit = sysInfo.MemoryLimit
v.SwapLimit = sysInfo.SwapLimit
v.KernelMemory = sysInfo.KernelMemory
v.KernelMemoryTCP = sysInfo.KernelMemoryTCP
v.OomKillDisable = sysInfo.OomKillDisable
v.CPUCfsPeriod = sysInfo.CPUCfsPeriod
v.CPUCfsQuota = sysInfo.CPUCfsQuota

View file

@ -32,6 +32,7 @@ keywords: "API, Docker, rcli, REST, documentation"
* `POST /swarm/init` now accepts a `DataPathPort` property to set data path port number.
* `GET /info` now returns information about `DataPathPort` that is currently used in swarm
* `GET /swarm` endpoint now returns DataPathPort info
* `POST /containers/create` now takes `KernelMemoryTCP` field to set hard limit for kernel TCP buffer memory.
## V1.39 API changes

View file

@ -0,0 +1,49 @@
package container // import "github.com/docker/docker/integration/container"
import (
"context"
"strconv"
"strings"
"testing"
"time"
containertypes "github.com/docker/docker/api/types/container"
"github.com/docker/docker/integration/internal/container"
"github.com/docker/docker/internal/test/request"
"gotest.tools/assert"
is "gotest.tools/assert/cmp"
"gotest.tools/poll"
"gotest.tools/skip"
)
func TestKernelTCPMemory(t *testing.T) {
skip.If(t, testEnv.DaemonInfo.OSType != "linux")
skip.If(t, !testEnv.DaemonInfo.KernelMemoryTCP)
defer setupTest(t)()
client := request.NewAPIClient(t)
ctx := context.Background()
const (
kernelMemoryTCP int64 = 200 * 1024 * 1024
)
cID := container.Run(t, ctx, client, func(c *container.TestContainerConfig) {
c.HostConfig.Resources = containertypes.Resources{
KernelMemoryTCP: kernelMemoryTCP,
}
})
poll.WaitOn(t, container.IsInState(ctx, client, cID, "running"), poll.WithDelay(100*time.Millisecond))
inspect, err := client.ContainerInspect(ctx, cID)
assert.NilError(t, err)
assert.Check(t, is.Equal(kernelMemoryTCP, inspect.HostConfig.KernelMemoryTCP))
res, err := container.Exec(ctx, client, cID,
[]string{"cat", "/sys/fs/cgroup/memory/memory.kmem.tcp.limit_in_bytes"})
assert.NilError(t, err)
assert.Assert(t, is.Len(res.Stderr(), 0))
assert.Equal(t, 0, res.ExitCode)
assert.Check(t, is.Equal(strconv.FormatInt(kernelMemoryTCP, 10), strings.TrimSpace(res.Stdout())))
}

View file

@ -47,6 +47,9 @@ type cgroupMemInfo struct {
// Whether kernel memory limit is supported or not
KernelMemory bool
// Whether kernel memory TCP limit is supported or not
KernelMemoryTCP bool
}
type cgroupCPUInfo struct {

View file

@ -95,6 +95,10 @@ func checkCgroupMem(cgMounts map[string]string, quiet bool) cgroupMemInfo {
if !quiet && !kernelMemory {
logrus.Warn("Your kernel does not support kernel memory limit")
}
kernelMemoryTCP := cgroupEnabled(mountPoint, "memory.kmem.tcp.limit_in_bytes")
if !quiet && !kernelMemoryTCP {
logrus.Warn("Your kernel does not support kernel memory TCP limit")
}
return cgroupMemInfo{
MemoryLimit: true,
@ -103,6 +107,7 @@ func checkCgroupMem(cgMounts map[string]string, quiet bool) cgroupMemInfo {
OomKillDisable: oomKillDisable,
MemorySwappiness: memorySwappiness,
KernelMemory: kernelMemory,
KernelMemoryTCP: kernelMemoryTCP,
}
}