8000 Add memory.kernelTCP support for linux by yongtang · Pull Request #37043 · moby/moby · GitHub
[go: up one dir, main page]

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions api/server/router/container/container_routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,12 @@ func (s *containerRouter) postContainersCreate(ctx context.Context, w http.Respo
}
}

// When using API 1.39 and under, KernelMemoryTCP should be ignored because it
// was added in API 1.40.
if hostConfig != nil && versions.LessThan(version, "1.40") {
hostConfig.KernelMemoryTCP = 0
}

ccr, err := s.backend.ContainerCreate(types.ContainerCreateConfig{
Name: name,
Config: config,
Expand Down
4 changes: 4 additions & 0 deletions api/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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."
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

" in bytes" ?

type: "integer"
format: "int64"
MemoryReservation:
description: "Memory soft limit in bytes."
type: "integer"
Expand Down
1 change: 1 addition & 0 deletions api/types/container/host_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

" (in bytes)" ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ping @yongtang

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
Expand Down
1 change: 1 addition & 0 deletions api/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions daemon/daemon_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,10 @@ func getMemoryResources(config containertypes.Resources) *specs.LinuxMemory {
memory.Kernel = &config.KernelMemory
}

if config.KernelMemoryTCP != 0 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we anticipate adding this to docker container update as well, we need to think how to reset this

memory.KernelTCP = &config.KernelMemoryTCP
}

return &memory
}

Expand Down
1 change: 1 addition & 0 deletions daemon/info_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions docs/api/version-history.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
51 changes: 51 additions & 0 deletions integration/container/run_linux_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
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/api/types/versions"
"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")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably add a skip for API < 1.40 as well

skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.40"), "skip test from new feature")
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())))
}
3 changes: 3 additions & 0 deletions pkg/sysinfo/sysinfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
5 changes: 5 additions & 0 deletions pkg/sysinfo/sysinfo_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -103,6 +107,7 @@ func checkCgroupMem(cgMounts map[string]string, quiet bool) cgroupMemInfo {
OomKillDisable: oomKillDisable,
MemorySwappiness: memorySwappiness,
KernelMemory: kernelMemory,
KernelMemoryTCP: kernelMemoryTCP,
}
}

Expand Down
0