Skip to content

Commit

Permalink
feature: limit blkio device's read/write Bps/IOps
Browse files Browse the repository at this point in the history
fixes AliyunContainerService#2509

Signed-off-by: Leno Hou <lenohou@gmail.com>
  • Loading branch information
houstar committed Dec 16, 2018
1 parent 9e879af commit f6f86de
Show file tree
Hide file tree
Showing 9 changed files with 135 additions and 34 deletions.
12 changes: 6 additions & 6 deletions apis/swagger.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2471,12 +2471,6 @@ definitions:
type: "array"
items:
type: "string"
DiskQuota:
type: "object"
description: "update disk quota for container"
x-nullable: true
additionalProperties:
type: "string"

ContainerUpgradeConfig:
description: |
Expand Down Expand Up @@ -2630,6 +2624,12 @@ definitions:
items:
type: "string"
example: "c 13:* rwm"
DiskQuota:
type: "object"
description: "update disk quota for container"
x-nullable: true
additionalProperties:
type: "string"
KernelMemory:
description: "Kernel memory limit in bytes."
type: "integer"
Expand Down
5 changes: 4 additions & 1 deletion apis/types/resources.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 0 additions & 11 deletions apis/types/update_config.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 22 additions & 14 deletions cli/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ func (uc *UpdateCommand) addFlags() {
flagSet.StringSliceVarP(&uc.labels, "label", "l", nil, "Set label for container")
flagSet.StringVar(&uc.restartPolicy, "restart", "", "Restart policy to apply when container exits")
flagSet.StringSliceVar(&uc.diskQuota, "disk-quota", nil, "Update disk quota for container(/=10g)")
flagSet.Var(&uc.blkioDeviceReadBps, "device-read-bps", "Update read rate (bytes per second) from a device")
flagSet.Var(&uc.blkioDeviceWriteBps, "device-write-bps", "Update write rate (bytes per second) from a device")
flagSet.Var(&uc.blkioDeviceReadIOps, "device-read-iops", "Update read rate (io per second) from a device")
flagSet.Var(&uc.blkioDeviceWriteIOps, "device-write-iops", "Update write rate (io per second) from a device")
}

// updateRun is the entry of update command.
Expand All @@ -68,23 +72,28 @@ func (uc *UpdateCommand) updateRun(args []string) error {
return err
}

resource := types.Resources{
CPUPeriod: uc.cpuperiod,
CPUShares: uc.cpushare,
CPUQuota: uc.cpuquota,
CpusetCpus: uc.cpusetcpus,
CpusetMems: uc.cpusetmems,
Memory: memory,
MemorySwap: memorySwap,
BlkioWeight: uc.blkioWeight,
}

restartPolicy, err := opts.ParseRestartPolicy(uc.restartPolicy)
diskQuota, err := opts.ParseDiskQuota(uc.diskQuota)
if err != nil {
return err
}

diskQuota, err := opts.ParseDiskQuota(uc.diskQuota)
resource := types.Resources{
CPUPeriod: uc.cpuperiod,
CPUShares: uc.cpushare,
CPUQuota: uc.cpuquota,
CpusetCpus: uc.cpusetcpus,
CpusetMems: uc.cpusetmems,
DiskQuota: diskQuota,
Memory: memory,
MemorySwap: memorySwap,
BlkioWeight: uc.blkioWeight,
BlkioDeviceReadBps: uc.blkioDeviceReadBps.Value(),
BlkioDeviceWriteBps: uc.blkioDeviceWriteBps.Value(),
BlkioDeviceReadIOps: uc.blkioDeviceReadIOps.Value(),
BlkioDeviceWriteIOps: uc.blkioDeviceWriteIOps.Value(),
}

restartPolicy, err := opts.ParseRestartPolicy(uc.restartPolicy)
if err != nil {
return err
}
Expand All @@ -94,7 +103,6 @@ func (uc *UpdateCommand) updateRun(args []string) error {
Label: uc.labels,
RestartPolicy: restartPolicy,
Resources: resource,
DiskQuota: diskQuota,
}

apiClient := uc.cli.Client()
Expand Down
1 change: 0 additions & 1 deletion cri/v1alpha2/cri.go
Original file line number Diff line number Diff line change
Expand Up @@ -1105,7 +1105,6 @@ func (c *CriManager) UpdateContainerResources(ctx context.Context, r *runtime.Up
resources := r.GetLinux()
updateConfig := &apitypes.UpdateConfig{
Resources: parseResourcesFromCRI(resources),
DiskQuota: resources.GetDiskQuota(),
}
err = c.ContainerMgr.Update(ctx, containerID, updateConfig)
if err != nil {
Expand Down
1 change: 1 addition & 0 deletions cri/v1alpha2/cri_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -1043,6 +1043,7 @@ func parseResourcesFromCRI(runtimeResources *runtime.LinuxContainerResources) ap
BlkioDeviceWriteBps: parseThrottleDeviceFromCRI(runtimeResources.GetBlkioDeviceWriteBps()),
BlkioDeviceReadIOps: parseThrottleDeviceFromCRI(runtimeResources.GetBlkioDeviceRead_IOps()),
BlkioDeviceWriteIOps: parseThrottleDeviceFromCRI(runtimeResources.GetBlkioDeviceWrite_IOps()),
DiskQuota: runtimeResources.GetDiskQuota(),
KernelMemory: runtimeResources.GetKernelMemory(),
MemoryReservation: runtimeResources.GetMemoryReservation(),
MemorySwappiness: memorySwappiness,
Expand Down
1 change: 1 addition & 0 deletions cri/v1alpha2/cri_utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ var (
Memory: 1000,
CpusetCpus: "0",
CpusetMems: "0",
DiskQuota: map[string]string{"foo": "foo"},
BlkioWeight: uint16(100),
BlkioWeightDevice: apitypesWeightDevicesSlice,
BlkioDeviceReadBps: apitypesThrottleDevicesSlice,
Expand Down
2 changes: 1 addition & 1 deletion daemon/mgr/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -1048,7 +1048,7 @@ func (mgr *ContainerManager) Update(ctx context.Context, name string, config *ty
}

// update container disk quota
if err := mgr.updateContainerDiskQuota(ctx, c, config.DiskQuota); err != nil {
if err := mgr.updateContainerDiskQuota(ctx, c, config.Resources.DiskQuota); err != nil {
return errors.Wrapf(err, "failed to update diskquota of container %s", c.ID)
}

Expand Down
100 changes: 100 additions & 0 deletions test/cli_run_blkio_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,3 +139,103 @@ func (suite *PouchRunBlkioSuite) TestRunWithBlkioWeight(c *check.C) {
defer DelContainerForceMultyTime(c, name)
res.Assert(c, icmd.Success)
}

// TestRunWithBlkIODeviceWriteBps is to verify blkio write bps
func (suite *PouchRunBlkioSuite) TestRunBlockIODeviceWriteBps(c *check.C) {
cname := "TestRunBlockIODeviceWriteBps"
testDisk := "/dev/null"

number, exist := util.GetMajMinNumOfDevice(testDisk)
if !exist {
c.Skip("fail to get major:minor device number")
}

limitSpeed := "100"
expected := fmt.Sprintf("%s:%d %s\n", number, value, limitSpeed)

blkioDeviceWriteBpsFile := "/sys/fs/cgroup/blkio/blkio.throttle.write_bps_device"
throttleDev := testDisk + ":" + limitSpeed

res := command.PouchRun("run", "--name", cname,
"--device-write-bps ", throttleDev, busyboxImage, "cat", blkioDeviceWriteBps)
defer DelContainerForceMultyTime(c, cname)
res.Assert(c, icmd.Success)

out := res.Stdout()
c.Assert(out, check.Equals, expected)
}

// TestRunWithBlkIODeviceReadBps is to verify blkio read bps
func (suite *PouchRunBlkioSuite) TestRunBlockIODeviceReadBps(c *check.C) {
cname := "TestRunBlockIODeviceReadBps"
testDisk := "/dev/null"

number, exist := util.GetMajMinNumOfDevice(testDisk)
if !exist {
c.Skip("fail to get major:minor device number")
}

limitSpeed := "100"
expected := fmt.Sprintf("%s:%d %s\n", number, value, limitSpeed)

blkioDeviceReadBpsFile := "/sys/fs/cgroup/blkio/blkio.throttle.read_bps_device"
throttleDev := testDisk + ":" + limitSpeed

res := command.PouchRun("run", "--name", cname,
"--device-read-bps ", throttleDev, busyboxImage, "cat", blkioDeviceReadBps)
defer DelContainerForceMultyTime(c, cname)
res.Assert(c, icmd.Success)

out := res.Stdout()
c.Assert(out, check.Equals, expected)
}

// TestRunWithBlkIODeviceWriteIOps is to verify blkio write iops
func (suite *PouchRunBlkioSuite) TestRunBlockIODeviceWriteIOps(c *check.C) {
cname := "TestRunBlockIODeviceWriteIOps"
testDisk := "/dev/null"

number, exist := util.GetMajMinNumOfDevice(testDisk)
if !exist {
c.Skip("fail to get major:minor device number")
}

limitSpeed := "100"
expected := fmt.Sprintf("%s:%d %s\n", number, value, limitSpeed)

blkioDeviceWriteIOpsFile := "/sys/fs/cgroup/blkio/blkio.throttle.write_iops_device"
throttleDev := testDisk + ":" + limitSpeed

res := command.PouchRun("run", "--name", cname,
"--device-write-iops ", throttleDev, busyboxImage, "cat", blkioDeviceWriteIOpsFile)
defer DelContainerForceMultyTime(c, cname)
res.Assert(c, icmd.Success)

out := res.Stdout()
c.Assert(out, check.Equals, expected)
}

// TestRunWithBlkIODeviceWriteIOps is to verify blkio read iops
func (suite *PouchRunBlkioSuite) TestRunBlockIODeviceReadIOps(c *check.C) {
cname := "TestRunBlockIODeviceReadIOps"
testDisk := "/dev/null"

number, exist := util.GetMajMinNumOfDevice(testDisk)
if !exist {
c.Skip("fail to get major:minor device number")
}

limitSpeed := "100"
expected := fmt.Sprintf("%s:%d %s\n", number, value, limitSpeed)

blkioDeviceReadIOpsFile := "/sys/fs/cgroup/blkio/blkio.throttle.read_iops_device"
throttleDev := testDisk + ":" + limitSpeed

res := command.PouchRun("run", "--name", cname,
"--device-read-iops ", throttleDev, busyboxImage, "cat", blkioDeviceReadIOpsFile)
defer DelContainerForceMultyTime(c, cname)
res.Assert(c, icmd.Success)

out := res.Stdout()
c.Assert(out, check.Equals, expected)
}

0 comments on commit f6f86de

Please sign in to comment.