Skip to content

Commit ee0a8b6

Browse files
authored
Merge pull request #1537 from Ace-Tang/resource_check
feature: add container setting check
2 parents d87e793 + 6f229a5 commit ee0a8b6

File tree

9 files changed

+151
-67
lines changed

9 files changed

+151
-67
lines changed

apis/opts/memory_swappiness.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ import "fmt"
66

77
// ValidateMemorySwappiness verifies the correctness of memory-swappiness.
88
func ValidateMemorySwappiness(memorySwappiness int64) error {
9-
if memorySwappiness != -1 && (memorySwappiness < 0 || memorySwappiness > 100) {
10-
return fmt.Errorf("invalid memory swappiness: %d (its range is -1 or 0-100)", memorySwappiness)
9+
if memorySwappiness < 0 || memorySwappiness > 100 {
10+
return fmt.Errorf("invalid memory swappiness: %d (its range is 0-100)", memorySwappiness)
1111
}
1212
return nil
1313
}

apis/opts/memory_swappiness_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ func TestValidateMemorySwappiness(t *testing.T) {
1616
testCases := []TestCase{
1717
{
1818
input: -1,
19-
expected: nil,
19+
expected: fmt.Errorf("invalid memory swappiness: %d (its range is 0-100)", -1),
2020
},
2121
{
2222
input: 0,
@@ -32,11 +32,11 @@ func TestValidateMemorySwappiness(t *testing.T) {
3232
},
3333
{
3434
input: -5,
35-
expected: fmt.Errorf("invalid memory swappiness: %d (its range is -1 or 0-100)", -5),
35+
expected: fmt.Errorf("invalid memory swappiness: %d (its range is 0-100)", -5),
3636
},
3737
{
3838
input: 200,
39-
expected: fmt.Errorf("invalid memory swappiness: %d (its range is -1 or 0-100)", 200),
39+
expected: fmt.Errorf("invalid memory swappiness: %d (its range is 0-100)", 200),
4040
},
4141
}
4242

apis/swagger.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2349,7 +2349,7 @@ definitions:
23492349
description: "Tune a container's memory swappiness behavior. Accepts an integer between 0 and 100."
23502350
type: "integer"
23512351
format: "int64"
2352-
minimum: -1
2352+
minimum: 0
23532353
maximum: 100
23542354
NanoCPUs:
23552355
description: "CPU quota in units of 10<sup>-9</sup> CPUs."

apis/types/resources.go

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cli/common_flags.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ func addCommonFlags(flagSet *pflag.FlagSet) *container {
5050

5151
flagSet.StringVarP(&c.memory, "memory", "m", "", "Memory limit")
5252
flagSet.StringVar(&c.memorySwap, "memory-swap", "", "Swap limit equal to memory + swap, '-1' to enable unlimited swap")
53-
flagSet.Int64Var(&c.memorySwappiness, "memory-swappiness", -1, "Container memory swappiness [0, 100]")
53+
flagSet.Int64Var(&c.memorySwappiness, "memory-swappiness", 0, "Container memory swappiness [0, 100]")
5454
// for alikernel isolation options
5555
flagSet.Int64Var(&c.memoryWmarkRatio, "memory-wmark-ratio", 0, "Represent this container's memory low water mark percentage, range in [0, 100]. The value of memory low water mark is memory.limit_in_bytes * MemoryWmarkRatio")
5656
flagSet.Int64Var(&c.memoryExtra, "memory-extra", 0, "Represent container's memory high water mark percentage, range in [0, 100]")

daemon/mgr/container.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -386,11 +386,14 @@ func (mgr *ContainerManager) Create(ctx context.Context, name string, config *ty
386386
}
387387

388388
// validate container Config
389-
warnings, err := validateConfig(config)
389+
warnings, err := validateConfig(&config.ContainerConfig, config.HostConfig, false)
390390
if err != nil {
391391
return nil, err
392392
}
393393

394+
// amendContainerSettings modify container config settings to wanted
395+
amendContainerSettings(&config.ContainerConfig, config.HostConfig)
396+
394397
// store disk
395398
if err := container.Write(mgr.Store); err != nil {
396399
logrus.Errorf("failed to update meta: %v", err)
@@ -851,6 +854,14 @@ func (mgr *ContainerManager) Update(ctx context.Context, name string, config *ty
851854
return err
852855
}
853856

857+
warnings, err := validateResource(&config.Resources, true)
858+
if err != nil {
859+
return err
860+
}
861+
if len(warnings) != 0 {
862+
logrus.Warnf("warnings update %s: %v", name, warnings)
863+
}
864+
854865
restore := false
855866
configBack := *c.Config
856867
hostconfigBack := *c.HostConfig

daemon/mgr/container_types.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,59 @@ var (
2020
// GCExecProcessTick is the time interval to trigger gc unused exec config,
2121
// time unit is minute.
2222
GCExecProcessTick = 5
23+
24+
// MinMemory is minimal memory container should has
25+
MinMemory int64 = 4194304
26+
)
27+
28+
var (
29+
// MemoryWarn is warning for flag --memory
30+
MemoryWarn = "Current Kernel does not support memory limit, discard --memory"
31+
32+
// MemorySwapWarn is warning for flag --memory-swap
33+
MemorySwapWarn = "Current Kernel does not support memory swap, discard --memory-swap"
34+
35+
// MemorySwappinessWarn is warning for flag --memory-swappiness
36+
MemorySwappinessWarn = "Current Kernel does not support memory swappiness , discard --memory-swappiness"
37+
38+
//OOMKillWarn is warning for flag --oom-kill-disable
39+
OOMKillWarn = "Current Kernel does not support disable oom kill, discard --oom-kill-disable"
40+
41+
// CpusetCpusWarn is warning for flag --cpuset-cpus
42+
CpusetCpusWarn = "Current Kernel does not support cpuset cpus, discard --cpuset-cpus"
43+
44+
// CpusetMemsWarn is warning for flag --cpuset-mems
45+
CpusetMemsWarn = "Current Kernel does not support cpuset mems, discard --cpuset-mems"
46+
47+
// CPUSharesWarn is warning for flag --cpu-shares
48+
CPUSharesWarn = "Current Kernel does not support cpu shares, discard --cpu-shares"
49+
50+
// CPUQuotaWarn is warning for flag --cpu-quota
51+
CPUQuotaWarn = "Current Kernel does not support cpu quota, discard --cpu-quota"
52+
53+
// CPUPeriodWarn is warning for flag --cpu-period
54+
CPUPeriodWarn = "Current Kernel does not support cpu period, discard --cpu-period"
55+
56+
// BlkioWeightWarn is warning for flag --blkio-weight
57+
BlkioWeightWarn = "Current Kernel does not support blkio weight, discard --blkio-weight"
58+
59+
// BlkioWeightDeviceWarn is warning for flag --blkio-weight-device
60+
BlkioWeightDeviceWarn = "Current Kernel does not support blkio weight device, discard --blkio-weight-device"
61+
62+
// BlkioDeviceReadBpsWarn is warning for flag --device-read-bps
63+
BlkioDeviceReadBpsWarn = "Current Kernel does not support blkio device throttle read bps, discard --device-read-bps"
64+
65+
// BlkioDeviceWriteBpsWarn is warning for flag --device-write-bps
66+
BlkioDeviceWriteBpsWarn = "Current Kernel does not support blkio device throttle write bps, discard --device-write-bps"
67+
68+
// BlkioDeviceReadIOpsWarn is warning for flag --device-read-iops
69+
BlkioDeviceReadIOpsWarn = "Current Kernel does not support blkio device throttle read iops, discard --device-read-iops"
70+
71+
// BlkioDeviceWriteIOpsWarn is warning for flag --device-write-iops
72+
BlkioDeviceWriteIOpsWarn = "Current Kernel does not support blkio device throttle, discard --device-write-iops"
73+
74+
// PidsLimitWarn is warning for flag --pids-limit
75+
PidsLimitWarn = "Current Kernel does not support pids cgroup, discard --pids-limit"
2376
)
2477

2578
const (

daemon/mgr/container_utils.go

Lines changed: 57 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -227,22 +227,23 @@ func parsePSOutput(output []byte, pids []int) (*types.ContainerProcessList, erro
227227
}
228228

229229
// validateConfig validates container config
230-
func validateConfig(config *types.ContainerCreateConfig) ([]string, error) {
231-
amendResource(&config.HostConfig.Resources)
232-
230+
func validateConfig(config *types.ContainerConfig, hostConfig *types.HostConfig, update bool) ([]string, error) {
233231
// validates container hostconfig
234232
warnings := make([]string, 0)
235-
warns, err := validateResource(&config.HostConfig.Resources)
233+
warns, err := validateResource(&hostConfig.Resources, update)
236234
if err != nil {
237235
return nil, err
238236
}
239237
warnings = append(warnings, warns...)
240238

239+
if hostConfig.OomScoreAdj < -1000 || hostConfig.OomScoreAdj > 1000 {
240+
return warnings, fmt.Errorf("oom score should be in range [-1000, 1000]")
241+
}
241242
// TODO: add more validate here
242243
return warnings, nil
243244
}
244245

245-
func validateResource(r *types.Resources) ([]string, error) {
246+
func validateResource(r *types.Resources, update bool) ([]string, error) {
246247
cgroupInfo := system.NewCgroupInfo()
247248
if cgroupInfo == nil {
248249
return nil, nil
@@ -251,125 +252,124 @@ func validateResource(r *types.Resources) ([]string, error) {
251252

252253
// validates memory cgroup value
253254
if cgroupInfo.Memory != nil {
254-
if r.Memory != 0 && !cgroupInfo.Memory.MemoryLimit {
255-
warn := "Current Kernel does not support memory limit, discard --memory"
256-
logrus.Warn(warn)
257-
warnings = append(warnings, warn)
255+
if r.Memory > 0 && !cgroupInfo.Memory.MemoryLimit {
256+
logrus.Warn(MemoryWarn)
257+
warnings = append(warnings, MemoryWarn)
258258
r.Memory = 0
259259
r.MemorySwap = 0
260260
}
261-
if r.MemorySwap != 0 && !cgroupInfo.Memory.MemorySwap {
262-
warn := "Current Kernel does not support memory swap, discard --memory-swap"
263-
logrus.Warn(warn)
264-
warnings = append(warnings, warn)
261+
if r.MemorySwap > 0 && !cgroupInfo.Memory.MemorySwap {
262+
logrus.Warn(MemorySwapWarn)
263+
warnings = append(warnings, MemorySwapWarn)
265264
r.MemorySwap = 0
266265
}
266+
if r.Memory != 0 && r.Memory < MinMemory {
267+
return warnings, fmt.Errorf("Minimal memory should greater than 4M")
268+
}
267269
if r.Memory > 0 && r.MemorySwap > 0 && r.MemorySwap < 2*r.Memory {
268270
warnings = append(warnings, "You should typically size your swap space to approximately 2x main memory for systems with less than 2GB of RAM")
269271
}
270272
if r.MemorySwappiness != nil && !cgroupInfo.Memory.MemorySwappiness {
271-
warn := "Current Kernel does not support memory swappiness , discard --memory-swappiness"
272-
logrus.Warn(warn)
273-
warnings = append(warnings, warn)
273+
logrus.Warn(MemorySwappinessWarn)
274+
warnings = append(warnings, MemorySwappinessWarn)
274275
r.MemorySwappiness = nil
275276
}
277+
if r.MemorySwappiness != nil && (*r.MemorySwappiness < 0 || *r.MemorySwappiness > 100) {
278+
return warnings, fmt.Errorf("MemorySwappiness should in range [-1, 100]")
279+
}
276280
if r.OomKillDisable != nil && !cgroupInfo.Memory.OOMKillDisable {
277-
warn := "Current Kernel does not support disable oom kill, discard --oom-kill-disable"
278-
logrus.Warn(warn)
279-
warnings = append(warnings, warn)
281+
logrus.Warn(OOMKillWarn)
282+
warnings = append(warnings, OOMKillWarn)
280283
r.OomKillDisable = nil
281284
}
282285
}
283286

284287
// validates cpu cgroup value
285288
if cgroupInfo.CPU != nil {
286289
if r.CpusetCpus != "" && !cgroupInfo.CPU.CpusetCpus {
287-
warn := "Current Kernel does not support cpuset cpus, discard --cpuset-cpus"
288-
logrus.Warn(warn)
289-
warnings = append(warnings, warn)
290+
logrus.Warn(CpusetCpusWarn)
291+
warnings = append(warnings, CpusetCpusWarn)
290292
r.CpusetCpus = ""
291293
}
292294
if r.CpusetMems != "" && !cgroupInfo.CPU.CpusetMems {
293-
warn := "Current Kernel does not support cpuset cpus, discard --cpuset-mems"
294-
logrus.Warn(warn)
295-
warnings = append(warnings, warn)
295+
logrus.Warn(CpusetMemsWarn)
296+
warnings = append(warnings, CpusetMemsWarn)
296297
r.CpusetMems = ""
297298
}
298299
if r.CPUShares > 0 && !cgroupInfo.CPU.CPUShares {
299-
warn := "Current Kernel does not support cpu shares, discard --cpu-shares"
300-
logrus.Warn(warn)
301-
warnings = append(warnings, warn)
300+
logrus.Warn(CPUSharesWarn)
301+
warnings = append(warnings, CPUSharesWarn)
302302
r.CPUShares = 0
303303
}
304304
if r.CPUQuota > 0 && !cgroupInfo.CPU.CPUQuota {
305-
warn := "Current Kernel does not support cpu quota, discard --cpu-quota"
306-
logrus.Warn(warn)
307-
warnings = append(warnings, warn)
305+
logrus.Warn(CPUQuotaWarn)
306+
warnings = append(warnings, CPUQuotaWarn)
308307
r.CPUQuota = 0
309308
}
309+
// cpu.cfs_quota_us can accept value less than 0, we allow -1 and > 1000
310+
if r.CPUQuota > 0 && r.CPUQuota < 1000 {
311+
return warnings, fmt.Errorf("CPU cfs quota should be greater than 1ms(1000)")
312+
}
310313
if r.CPUPeriod > 0 && !cgroupInfo.CPU.CPUPeriod {
311-
warn := "Current Kernel does not support cpu period, discard --cpu-period"
312-
logrus.Warn(warn)
313-
warnings = append(warnings, warn)
314+
logrus.Warn(CPUPeriodWarn)
315+
warnings = append(warnings, CPUPeriodWarn)
314316
r.CPUPeriod = 0
315317
}
318+
if r.CPUPeriod != 0 && (r.CPUPeriod < 1000 || r.CPUPeriod > 1000000) {
319+
return warnings, fmt.Errorf("CPU cfs period should be in range [1000, 1000000](1ms, 1s)")
320+
}
316321
}
317322

318323
// validates blkio cgroup value
319324
if cgroupInfo.Blkio != nil {
320325
if r.BlkioWeight > 0 && !cgroupInfo.Blkio.BlkioWeight {
321-
warn := "Current Kernel does not support blkio weight, discard --blkio-weight"
322-
logrus.Warn(warn)
323-
warnings = append(warnings, warn)
326+
logrus.Warn(BlkioWeightWarn)
327+
warnings = append(warnings, BlkioWeightWarn)
324328
r.BlkioWeight = 0
325329
}
326330
if len(r.BlkioWeightDevice) > 0 && !cgroupInfo.Blkio.BlkioWeightDevice {
327-
warn := "Current Kernel does not support blkio weight device, discard --blkio-weight-device"
328-
logrus.Warn(warn)
329-
warnings = append(warnings, warn)
331+
logrus.Warn(BlkioWeightDeviceWarn)
332+
warnings = append(warnings, BlkioWeightDeviceWarn)
330333
r.BlkioWeightDevice = []*types.WeightDevice{}
331334
}
332335
if len(r.BlkioDeviceReadBps) > 0 && !cgroupInfo.Blkio.BlkioDeviceReadBps {
333-
warn := "Current Kernel does not support blkio device throttle read bps, discard --device-read-bps"
334-
logrus.Warn(warn)
335-
warnings = append(warnings, warn)
336+
logrus.Warn(BlkioDeviceReadBpsWarn)
337+
warnings = append(warnings, BlkioDeviceReadBpsWarn)
336338
r.BlkioDeviceReadBps = []*types.ThrottleDevice{}
337339
}
338340
if len(r.BlkioDeviceWriteBps) > 0 && !cgroupInfo.Blkio.BlkioDeviceWriteBps {
339-
warn := "Current Kernel does not support blkio device throttle write bps, discard --device-write-bps"
340-
logrus.Warn(warn)
341-
warnings = append(warnings, warn)
341+
logrus.Warn(BlkioDeviceWriteBpsWarn)
342+
warnings = append(warnings, BlkioDeviceWriteBpsWarn)
342343
r.BlkioDeviceWriteBps = []*types.ThrottleDevice{}
343344
}
344345
if len(r.BlkioDeviceReadIOps) > 0 && !cgroupInfo.Blkio.BlkioDeviceReadIOps {
345-
warn := "Current Kernel does not support blkio device throttle read iops, discard --device-read-iops"
346-
logrus.Warn(warn)
347-
warnings = append(warnings, warn)
346+
logrus.Warn(BlkioDeviceReadIOpsWarn)
347+
warnings = append(warnings, BlkioDeviceReadIOpsWarn)
348348
r.BlkioDeviceReadIOps = []*types.ThrottleDevice{}
349349
}
350350
if len(r.BlkioDeviceWriteIOps) > 0 && !cgroupInfo.Blkio.BlkioDeviceWriteIOps {
351-
warn := "Current Kernel does not support blkio device throttle, discard --device-write-iops"
352-
logrus.Warn(warn)
353-
warnings = append(warnings, warn)
351+
logrus.Warn(BlkioDeviceWriteIOpsWarn)
352+
warnings = append(warnings, BlkioDeviceWriteIOpsWarn)
354353
r.BlkioDeviceWriteIOps = []*types.ThrottleDevice{}
355354
}
356355
}
357356

358357
// validates pid cgroup value
359358
if cgroupInfo.Pids != nil {
360359
if r.PidsLimit != 0 && !cgroupInfo.Pids.Pids {
361-
warn := "Current Kernel does not support pids cgroup, discard --pids-limit"
362-
logrus.Warn(warn)
363-
warnings = append(warnings, warn)
360+
logrus.Warn(PidsLimitWarn)
361+
warnings = append(warnings, PidsLimitWarn)
364362
r.PidsLimit = 0
365363
}
366364
}
367365

368366
return warnings, nil
369367
}
370368

371-
// amendResource modify resource to correct setting.
372-
func amendResource(r *types.Resources) {
369+
// amendContainerSettings modify config settings to wanted,
370+
// it will be call before container created.
371+
func amendContainerSettings(config *types.ContainerConfig, hostConfig *types.HostConfig) {
372+
r := &hostConfig.Resources
373373
if r.Memory > 0 && r.MemorySwap == 0 {
374374
r.MemorySwap = 2 * r.Memory
375375
}

test/cli_update_test.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,26 @@ func (suite *PouchUpdateSuite) TestUpdateCpuPeriod(c *check.C) {
115115
c.Assert(metaJSON[0].HostConfig.CPUPeriod, check.Equals, int64(2000))
116116
}
117117

118+
// TestUpdateCpuMemoryFail is to verify the invalid value of updating container cpu and memory related flags will fail.
119+
func (suite *PouchUpdateSuite) TestUpdateCpuMemoryFail(c *check.C) {
120+
name := "update-container-cpu-memory-period-fail"
121+
122+
res := command.PouchRun("run", "-d", "--name", name, busyboxImage, "top")
123+
defer DelContainerForceMultyTime(c, name)
124+
res.Assert(c, icmd.Success)
125+
126+
res = command.PouchRun("update", "--cpu-period", "10", name)
127+
c.Assert(res.Stderr(), check.NotNil)
128+
res = command.PouchRun("update", "--cpu-period", "100000000", name)
129+
c.Assert(res.Stderr(), check.NotNil)
130+
res = command.PouchRun("update", "--cpu-period", "-1", name)
131+
c.Assert(res.Stderr(), check.NotNil)
132+
res = command.PouchRun("update", "--cpu-quota", "1", name)
133+
c.Assert(res.Stderr(), check.NotNil)
134+
res = command.PouchRun("update", "-m", "10000", name)
135+
c.Assert(res.Stderr(), check.NotNil)
136+
}
137+
118138
// TestUpdateRunningContainer is to verify the correctness of updating a running container.
119139
func (suite *PouchUpdateSuite) TestUpdateRunningContainer(c *check.C) {
120140
name := "update-running-container"

0 commit comments

Comments
 (0)