mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
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."
|
description: "Kernel memory limit in bytes."
|
||||||
type: "integer"
|
type: "integer"
|
||||||
format: "int64"
|
format: "int64"
|
||||||
|
KernelMemoryTCP:
|
||||||
|
description: "Sets hard limit for kernel TCP buffer memory."
|
||||||
|
type: "integer"
|
||||||
|
format: "int64"
|
||||||
MemoryReservation:
|
MemoryReservation:
|
||||||
description: "Memory soft limit in bytes."
|
description: "Memory soft limit in bytes."
|
||||||
type: "integer"
|
type: "integer"
|
||||||
|
|
|
@ -329,6 +329,7 @@ type Resources struct {
|
||||||
DeviceCgroupRules []string // List of rule to be added to the device cgroup
|
DeviceCgroupRules []string // List of rule to be added to the device cgroup
|
||||||
DiskQuota int64 // Disk limit (in bytes)
|
DiskQuota int64 // Disk limit (in bytes)
|
||||||
KernelMemory int64 // Kernel memory 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)
|
MemoryReservation int64 // Memory soft limit (in bytes)
|
||||||
MemorySwap int64 // Total memory usage (memory + swap); set `-1` to enable unlimited swap
|
MemorySwap int64 // Total memory usage (memory + swap); set `-1` to enable unlimited swap
|
||||||
MemorySwappiness *int64 // Tuning container memory swappiness behaviour
|
MemorySwappiness *int64 // Tuning container memory swappiness behaviour
|
||||||
|
|
|
@ -158,6 +158,7 @@ type Info struct {
|
||||||
MemoryLimit bool
|
MemoryLimit bool
|
||||||
SwapLimit bool
|
SwapLimit bool
|
||||||
KernelMemory bool
|
KernelMemory bool
|
||||||
|
KernelMemoryTCP bool
|
||||||
CPUCfsPeriod bool `json:"CpuCfsPeriod"`
|
CPUCfsPeriod bool `json:"CpuCfsPeriod"`
|
||||||
CPUCfsQuota bool `json:"CpuCfsQuota"`
|
CPUCfsQuota bool `json:"CpuCfsQuota"`
|
||||||
CPUShares bool
|
CPUShares bool
|
||||||
|
|
|
@ -111,6 +111,10 @@ func getMemoryResources(config containertypes.Resources) *specs.LinuxMemory {
|
||||||
memory.Kernel = &config.KernelMemory
|
memory.Kernel = &config.KernelMemory
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if config.KernelMemoryTCP != 0 {
|
||||||
|
memory.KernelTCP = &config.KernelMemoryTCP
|
||||||
|
}
|
||||||
|
|
||||||
return &memory
|
return &memory
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ func (daemon *Daemon) fillPlatformInfo(v *types.Info, sysInfo *sysinfo.SysInfo)
|
||||||
v.MemoryLimit = sysInfo.MemoryLimit
|
v.MemoryLimit = sysInfo.MemoryLimit
|
||||||
v.SwapLimit = sysInfo.SwapLimit
|
v.SwapLimit = sysInfo.SwapLimit
|
||||||
v.KernelMemory = sysInfo.KernelMemory
|
v.KernelMemory = sysInfo.KernelMemory
|
||||||
|
v.KernelMemoryTCP = sysInfo.KernelMemoryTCP
|
||||||
v.OomKillDisable = sysInfo.OomKillDisable
|
v.OomKillDisable = sysInfo.OomKillDisable
|
||||||
v.CPUCfsPeriod = sysInfo.CPUCfsPeriod
|
v.CPUCfsPeriod = sysInfo.CPUCfsPeriod
|
||||||
v.CPUCfsQuota = sysInfo.CPUCfsQuota
|
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.
|
* `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 /info` now returns information about `DataPathPort` that is currently used in swarm
|
||||||
* `GET /swarm` endpoint now returns DataPathPort info
|
* `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
|
## 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
|
// Whether kernel memory limit is supported or not
|
||||||
KernelMemory bool
|
KernelMemory bool
|
||||||
|
|
||||||
|
// Whether kernel memory TCP limit is supported or not
|
||||||
|
KernelMemoryTCP bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type cgroupCPUInfo struct {
|
type cgroupCPUInfo struct {
|
||||||
|
|
|
@ -95,6 +95,10 @@ func checkCgroupMem(cgMounts map[string]string, quiet bool) cgroupMemInfo {
|
||||||
if !quiet && !kernelMemory {
|
if !quiet && !kernelMemory {
|
||||||
logrus.Warn("Your kernel does not support kernel memory limit")
|
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{
|
return cgroupMemInfo{
|
||||||
MemoryLimit: true,
|
MemoryLimit: true,
|
||||||
|
@ -103,6 +107,7 @@ func checkCgroupMem(cgMounts map[string]string, quiet bool) cgroupMemInfo {
|
||||||
OomKillDisable: oomKillDisable,
|
OomKillDisable: oomKillDisable,
|
||||||
MemorySwappiness: memorySwappiness,
|
MemorySwappiness: memorySwappiness,
|
||||||
KernelMemory: kernelMemory,
|
KernelMemory: kernelMemory,
|
||||||
|
KernelMemoryTCP: kernelMemoryTCP,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue