Skip to content

Commit

Permalink
Add support for remaining blkio settings
Browse files Browse the repository at this point in the history
Signed-off-by: Swagat Bora <[email protected]>
  • Loading branch information
swagatbora90 committed Mar 5, 2025
1 parent 8814dec commit d7d06b4
Show file tree
Hide file tree
Showing 11 changed files with 679 additions and 52 deletions.
29 changes: 26 additions & 3 deletions cmd/nerdctl/container/container_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,19 +199,42 @@ func createOptions(cmd *cobra.Command) (types.ContainerCreateOptions, error) {
if err != nil {
return opt, err
}
opt.Cgroupns, err = cmd.Flags().GetString("cgroupns")
if err != nil {
return opt, err
}
opt.CgroupParent, err = cmd.Flags().GetString("cgroup-parent")
if err != nil {
return opt, err
}
opt.Device, err = cmd.Flags().GetStringSlice("device")
if err != nil {
return opt, err
}
// #endregion

// #region for blkio flags
opt.BlkioWeight, err = cmd.Flags().GetUint16("blkio-weight")
if err != nil {
return opt, err
}
opt.Cgroupns, err = cmd.Flags().GetString("cgroupns")
opt.BlkioWeightDevice, err = cmd.Flags().GetStringArray("blkio-weight-device")
if err != nil {
return opt, err
}
opt.CgroupParent, err = cmd.Flags().GetString("cgroup-parent")
opt.BlkioDeviceReadBps, err = cmd.Flags().GetStringArray("device-read-bps")
if err != nil {
return opt, err
}
opt.Device, err = cmd.Flags().GetStringSlice("device")
opt.BlkioDeviceWriteBps, err = cmd.Flags().GetStringArray("device-write-bps")
if err != nil {
return opt, err
}
opt.BlkioDeviceReadIOps, err = cmd.Flags().GetStringArray("device-read-iops")
if err != nil {
return opt, err
}
opt.BlkioDeviceWriteIOps, err = cmd.Flags().GetStringArray("device-write-iops")
if err != nil {
return opt, err
}
Expand Down
10 changes: 9 additions & 1 deletion cmd/nerdctl/container/container_run.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,6 @@ func setCreateFlags(cmd *cobra.Command) {
})
cmd.Flags().Int64("pids-limit", -1, "Tune container pids limit (set -1 for unlimited)")
cmd.Flags().StringSlice("cgroup-conf", nil, "Configure cgroup v2 (key=value)")
cmd.Flags().Uint16("blkio-weight", 0, "Block IO (relative weight), between 10 and 1000, or 0 to disable (default 0)")
cmd.Flags().String("cgroupns", defaults.CgroupnsMode(), `Cgroup namespace to use, the default depends on the cgroup version ("host"|"private")`)
cmd.Flags().String("cgroup-parent", "", "Optional parent cgroup for the container")
cmd.RegisterFlagCompletionFunc("cgroupns", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
Expand All @@ -173,6 +172,15 @@ func setCreateFlags(cmd *cobra.Command) {
cmd.Flags().String("rdt-class", "", "Name of the RDT class (or CLOS) to associate the container with")
// #endregion

// #region blkio flags
cmd.Flags().Uint16("blkio-weight", 0, "Block IO (relative weight), between 10 and 1000, or 0 to disable (default 0)")
cmd.Flags().StringArray("blkio-weight-device", []string{}, "Block IO weight (relative device weight) (default [])")
cmd.Flags().StringArray("device-read-bps", []string{}, "Limit read rate (bytes per second) from a device (default [])")
cmd.Flags().StringArray("device-read-iops", []string{}, "Limit read rate (IO per second) from a device (default [])")
cmd.Flags().StringArray("device-write-bps", []string{}, "Limit write rate (bytes per second) to a device (default [])")
cmd.Flags().StringArray("device-write-iops", []string{}, "Limit write rate (IO per second) to a device (default [])")
// #endregion

// user flags
cmd.Flags().StringP("user", "u", "", "Username or UID (format: <name|uid>[:<group|gid>])")
cmd.Flags().String("umask", "", "Set the umask inside the container. Defaults to 0022")
Expand Down
128 changes: 128 additions & 0 deletions cmd/nerdctl/container/container_run_cgroup_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"os"
"path/filepath"
"strconv"
"strings"
"testing"

"gotest.tools/v3/assert"
Expand Down Expand Up @@ -477,3 +478,130 @@ func TestRunBlkioWeightCgroupV2(t *testing.T) {
base.Cmd("update", containerName, "--blkio-weight", "400").AssertOK()
base.Cmd("exec", containerName, "cat", "io.bfq.weight").AssertOutExactly("default 400\n")
}

func TestRunBlkioSettingCgroupV2(t *testing.T) {
testCase := nerdtest.Setup()

testCase.SubTests = []*test.Case{
{
Description: "blkio-weight",
Command: func(data test.Data, helpers test.Helpers) test.TestableCommand {
return helpers.Command("run", "-d", "--name", data.Identifier(),
"--blkio-weight", "150",
testutil.AlpineImage, "sleep", "infinity")
},
Expected: func(data test.Data, helpers test.Helpers) *test.Expected {
return &test.Expected{
ExitCode: 0,
Output: expect.All(
func(stdout string, info string, t *testing.T) {
assert.Assert(t, strings.Contains(helpers.Capture("inspect", "--format", "{{.HostConfig.BlkioWeight}}", data.Identifier()), "150"))
},
),
}
},
},
{
Description: "blkio-weight-device",
Require: nerdtest.CGroupV2,
Command: func(data test.Data, helpers test.Helpers) test.TestableCommand {
return helpers.Command("run", "-d", "--name", data.Identifier(),
"--blkio-weight-device", "/dev/sda:100",
testutil.AlpineImage, "sleep", "infinity")
},
Expected: func(data test.Data, helpers test.Helpers) *test.Expected {
return &test.Expected{
ExitCode: 0,
Output: expect.All(
func(stdout string, info string, t *testing.T) {
inspectOut := helpers.Capture("inspect", "--format", "{{range .HostConfig.BlkioWeightDevice}}{{.Weight}}{{end}}", data.Identifier())
assert.Assert(t, strings.Contains(inspectOut, "100"))
},
),
}
},
},
{
Description: "device-read-bps",
Require: nerdtest.CGroupV2,
Command: func(data test.Data, helpers test.Helpers) test.TestableCommand {
return helpers.Command("run", "-d", "--name", data.Identifier(),
"--device-read-bps", "/dev/sda:1048576",
testutil.AlpineImage, "sleep", "infinity")
},
Expected: func(data test.Data, helpers test.Helpers) *test.Expected {
return &test.Expected{
ExitCode: 0,
Output: expect.All(
func(stdout string, info string, t *testing.T) {
inspectOut := helpers.Capture("inspect", "--format", "{{range .HostConfig.BlkioDeviceReadBps}}{{.Rate}}{{end}}", data.Identifier())
assert.Assert(t, strings.Contains(inspectOut, "1048576"))
},
),
}
},
},
{
Description: "device-write-bps",
Require: nerdtest.CGroupV2,
Command: func(data test.Data, helpers test.Helpers) test.TestableCommand {
return helpers.Command("run", "-d", "--name", data.Identifier(),
"--device-write-bps", "/dev/sda:2097152",
testutil.AlpineImage, "sleep", "infinity")
},
Expected: func(data test.Data, helpers test.Helpers) *test.Expected {
return &test.Expected{
ExitCode: 0,
Output: expect.All(
func(stdout string, info string, t *testing.T) {
inspectOut := helpers.Capture("inspect", "--format", "{{range .HostConfig.BlkioDeviceWriteBps}}{{.Rate}}{{end}}", data.Identifier())
assert.Assert(t, strings.Contains(inspectOut, "2097152"))
},
),
}
},
},
{
Description: "device-read-iops",
Require: nerdtest.CGroupV2,
Command: func(data test.Data, helpers test.Helpers) test.TestableCommand {
return helpers.Command("run", "-d", "--name", data.Identifier(),
"--device-read-iops", "/dev/sda:1000",
testutil.AlpineImage, "sleep", "infinity")
},
Expected: func(data test.Data, helpers test.Helpers) *test.Expected {
return &test.Expected{
ExitCode: 0,
Output: expect.All(
func(stdout string, info string, t *testing.T) {
inspectOut := helpers.Capture("inspect", "--format", "{{range .HostConfig.BlkioDeviceReadIOps}}{{.Rate}}{{end}}", data.Identifier())
assert.Assert(t, strings.Contains(inspectOut, "1000"))
},
),
}
},
},
{
Description: "device-write-iops",
Require: nerdtest.CGroupV2,
Command: func(data test.Data, helpers test.Helpers) test.TestableCommand {
return helpers.Command("run", "-d", "--name", data.Identifier(),
"--device-write-iops", "/dev/sda:2000",
testutil.AlpineImage, "sleep", "infinity")
},
Expected: func(data test.Data, helpers test.Helpers) *test.Expected {
return &test.Expected{
ExitCode: 0,
Output: expect.All(
func(stdout string, info string, t *testing.T) {
inspectOut := helpers.Capture("inspect", "--format", "{{range .HostConfig.BlkioDeviceWriteIOps}}{{.Rate}}{{end}}", data.Identifier())
assert.Assert(t, strings.Contains(inspectOut, "2000"))
},
),
}
},
},
}

testCase.Run(t)
}
7 changes: 6 additions & 1 deletion docs/command-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,11 @@ Resource flags:
- :whale: `--pids-limit`: Tune container pids limit
- :nerd_face: `--cgroup-conf`: Configure cgroup v2 (key=value)
- :whale: `--blkio-weight`: Block IO (relative weight), between 10 and 1000, or 0 to disable (default 0)
- :whale: `--blkio-weight-device`: Block IO weight (relative device weight)
- :whale: `--device-read-bps`: Limit read rate (bytes per second) from a device
- :whale: `--device-read-iops`: Limit read rate (IO per second) from a device
- :whale: `--device-write-bps`: Limit write rate (bytes per second) to a device
- :whale: `--device-write-iops`: Limit write rate (IO per second) to a device
- :whale: `--cgroupns=(host|private)`: Cgroup namespace to use
- Default: "private" on cgroup v2 hosts, "host" on cgroup v1 hosts
- :whale: `--cgroup-parent`: Optional parent cgroup for the container
Expand Down Expand Up @@ -414,7 +419,7 @@ IPFS flags:
- :nerd_face: `--ipfs-address`: Multiaddr of IPFS API (default uses `$IPFS_PATH` env variable if defined or local directory `~/.ipfs`)

Unimplemented `docker run` flags:
`--blkio-weight-device`, `--cpu-rt-*`, `--device-*`,
`--cpu-rt-*`, `--device-cgroup-rule`,
`--disable-content-trust`, `--expose`, `--health-*`, `--isolation`, `--no-healthcheck`,
`--link*`, `--publish-all`, `--storage-opt`,
`--userns`, `--volume-driver`
Expand Down
17 changes: 15 additions & 2 deletions pkg/api/types/container_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,6 @@ type ContainerCreateOptions struct {
PidsLimit int64
// CgroupConf specifies to configure cgroup v2 (key=value)
CgroupConf []string
// BlkioWeight specifies the block IO (relative weight), between 10 and 1000, or 0 to disable (default 0)
BlkioWeight uint16
// Cgroupns specifies the cgroup namespace to use
Cgroupns string
// CgroupParent specifies the optional parent cgroup for the container
Expand All @@ -150,6 +148,21 @@ type ContainerCreateOptions struct {
Device []string
// #endregion

// #region for blkio related flags
// BlkioWeight specifies the block IO (relative weight), between 10 and 1000, or 0 to disable (default 0)
BlkioWeight uint16
// BlkioWeightDevice specifies the Block IO weight (relative device weight)
BlkioWeightDevice []string
// BlkioDeviceReadBps specifies the Block IO read rate limit(bytes per second) of a device
BlkioDeviceReadBps []string
// BlkioDeviceWriteBps specifies the Block IO write rate limit(bytes per second) of a device
BlkioDeviceWriteBps []string
// BlkioDeviceReadIOps specifies the Block IO read rate limit(IO per second) of a device
BlkioDeviceReadIOps []string
// BlkioDeviceWriteIOps specifies the Block IO read rate limit(IO per second) of a device
BlkioDeviceWriteIOps []string
// #endregion

// #region for intel RDT flags
// RDTClass specifies the Intel Resource Director Technology (RDT) class
RDTClass string
Expand Down
15 changes: 4 additions & 11 deletions pkg/cmd/container/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -331,8 +331,6 @@ func Create(ctx context.Context, client *containerd.Client, args []string, netMa

internalLabels.rm = containerutil.EncodeContainerRmOptLabel(options.Rm)

internalLabels.blkioWeight = options.BlkioWeight

// TODO: abolish internal labels and only use annotations
ilOpt, err := withInternalLabels(internalLabels)
if err != nil {
Expand Down Expand Up @@ -624,11 +622,10 @@ func withStop(stopSignal string, stopTimeout int, ensuredImage *imgutil.EnsuredI

type internalLabels struct {
// labels from cmd options
namespace string
platform string
extraHosts []string
pidFile string
blkioWeight uint16
namespace string
platform string
extraHosts []string
pidFile string
// labels from cmd options or automatically set
name string
hostname string
Expand Down Expand Up @@ -754,10 +751,6 @@ func withInternalLabels(internalLabels internalLabels) (containerd.NewContainerO
m[labels.ContainerAutoRemove] = internalLabels.rm
}

if internalLabels.blkioWeight > 0 {
hostConfigLabel.BlkioWeight = internalLabels.blkioWeight
}

if internalLabels.cidFile != "" {
hostConfigLabel.CidFile = internalLabels.cidFile
}
Expand Down
Loading

0 comments on commit d7d06b4

Please sign in to comment.