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>
... | ... |
@@ -429,6 +429,10 @@ definitions: |
429 | 429 |
description: "Kernel memory limit in bytes." |
430 | 430 |
type: "integer" |
431 | 431 |
format: "int64" |
432 |
+ KernelMemoryTCP: |
|
433 |
+ description: "Sets hard limit for kernel TCP buffer memory." |
|
434 |
+ type: "integer" |
|
435 |
+ format: "int64" |
|
432 | 436 |
MemoryReservation: |
433 | 437 |
description: "Memory soft limit in bytes." |
434 | 438 |
type: "integer" |
... | ... |
@@ -329,6 +329,7 @@ type Resources struct { |
329 | 329 |
DeviceCgroupRules []string // List of rule to be added to the device cgroup |
330 | 330 |
DiskQuota int64 // Disk limit (in bytes) |
331 | 331 |
KernelMemory int64 // Kernel memory limit (in bytes) |
332 |
+ KernelMemoryTCP int64 // Sets hard limit for kernel TCP buffer memory |
|
332 | 333 |
MemoryReservation int64 // Memory soft limit (in bytes) |
333 | 334 |
MemorySwap int64 // Total memory usage (memory + swap); set `-1` to enable unlimited swap |
334 | 335 |
MemorySwappiness *int64 // Tuning container memory swappiness behaviour |
... | ... |
@@ -111,6 +111,10 @@ func getMemoryResources(config containertypes.Resources) *specs.LinuxMemory { |
111 | 111 |
memory.Kernel = &config.KernelMemory |
112 | 112 |
} |
113 | 113 |
|
114 |
+ if config.KernelMemoryTCP != 0 { |
|
115 |
+ memory.KernelTCP = &config.KernelMemoryTCP |
|
116 |
+ } |
|
117 |
+ |
|
114 | 118 |
return &memory |
115 | 119 |
} |
116 | 120 |
|
... | ... |
@@ -20,6 +20,7 @@ func (daemon *Daemon) fillPlatformInfo(v *types.Info, sysInfo *sysinfo.SysInfo) |
20 | 20 |
v.MemoryLimit = sysInfo.MemoryLimit |
21 | 21 |
v.SwapLimit = sysInfo.SwapLimit |
22 | 22 |
v.KernelMemory = sysInfo.KernelMemory |
23 |
+ v.KernelMemoryTCP = sysInfo.KernelMemoryTCP |
|
23 | 24 |
v.OomKillDisable = sysInfo.OomKillDisable |
24 | 25 |
v.CPUCfsPeriod = sysInfo.CPUCfsPeriod |
25 | 26 |
v.CPUCfsQuota = sysInfo.CPUCfsQuota |
... | ... |
@@ -32,6 +32,7 @@ keywords: "API, Docker, rcli, REST, documentation" |
32 | 32 |
* `POST /swarm/init` now accepts a `DataPathPort` property to set data path port number. |
33 | 33 |
* `GET /info` now returns information about `DataPathPort` that is currently used in swarm |
34 | 34 |
* `GET /swarm` endpoint now returns DataPathPort info |
35 |
+* `POST /containers/create` now takes `KernelMemoryTCP` field to set hard limit for kernel TCP buffer memory. |
|
35 | 36 |
|
36 | 37 |
## V1.39 API changes |
37 | 38 |
|
38 | 39 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,49 @@ |
0 |
+package container // import "github.com/docker/docker/integration/container" |
|
1 |
+ |
|
2 |
+import ( |
|
3 |
+ "context" |
|
4 |
+ "strconv" |
|
5 |
+ "strings" |
|
6 |
+ "testing" |
|
7 |
+ "time" |
|
8 |
+ |
|
9 |
+ containertypes "github.com/docker/docker/api/types/container" |
|
10 |
+ "github.com/docker/docker/integration/internal/container" |
|
11 |
+ "github.com/docker/docker/internal/test/request" |
|
12 |
+ "gotest.tools/assert" |
|
13 |
+ is "gotest.tools/assert/cmp" |
|
14 |
+ "gotest.tools/poll" |
|
15 |
+ "gotest.tools/skip" |
|
16 |
+) |
|
17 |
+ |
|
18 |
+func TestKernelTCPMemory(t *testing.T) { |
|
19 |
+ skip.If(t, testEnv.DaemonInfo.OSType != "linux") |
|
20 |
+ skip.If(t, !testEnv.DaemonInfo.KernelMemoryTCP) |
|
21 |
+ |
|
22 |
+ defer setupTest(t)() |
|
23 |
+ client := request.NewAPIClient(t) |
|
24 |
+ ctx := context.Background() |
|
25 |
+ |
|
26 |
+ const ( |
|
27 |
+ kernelMemoryTCP int64 = 200 * 1024 * 1024 |
|
28 |
+ ) |
|
29 |
+ |
|
30 |
+ cID := container.Run(t, ctx, client, func(c *container.TestContainerConfig) { |
|
31 |
+ c.HostConfig.Resources = containertypes.Resources{ |
|
32 |
+ KernelMemoryTCP: kernelMemoryTCP, |
|
33 |
+ } |
|
34 |
+ }) |
|
35 |
+ |
|
36 |
+ poll.WaitOn(t, container.IsInState(ctx, client, cID, "running"), poll.WithDelay(100*time.Millisecond)) |
|
37 |
+ |
|
38 |
+ inspect, err := client.ContainerInspect(ctx, cID) |
|
39 |
+ assert.NilError(t, err) |
|
40 |
+ assert.Check(t, is.Equal(kernelMemoryTCP, inspect.HostConfig.KernelMemoryTCP)) |
|
41 |
+ |
|
42 |
+ res, err := container.Exec(ctx, client, cID, |
|
43 |
+ []string{"cat", "/sys/fs/cgroup/memory/memory.kmem.tcp.limit_in_bytes"}) |
|
44 |
+ assert.NilError(t, err) |
|
45 |
+ assert.Assert(t, is.Len(res.Stderr(), 0)) |
|
46 |
+ assert.Equal(t, 0, res.ExitCode) |
|
47 |
+ assert.Check(t, is.Equal(strconv.FormatInt(kernelMemoryTCP, 10), strings.TrimSpace(res.Stdout()))) |
|
48 |
+} |
... | ... |
@@ -95,6 +95,10 @@ func checkCgroupMem(cgMounts map[string]string, quiet bool) cgroupMemInfo { |
95 | 95 |
if !quiet && !kernelMemory { |
96 | 96 |
logrus.Warn("Your kernel does not support kernel memory limit") |
97 | 97 |
} |
98 |
+ kernelMemoryTCP := cgroupEnabled(mountPoint, "memory.kmem.tcp.limit_in_bytes") |
|
99 |
+ if !quiet && !kernelMemoryTCP { |
|
100 |
+ logrus.Warn("Your kernel does not support kernel memory TCP limit") |
|
101 |
+ } |
|
98 | 102 |
|
99 | 103 |
return cgroupMemInfo{ |
100 | 104 |
MemoryLimit: true, |
... | ... |
@@ -103,6 +107,7 @@ func checkCgroupMem(cgMounts map[string]string, quiet bool) cgroupMemInfo { |
103 | 103 |
OomKillDisable: oomKillDisable, |
104 | 104 |
MemorySwappiness: memorySwappiness, |
105 | 105 |
KernelMemory: kernelMemory, |
106 |
+ KernelMemoryTCP: kernelMemoryTCP, |
|
106 | 107 |
} |
107 | 108 |
} |
108 | 109 |
|