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:
parent
ea3ac621e3
commit
f023816608
9 changed files with 69 additions and 0 deletions
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
49
integration/container/run_linux_test.go
Normal file
49
integration/container/run_linux_test.go
Normal 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())))
|
||||
}
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue