Signed-off-by: Ma Shimiao <mashimiao.fnst@cn.fujitsu.com>
| ... | ... |
@@ -469,7 +469,9 @@ __docker_subcommand() {
|
| 469 | 469 |
"($help)--cidfile=[Write the container ID to the file]:CID file:_files" |
| 470 | 470 |
"($help)*--device=[Add a host device to the container]:device:_files" |
| 471 | 471 |
"($help)*--device-read-bps=[Limit the read rate (bytes per second) from a device]:device:IO rate: " |
| 472 |
+ "($help)*--device-read-iops=[Limit the read rate (IO per second) from a device]:device:IO rate: " |
|
| 472 | 473 |
"($help)*--device-write-bps=[Limit the write rate (bytes per second) to a device]:device:IO rate: " |
| 474 |
+ "($help)*--device-write-iops=[Limit the write rate (IO per second) to a device]:device:IO rate: " |
|
| 473 | 475 |
"($help)*--dns=[Set custom DNS servers]:DNS server: " |
| 474 | 476 |
"($help)*--dns-opt=[Set custom DNS options]:DNS option: " |
| 475 | 477 |
"($help)*--dns-search=[Set custom DNS search domains]:DNS domains: " |
| ... | ... |
@@ -174,6 +174,16 @@ func (daemon *Daemon) populateCommand(c *container.Container, env []string) erro |
| 174 | 174 |
return err |
| 175 | 175 |
} |
| 176 | 176 |
|
| 177 |
+ readIOpsDevice, err := getBlkioReadIOpsDevices(c.HostConfig) |
|
| 178 |
+ if err != nil {
|
|
| 179 |
+ return err |
|
| 180 |
+ } |
|
| 181 |
+ |
|
| 182 |
+ writeIOpsDevice, err := getBlkioWriteIOpsDevices(c.HostConfig) |
|
| 183 |
+ if err != nil {
|
|
| 184 |
+ return err |
|
| 185 |
+ } |
|
| 186 |
+ |
|
| 177 | 187 |
for _, limit := range ulimits {
|
| 178 | 188 |
rl, err := limit.GetRlimit() |
| 179 | 189 |
if err != nil {
|
| ... | ... |
@@ -189,18 +199,20 @@ func (daemon *Daemon) populateCommand(c *container.Container, env []string) erro |
| 189 | 189 |
CPUShares: c.HostConfig.CPUShares, |
| 190 | 190 |
BlkioWeight: c.HostConfig.BlkioWeight, |
| 191 | 191 |
}, |
| 192 |
- MemorySwap: c.HostConfig.MemorySwap, |
|
| 193 |
- KernelMemory: c.HostConfig.KernelMemory, |
|
| 194 |
- CpusetCpus: c.HostConfig.CpusetCpus, |
|
| 195 |
- CpusetMems: c.HostConfig.CpusetMems, |
|
| 196 |
- CPUPeriod: c.HostConfig.CPUPeriod, |
|
| 197 |
- CPUQuota: c.HostConfig.CPUQuota, |
|
| 198 |
- Rlimits: rlimits, |
|
| 199 |
- BlkioWeightDevice: weightDevices, |
|
| 200 |
- BlkioThrottleReadBpsDevice: readBpsDevice, |
|
| 201 |
- BlkioThrottleWriteBpsDevice: writeBpsDevice, |
|
| 202 |
- OomKillDisable: c.HostConfig.OomKillDisable, |
|
| 203 |
- MemorySwappiness: -1, |
|
| 192 |
+ MemorySwap: c.HostConfig.MemorySwap, |
|
| 193 |
+ KernelMemory: c.HostConfig.KernelMemory, |
|
| 194 |
+ CpusetCpus: c.HostConfig.CpusetCpus, |
|
| 195 |
+ CpusetMems: c.HostConfig.CpusetMems, |
|
| 196 |
+ CPUPeriod: c.HostConfig.CPUPeriod, |
|
| 197 |
+ CPUQuota: c.HostConfig.CPUQuota, |
|
| 198 |
+ Rlimits: rlimits, |
|
| 199 |
+ BlkioWeightDevice: weightDevices, |
|
| 200 |
+ BlkioThrottleReadBpsDevice: readBpsDevice, |
|
| 201 |
+ BlkioThrottleWriteBpsDevice: writeBpsDevice, |
|
| 202 |
+ BlkioThrottleReadIOpsDevice: readIOpsDevice, |
|
| 203 |
+ BlkioThrottleWriteIOpsDevice: writeIOpsDevice, |
|
| 204 |
+ OomKillDisable: c.HostConfig.OomKillDisable, |
|
| 205 |
+ MemorySwappiness: -1, |
|
| 204 | 206 |
} |
| 205 | 207 |
|
| 206 | 208 |
if c.HostConfig.MemorySwappiness != nil {
|
| ... | ... |
@@ -85,6 +85,36 @@ func parseSecurityOpt(container *container.Container, config *runconfig.HostConf |
| 85 | 85 |
return err |
| 86 | 86 |
} |
| 87 | 87 |
|
| 88 |
+func getBlkioReadIOpsDevices(config *runconfig.HostConfig) ([]*blkiodev.ThrottleDevice, error) {
|
|
| 89 |
+ var blkioReadIOpsDevice []*blkiodev.ThrottleDevice |
|
| 90 |
+ var stat syscall.Stat_t |
|
| 91 |
+ |
|
| 92 |
+ for _, iopsDevice := range config.BlkioDeviceReadIOps {
|
|
| 93 |
+ if err := syscall.Stat(iopsDevice.Path, &stat); err != nil {
|
|
| 94 |
+ return nil, err |
|
| 95 |
+ } |
|
| 96 |
+ readIOpsDevice := blkiodev.NewThrottleDevice(int64(stat.Rdev/256), int64(stat.Rdev%256), iopsDevice.Rate) |
|
| 97 |
+ blkioReadIOpsDevice = append(blkioReadIOpsDevice, readIOpsDevice) |
|
| 98 |
+ } |
|
| 99 |
+ |
|
| 100 |
+ return blkioReadIOpsDevice, nil |
|
| 101 |
+} |
|
| 102 |
+ |
|
| 103 |
+func getBlkioWriteIOpsDevices(config *runconfig.HostConfig) ([]*blkiodev.ThrottleDevice, error) {
|
|
| 104 |
+ var blkioWriteIOpsDevice []*blkiodev.ThrottleDevice |
|
| 105 |
+ var stat syscall.Stat_t |
|
| 106 |
+ |
|
| 107 |
+ for _, iopsDevice := range config.BlkioDeviceWriteIOps {
|
|
| 108 |
+ if err := syscall.Stat(iopsDevice.Path, &stat); err != nil {
|
|
| 109 |
+ return nil, err |
|
| 110 |
+ } |
|
| 111 |
+ writeIOpsDevice := blkiodev.NewThrottleDevice(int64(stat.Rdev/256), int64(stat.Rdev%256), iopsDevice.Rate) |
|
| 112 |
+ blkioWriteIOpsDevice = append(blkioWriteIOpsDevice, writeIOpsDevice) |
|
| 113 |
+ } |
|
| 114 |
+ |
|
| 115 |
+ return blkioWriteIOpsDevice, nil |
|
| 116 |
+} |
|
| 117 |
+ |
|
| 88 | 118 |
func getBlkioReadBpsDevices(config *runconfig.HostConfig) ([]*blkiodev.ThrottleDevice, error) {
|
| 89 | 119 |
var blkioReadBpsDevice []*blkiodev.ThrottleDevice |
| 90 | 120 |
var stat syscall.Stat_t |
| ... | ... |
@@ -299,6 +329,16 @@ func verifyContainerResources(resources *runconfig.Resources) ([]string, error) |
| 299 | 299 |
logrus.Warnf("Your kernel does not support Block I/O write limit in bytes per second. --device-write-bps discarded.")
|
| 300 | 300 |
resources.BlkioDeviceWriteBps = []*pblkiodev.ThrottleDevice{}
|
| 301 | 301 |
} |
| 302 |
+ if len(resources.BlkioDeviceReadIOps) > 0 && !sysInfo.BlkioReadIOpsDevice {
|
|
| 303 |
+ warnings = append(warnings, "Your kernel does not support Block read limit in IO per second.") |
|
| 304 |
+ logrus.Warnf("Your kernel does not support Block I/O read limit in IO per second. -device-read-iops discarded.")
|
|
| 305 |
+ resources.BlkioDeviceReadIOps = []*pblkiodev.ThrottleDevice{}
|
|
| 306 |
+ } |
|
| 307 |
+ if len(resources.BlkioDeviceWriteIOps) > 0 && !sysInfo.BlkioWriteIOpsDevice {
|
|
| 308 |
+ warnings = append(warnings, "Your kernel does not support Block write limit in IO per second.") |
|
| 309 |
+ logrus.Warnf("Your kernel does not support Block I/O write limit in IO per second. --device-write-iops discarded.")
|
|
| 310 |
+ resources.BlkioDeviceWriteIOps = []*pblkiodev.ThrottleDevice{}
|
|
| 311 |
+ } |
|
| 302 | 312 |
|
| 303 | 313 |
return warnings, nil |
| 304 | 314 |
} |
| ... | ... |
@@ -328,7 +368,6 @@ func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *runconfig.HostC |
| 328 | 328 |
hostConfig.OomKillDisable = false |
| 329 | 329 |
return warnings, fmt.Errorf("Your kernel does not support oom kill disable.")
|
| 330 | 330 |
} |
| 331 |
- |
|
| 332 | 331 |
if hostConfig.OomScoreAdj < -1000 || hostConfig.OomScoreAdj > 1000 {
|
| 333 | 332 |
return warnings, fmt.Errorf("Invalid value %d, range for oom score adj is [-1000, 1000].", hostConfig.OomScoreAdj)
|
| 334 | 333 |
} |
| ... | ... |
@@ -38,6 +38,14 @@ func parseSecurityOpt(container *container.Container, config *runconfig.HostConf |
| 38 | 38 |
return nil |
| 39 | 39 |
} |
| 40 | 40 |
|
| 41 |
+func getBlkioReadIOpsDevices(config *runconfig.HostConfig) ([]*blkiodev.ThrottleDevice, error) {
|
|
| 42 |
+ return nil, nil |
|
| 43 |
+} |
|
| 44 |
+ |
|
| 45 |
+func getBlkioWriteIOpsDevices(config *runconfig.HostConfig) ([]*blkiodev.ThrottleDevice, error) {
|
|
| 46 |
+ return nil, nil |
|
| 47 |
+} |
|
| 48 |
+ |
|
| 41 | 49 |
func getBlkioReadBpsDevices(config *runconfig.HostConfig) ([]*blkiodev.ThrottleDevice, error) {
|
| 42 | 50 |
return nil, nil |
| 43 | 51 |
} |
| ... | ... |
@@ -37,18 +37,20 @@ type Resources struct {
|
| 37 | 37 |
|
| 38 | 38 |
// Fields below here are platform specific |
| 39 | 39 |
|
| 40 |
- BlkioWeightDevice []*blkiodev.WeightDevice `json:"blkio_weight_device"` |
|
| 41 |
- BlkioThrottleReadBpsDevice []*blkiodev.ThrottleDevice `json:"blkio_throttle_read_bps_device"` |
|
| 42 |
- BlkioThrottleWriteBpsDevice []*blkiodev.ThrottleDevice `json:"blkio_throttle_write_bps_device"` |
|
| 43 |
- MemorySwap int64 `json:"memory_swap"` |
|
| 44 |
- KernelMemory int64 `json:"kernel_memory"` |
|
| 45 |
- CPUQuota int64 `json:"cpu_quota"` |
|
| 46 |
- CpusetCpus string `json:"cpuset_cpus"` |
|
| 47 |
- CpusetMems string `json:"cpuset_mems"` |
|
| 48 |
- CPUPeriod int64 `json:"cpu_period"` |
|
| 49 |
- Rlimits []*ulimit.Rlimit `json:"rlimits"` |
|
| 50 |
- OomKillDisable bool `json:"oom_kill_disable"` |
|
| 51 |
- MemorySwappiness int64 `json:"memory_swappiness"` |
|
| 40 |
+ BlkioWeightDevice []*blkiodev.WeightDevice `json:"blkio_weight_device"` |
|
| 41 |
+ BlkioThrottleReadBpsDevice []*blkiodev.ThrottleDevice `json:"blkio_throttle_read_bps_device"` |
|
| 42 |
+ BlkioThrottleWriteBpsDevice []*blkiodev.ThrottleDevice `json:"blkio_throttle_write_bps_device"` |
|
| 43 |
+ BlkioThrottleReadIOpsDevice []*blkiodev.ThrottleDevice `json:"blkio_throttle_read_iops_device"` |
|
| 44 |
+ BlkioThrottleWriteIOpsDevice []*blkiodev.ThrottleDevice `json:"blkio_throttle_write_iops_device"` |
|
| 45 |
+ MemorySwap int64 `json:"memory_swap"` |
|
| 46 |
+ KernelMemory int64 `json:"kernel_memory"` |
|
| 47 |
+ CPUQuota int64 `json:"cpu_quota"` |
|
| 48 |
+ CpusetCpus string `json:"cpuset_cpus"` |
|
| 49 |
+ CpusetMems string `json:"cpuset_mems"` |
|
| 50 |
+ CPUPeriod int64 `json:"cpu_period"` |
|
| 51 |
+ Rlimits []*ulimit.Rlimit `json:"rlimits"` |
|
| 52 |
+ OomKillDisable bool `json:"oom_kill_disable"` |
|
| 53 |
+ MemorySwappiness int64 `json:"memory_swappiness"` |
|
| 52 | 54 |
} |
| 53 | 55 |
|
| 54 | 56 |
// ProcessConfig is the platform specific structure that describes a process |
| ... | ... |
@@ -181,6 +183,8 @@ func SetupCgroups(container *configs.Config, c *Command) error {
|
| 181 | 181 |
container.Cgroups.BlkioWeightDevice = c.Resources.BlkioWeightDevice |
| 182 | 182 |
container.Cgroups.BlkioThrottleReadBpsDevice = c.Resources.BlkioThrottleReadBpsDevice |
| 183 | 183 |
container.Cgroups.BlkioThrottleWriteBpsDevice = c.Resources.BlkioThrottleWriteBpsDevice |
| 184 |
+ container.Cgroups.BlkioThrottleReadIOPSDevice = c.Resources.BlkioThrottleReadIOpsDevice |
|
| 185 |
+ container.Cgroups.BlkioThrottleWriteIOPSDevice = c.Resources.BlkioThrottleWriteIOpsDevice |
|
| 184 | 186 |
container.Cgroups.OomKillDisable = c.Resources.OomKillDisable |
| 185 | 187 |
container.Cgroups.MemorySwappiness = c.Resources.MemorySwappiness |
| 186 | 188 |
} |
| ... | ... |
@@ -107,6 +107,8 @@ This section lists each version from latest to oldest. Each listing includes a |
| 107 | 107 |
* Pushes initiated with `POST /images/(name)/push` and pulls initiated with `POST /images/create` |
| 108 | 108 |
will be cancelled if the HTTP connection making the API request is closed before |
| 109 | 109 |
the push or pull completes. |
| 110 |
+* `POST /containers/create` now allows you to set a read/write rate limit for a |
|
| 111 |
+ device (in bytes per second or IO per second). |
|
| 110 | 112 |
|
| 111 | 113 |
### v1.21 API changes |
| 112 | 114 |
|
| ... | ... |
@@ -248,7 +248,9 @@ Create a container |
| 248 | 248 |
"BlkioWeight": 300, |
| 249 | 249 |
"BlkioWeightDevice": [{}],
|
| 250 | 250 |
"BlkioDeviceReadBps": [{}],
|
| 251 |
+ "BlkioDeviceReadIOps": [{}],
|
|
| 251 | 252 |
"BlkioDeviceWriteBps": [{}],
|
| 253 |
+ "BlkioDeviceWriteIOps": [{}],
|
|
| 252 | 254 |
"MemorySwappiness": 60, |
| 253 | 255 |
"OomKillDisable": false, |
| 254 | 256 |
"OomScoreAdj": 500, |
| ... | ... |
@@ -306,10 +308,14 @@ Json Parameters: |
| 306 | 306 |
- **CpusetMems** - Memory nodes (MEMs) in which to allow execution (0-3, 0,1). Only effective on NUMA systems. |
| 307 | 307 |
- **BlkioWeight** - Block IO weight (relative weight) accepts a weight value between 10 and 1000. |
| 308 | 308 |
- **BlkioWeightDevice** - Block IO weight (relative device weight) in the form of: `"BlkioWeightDevice": [{"Path": "device_path", "Weight": weight}]`
|
| 309 |
-- **BlkioDeviceReadBps** - Limit read rate from a device in form of: `"BlkioDeviceReadBps": [{"Path": "device_path", "Rate": rate}]`, for example:
|
|
| 309 |
+- **BlkioDeviceReadBps** - Limit read rate (bytes per second) from a device in the form of: `"BlkioDeviceReadBps": [{"Path": "device_path", "Rate": rate}]`, for example:
|
|
| 310 | 310 |
`"BlkioDeviceReadBps": [{"Path": "/dev/sda", "Rate": "1024"}]"`
|
| 311 |
-- **BlkioDeviceWriteBps** - Limit write rate to a device in the form of: `"BlkioDeviceWriteBps": [{"Path": "device_path", "Rate": rate}]`, for example:
|
|
| 311 |
+- **BlkioDeviceWriteBps** - Limit write rate (bytes per second) to a device in the form of: `"BlkioDeviceWriteBps": [{"Path": "device_path", "Rate": rate}]`, for example:
|
|
| 312 | 312 |
`"BlkioDeviceWriteBps": [{"Path": "/dev/sda", "Rate": "1024"}]"`
|
| 313 |
+- **BlkioDeviceReadIOps** - Limit read rate (IO per second) from a device in the form of: `"BlkioDeviceReadIOps": [{"Path": "device_path", "Rate": rate}]`, for example:
|
|
| 314 |
+ `"BlkioDeviceReadIOps": [{"Path": "/dev/sda", "Rate": "1000"}]`
|
|
| 315 |
+- **BlkioDeviceWiiteIOps** - Limit write rate (IO per second) to a device in the form of: `"BlkioDeviceWriteIOps": [{"Path": "device_path", "Rate": rate}]`, for example:
|
|
| 316 |
+ `"BlkioDeviceWriteIOps": [{"Path": "/dev/sda", "Rate": "1000"}]`
|
|
| 313 | 317 |
- **MemorySwappiness** - Tune a container's memory swappiness behavior. Accepts an integer between 0 and 100. |
| 314 | 318 |
- **OomKillDisable** - Boolean value, whether to disable OOM Killer for the container or not. |
| 315 | 319 |
- **OomScoreAdj** - An integer value containing the score given to the container in order to tune OOM killer preferences. |
| ... | ... |
@@ -465,6 +471,8 @@ Return low-level information on the container `id` |
| 465 | 465 |
"BlkioWeightDevice": [{}],
|
| 466 | 466 |
"BlkioDeviceReadBps": [{}],
|
| 467 | 467 |
"BlkioDeviceWriteBps": [{}],
|
| 468 |
+ "BlkioDeviceReadIOps": [{}],
|
|
| 469 |
+ "BlkioDeviceWriteIOps": [{}],
|
|
| 468 | 470 |
"CapAdd": null, |
| 469 | 471 |
"CapDrop": null, |
| 470 | 472 |
"ContainerIDFile": "", |
| ... | ... |
@@ -31,7 +31,9 @@ Creates a new container. |
| 31 | 31 |
--cpuset-mems="" Memory nodes (MEMs) in which to allow execution (0-3, 0,1) |
| 32 | 32 |
--device=[] Add a host device to the container |
| 33 | 33 |
--device-read-bps=[] Limit read rate (bytes per second) from a device (e.g., --device-read-bps=/dev/sda:1mb) |
| 34 |
+ --device-read-iops=[] Limit read rate (IO per second) from a device (e.g., --device-read-iops=/dev/sda:1000) |
|
| 34 | 35 |
--device-write-bps=[] Limit write rate (bytes per second) to a device (e.g., --device-write-bps=/dev/sda:1mb) |
| 36 |
+ --device-write-iops=[] Limit write rate (IO per second) to a device (e.g., --device-write-iops=/dev/sda:1000) |
|
| 35 | 37 |
--disable-content-trust=true Skip image verification |
| 36 | 38 |
--dns=[] Set custom DNS servers |
| 37 | 39 |
--dns-opt=[] Set custom DNS options |
| ... | ... |
@@ -30,7 +30,9 @@ parent = "smn_cli" |
| 30 | 30 |
-d, --detach=false Run container in background and print container ID |
| 31 | 31 |
--device=[] Add a host device to the container |
| 32 | 32 |
--device-read-bps=[] Limit read rate (bytes per second) from a device (e.g., --device-read-bps=/dev/sda:1mb) |
| 33 |
+ --device-read-iops=[] Limit read rate (IO per second) from a device (e.g., --device-read-iops=/dev/sda:1000) |
|
| 33 | 34 |
--device-write-bps=[] Limit write rate (bytes per second) to a device (e.g., --device-write-bps=/dev/sda:1mb) |
| 35 |
+ --device-write-iops=[] Limit write rate (IO per second) to a device (e.g., --device-write-bps=/dev/sda:1000) |
|
| 34 | 36 |
--disable-content-trust=true Skip image verification |
| 35 | 37 |
--dns=[] Set custom DNS servers |
| 36 | 38 |
--dns-opt=[] Set custom DNS options |
| ... | ... |
@@ -632,6 +632,8 @@ container: |
| 632 | 632 |
| `--blkio-weight-device=""` | Block IO weight (relative device weight, format: `DEVICE_NAME:WEIGHT`) | |
| 633 | 633 |
| `--device-read-bps=""` | Limit read rate from a device (format: `<device-path>:<number>[<unit>]`). Number is a positive integer. Unit can be one of `kb`, `mb`, or `gb`. | |
| 634 | 634 |
| `--device-write-bps=""` | Limit write rate to a device (format: `<device-path>:<number>[<unit>]`). Number is a positive integer. Unit can be one of `kb`, `mb`, or `gb`. | |
| 635 |
+| `--device-read-iops="" ` | Limit read rate (IO per second) from a device (format: `<device-path>:<number>`). Number is a positive integer. | |
|
| 636 |
+| `--device-write-iops="" ` | Limit write rate (IO per second) to a device (format: `<device-path>:<number>`). Number is a positive integer. | |
|
| 635 | 637 |
| `--oom-kill-disable=false` | Whether to disable OOM Killer for the container or not. | |
| 636 | 638 |
| `--memory-swappiness=""` | Tune a container's memory swappiness behavior. Accepts an integer between 0 and 100. | |
| 637 | 639 |
| `--shm-size=""` | Size of `/dev/shm`. The format is `<number><unit>`. `number` must be greater than `0`. Unit is optional and can be `b` (bytes), `k` (kilobytes), `m` (megabytes), or `g` (gigabytes). If you omit the unit, the system uses bytes. If you omit the size entirely, the system uses `64m`. | |
| ... | ... |
@@ -983,15 +985,15 @@ on `/dev/sda` setting that weight to `200`: |
| 983 | 983 |
--blkio-weight-device "/dev/sda:200" \ |
| 984 | 984 |
ubuntu |
| 985 | 985 |
|
| 986 |
-The `--device-read-bps` flag limits the read rate from a device. For example, |
|
| 987 |
-this command creates a container and limits the read rate to `1mb` per second |
|
| 988 |
-from `/dev/sda`: |
|
| 986 |
+The `--device-read-bps` flag limits the read rate (bytes per second) from a device. |
|
| 987 |
+For example, this command creates a container and limits the read rate to `1mb` |
|
| 988 |
+per second from `/dev/sda`: |
|
| 989 | 989 |
|
| 990 | 990 |
$ docker run -it --device-read-bps /dev/sda:1mb ubuntu |
| 991 | 991 |
|
| 992 |
-The `--device-write-bps` flag limits the write rate to a device. For example, |
|
| 993 |
-this command creates a container and limits the write rate to `1mb` per second |
|
| 994 |
-for `/dev/sda`: |
|
| 992 |
+The `--device-write-bps` flag limits the write rate (bytes per second)to a device. |
|
| 993 |
+For example, this command creates a container and limits the write rate to `1mb` |
|
| 994 |
+per second for `/dev/sda`: |
|
| 995 | 995 |
|
| 996 | 996 |
$ docker run -it --device-write-bps /dev/sda:1mb ubuntu |
| 997 | 997 |
|
| ... | ... |
@@ -999,6 +1001,21 @@ Both flags take limits in the `<device-path>:<limit>[unit]` format. Both read |
| 999 | 999 |
and write rates must be a positive integer. You can specify the rate in `kb` |
| 1000 | 1000 |
(kilobytes), `mb` (megabytes), or `gb` (gigabytes). |
| 1001 | 1001 |
|
| 1002 |
+The `--device-read-iops` flag limits read rate (IO per second) from a device. |
|
| 1003 |
+For example, this command creates a container and limits the read rate to |
|
| 1004 |
+`1000` IO per second from `/dev/sda`: |
|
| 1005 |
+ |
|
| 1006 |
+ $ docker run -ti --device-read-iops /dev/sda:1000 ubuntu |
|
| 1007 |
+ |
|
| 1008 |
+The `--device-write-iops` flag limits write rate (IO per second) to a device. |
|
| 1009 |
+For example, this command creates a container and limits the write rate to |
|
| 1010 |
+`1000` IO per second to `/dev/sda`: |
|
| 1011 |
+ |
|
| 1012 |
+ $ docker run -ti --device-write-iops /dev/sda:1000 ubuntu |
|
| 1013 |
+ |
|
| 1014 |
+Both flags take limits in the `<device-path>:<limit>` format. Both read and |
|
| 1015 |
+write rates must be a positive integer. |
|
| 1016 |
+ |
|
| 1002 | 1017 |
## Additional groups |
| 1003 | 1018 |
--group-add: Add Linux capabilities |
| 1004 | 1019 |
|
| ... | ... |
@@ -267,6 +267,18 @@ func (s *DockerSuite) TestRunWithBlkioInvalidDeviceWriteBps(c *check.C) {
|
| 267 | 267 |
c.Assert(err, check.NotNil, check.Commentf(out)) |
| 268 | 268 |
} |
| 269 | 269 |
|
| 270 |
+func (s *DockerSuite) TestRunWithBlkioInvalidReadiopsDevice(c *check.C) {
|
|
| 271 |
+ testRequires(c, blkioWeight) |
|
| 272 |
+ out, _, err := dockerCmdWithError("run", "--device-read-iops", "/dev/sdX:500", "busybox", "true")
|
|
| 273 |
+ c.Assert(err, check.NotNil, check.Commentf(out)) |
|
| 274 |
+} |
|
| 275 |
+ |
|
| 276 |
+func (s *DockerSuite) TestRunWithBlkioInvalidWriteiopsDevice(c *check.C) {
|
|
| 277 |
+ testRequires(c, blkioWeight) |
|
| 278 |
+ out, _, err := dockerCmdWithError("run", "--device-write-iops", "/dev/sdX:500", "busybox", "true")
|
|
| 279 |
+ c.Assert(err, check.NotNil, check.Commentf(out)) |
|
| 280 |
+} |
|
| 281 |
+ |
|
| 270 | 282 |
func (s *DockerSuite) TestRunOOMExitCode(c *check.C) {
|
| 271 | 283 |
testRequires(c, oomControl) |
| 272 | 284 |
errChan := make(chan error) |
| ... | ... |
@@ -21,7 +21,9 @@ docker-create - Create a new container |
| 21 | 21 |
[**--cpuset-mems**[=*CPUSET-MEMS*]] |
| 22 | 22 |
[**--device**[=*[]*]] |
| 23 | 23 |
[**--device-read-bps**[=*[]*]] |
| 24 |
+[**--device-read-iops**[=*[]*]] |
|
| 24 | 25 |
[**--device-write-bps**[=*[]*]] |
| 26 |
+[**--device-write-iops**[=*[]*]] |
|
| 25 | 27 |
[**--dns**[=*[]*]] |
| 26 | 28 |
[**--dns-search**[=*[]*]] |
| 27 | 29 |
[**--dns-opt**[=*[]*]] |
| ... | ... |
@@ -130,9 +132,15 @@ two memory nodes. |
| 130 | 130 |
**--device-read-bps**=[] |
| 131 | 131 |
Limit read rate (bytes per second) from a device (e.g. --device-read-bps=/dev/sda:1mb) |
| 132 | 132 |
|
| 133 |
+**--device-read-iops**=[] |
|
| 134 |
+ Limit read rate (IO per second) from a device (e.g. --device-read-iops=/dev/sda:1000) |
|
| 135 |
+ |
|
| 133 | 136 |
**--device-write-bps**=[] |
| 134 | 137 |
Limit write rate (bytes per second) to a device (e.g. --device-write-bps=/dev/sda:1mb) |
| 135 | 138 |
|
| 139 |
+**--device-write-iops**=[] |
|
| 140 |
+ Limit write rate (IO per second) to a device (e.g. --device-write-iops=/dev/sda:1000) |
|
| 141 |
+ |
|
| 136 | 142 |
**--dns**=[] |
| 137 | 143 |
Set custom DNS servers |
| 138 | 144 |
|
| ... | ... |
@@ -22,7 +22,9 @@ docker-run - Run a command in a new container |
| 22 | 22 |
[**-d**|**--detach**[=*false*]] |
| 23 | 23 |
[**--device**[=*[]*]] |
| 24 | 24 |
[**--device-read-bps**[=*[]*]] |
| 25 |
+[**--device-read-iops**[=*[]*]] |
|
| 25 | 26 |
[**--device-write-bps**[=*[]*]] |
| 27 |
+[**--device-write-iops**[=*[]*]] |
|
| 26 | 28 |
[**--dns**[=*[]*]] |
| 27 | 29 |
[**--dns-opt**[=*[]*]] |
| 28 | 30 |
[**--dns-search**[=*[]*]] |
| ... | ... |
@@ -197,9 +199,15 @@ stopping the process by pressing the keys CTRL-P CTRL-Q. |
| 197 | 197 |
**--device-read-bps**=[] |
| 198 | 198 |
Limit read rate from a device (e.g. --device-read-bps=/dev/sda:1mb) |
| 199 | 199 |
|
| 200 |
+**--device-read-iops**=[] |
|
| 201 |
+ Limit read rate from a device (e.g. --device-read-iops=/dev/sda:1000) |
|
| 202 |
+ |
|
| 200 | 203 |
**--device-write-bps**=[] |
| 201 | 204 |
Limit write rate to a device (e.g. --device-write-bps=/dev/sda:1mb) |
| 202 | 205 |
|
| 206 |
+**--device-write-iops**=[] |
|
| 207 |
+ Limit write rate a a device (e.g. --device-write-iops=/dev/sda:1000) |
|
| 208 |
+ |
|
| 203 | 209 |
**--dns-search**=[] |
| 204 | 210 |
Set custom DNS search domains (Use --dns-search=. if you don't wish to set the search domain) |
| 205 | 211 |
|
| ... | ... |
@@ -219,6 +219,29 @@ func ValidateThrottleBpsDevice(val string) (*blkiodev.ThrottleDevice, error) {
|
| 219 | 219 |
}, nil |
| 220 | 220 |
} |
| 221 | 221 |
|
| 222 |
+// ValidateThrottleIOpsDevice validates that the specified string has a valid device-rate format. |
|
| 223 |
+func ValidateThrottleIOpsDevice(val string) (*blkiodev.ThrottleDevice, error) {
|
|
| 224 |
+ split := strings.SplitN(val, ":", 2) |
|
| 225 |
+ if len(split) != 2 {
|
|
| 226 |
+ return nil, fmt.Errorf("bad format: %s", val)
|
|
| 227 |
+ } |
|
| 228 |
+ if !strings.HasPrefix(split[0], "/dev/") {
|
|
| 229 |
+ return nil, fmt.Errorf("bad format for device path: %s", val)
|
|
| 230 |
+ } |
|
| 231 |
+ rate, err := strconv.ParseUint(split[1], 10, 64) |
|
| 232 |
+ if err != nil {
|
|
| 233 |
+ return nil, fmt.Errorf("invalid rate for device: %s. The correct format is <device-path>:<number>. Number must be a positive integer", val)
|
|
| 234 |
+ } |
|
| 235 |
+ if rate < 0 {
|
|
| 236 |
+ return nil, fmt.Errorf("invalid rate for device: %s. The correct format is <device-path>:<number>. Number must be a positive integer", val)
|
|
| 237 |
+ } |
|
| 238 |
+ |
|
| 239 |
+ return &blkiodev.ThrottleDevice{
|
|
| 240 |
+ Path: split[0], |
|
| 241 |
+ Rate: uint64(rate), |
|
| 242 |
+ }, nil |
|
| 243 |
+} |
|
| 244 |
+ |
|
| 222 | 245 |
// ValidateEnv validates an environment variable and returns it. |
| 223 | 246 |
// If no value is specified, it returns the current value using os.Getenv. |
| 224 | 247 |
// |
| ... | ... |
@@ -69,6 +69,12 @@ type cgroupBlkioInfo struct {
|
| 69 | 69 |
|
| 70 | 70 |
// Whether Block IO write limit in bytes per second is supported or not |
| 71 | 71 |
BlkioWriteBpsDevice bool |
| 72 |
+ |
|
| 73 |
+ // Whether Block IO read limit in IO per second is supported or not |
|
| 74 |
+ BlkioReadIOpsDevice bool |
|
| 75 |
+ |
|
| 76 |
+ // Whether Block IO write limit in IO per second is supported or not |
|
| 77 |
+ BlkioWriteIOpsDevice bool |
|
| 72 | 78 |
} |
| 73 | 79 |
|
| 74 | 80 |
type cgroupCpusetInfo struct {
|
| ... | ... |
@@ -136,11 +136,22 @@ func checkCgroupBlkioInfo(quiet bool) cgroupBlkioInfo {
|
| 136 | 136 |
if !quiet && !writeBpsDevice {
|
| 137 | 137 |
logrus.Warn("Your kernel does not support cgroup blkio throttle.write_bps_device")
|
| 138 | 138 |
} |
| 139 |
+ readIOpsDevice := cgroupEnabled(mountPoint, "blkio.throttle.read_iops_device") |
|
| 140 |
+ if !quiet && !readIOpsDevice {
|
|
| 141 |
+ logrus.Warn("Your kernel does not support cgroup blkio throttle.read_iops_device")
|
|
| 142 |
+ } |
|
| 143 |
+ |
|
| 144 |
+ writeIOpsDevice := cgroupEnabled(mountPoint, "blkio.throttle.write_iops_device") |
|
| 145 |
+ if !quiet && !writeIOpsDevice {
|
|
| 146 |
+ logrus.Warn("Your kernel does not support cgroup blkio throttle.write_iops_device")
|
|
| 147 |
+ } |
|
| 139 | 148 |
return cgroupBlkioInfo{
|
| 140 |
- BlkioWeight: weight, |
|
| 141 |
- BlkioWeightDevice: weightDevice, |
|
| 142 |
- BlkioReadBpsDevice: readBpsDevice, |
|
| 143 |
- BlkioWriteBpsDevice: writeBpsDevice, |
|
| 149 |
+ BlkioWeight: weight, |
|
| 150 |
+ BlkioWeightDevice: weightDevice, |
|
| 151 |
+ BlkioReadBpsDevice: readBpsDevice, |
|
| 152 |
+ BlkioWriteBpsDevice: writeBpsDevice, |
|
| 153 |
+ BlkioReadIOpsDevice: readIOpsDevice, |
|
| 154 |
+ BlkioWriteIOpsDevice: writeIOpsDevice, |
|
| 144 | 155 |
} |
| 145 | 156 |
} |
| 146 | 157 |
|
| ... | ... |
@@ -171,22 +171,24 @@ type Resources struct {
|
| 171 | 171 |
CPUShares int64 `json:"CpuShares"` // CPU shares (relative weight vs. other containers) |
| 172 | 172 |
|
| 173 | 173 |
// Applicable to UNIX platforms |
| 174 |
- CgroupParent string // Parent cgroup. |
|
| 175 |
- BlkioWeight uint16 // Block IO weight (relative weight vs. other containers) |
|
| 176 |
- BlkioWeightDevice []*blkiodev.WeightDevice |
|
| 177 |
- BlkioDeviceReadBps []*blkiodev.ThrottleDevice |
|
| 178 |
- BlkioDeviceWriteBps []*blkiodev.ThrottleDevice |
|
| 179 |
- CPUPeriod int64 `json:"CpuPeriod"` // CPU CFS (Completely Fair Scheduler) period |
|
| 180 |
- CPUQuota int64 `json:"CpuQuota"` // CPU CFS (Completely Fair Scheduler) quota |
|
| 181 |
- CpusetCpus string // CpusetCpus 0-2, 0,1 |
|
| 182 |
- CpusetMems string // CpusetMems 0-2, 0,1 |
|
| 183 |
- Devices []DeviceMapping // List of devices to map inside the container |
|
| 184 |
- KernelMemory int64 // Kernel memory limit (in bytes) |
|
| 185 |
- Memory int64 // Memory limit (in bytes) |
|
| 186 |
- MemoryReservation int64 // Memory soft limit (in bytes) |
|
| 187 |
- MemorySwap int64 // Total memory usage (memory + swap); set `-1` to disable swap |
|
| 188 |
- MemorySwappiness *int64 // Tuning container memory swappiness behaviour |
|
| 189 |
- Ulimits []*ulimit.Ulimit // List of ulimits to be set in the container |
|
| 174 |
+ CgroupParent string // Parent cgroup. |
|
| 175 |
+ BlkioWeight uint16 // Block IO weight (relative weight vs. other containers) |
|
| 176 |
+ BlkioWeightDevice []*blkiodev.WeightDevice |
|
| 177 |
+ BlkioDeviceReadBps []*blkiodev.ThrottleDevice |
|
| 178 |
+ BlkioDeviceWriteBps []*blkiodev.ThrottleDevice |
|
| 179 |
+ BlkioDeviceReadIOps []*blkiodev.ThrottleDevice |
|
| 180 |
+ BlkioDeviceWriteIOps []*blkiodev.ThrottleDevice |
|
| 181 |
+ CPUPeriod int64 `json:"CpuPeriod"` // CPU CFS (Completely Fair Scheduler) period |
|
| 182 |
+ CPUQuota int64 `json:"CpuQuota"` // CPU CFS (Completely Fair Scheduler) quota |
|
| 183 |
+ CpusetCpus string // CpusetCpus 0-2, 0,1 |
|
| 184 |
+ CpusetMems string // CpusetMems 0-2, 0,1 |
|
| 185 |
+ Devices []DeviceMapping // List of devices to map inside the container |
|
| 186 |
+ KernelMemory int64 // Kernel memory limit (in bytes) |
|
| 187 |
+ Memory int64 // Memory limit (in bytes) |
|
| 188 |
+ MemoryReservation int64 // Memory soft limit (in bytes) |
|
| 189 |
+ MemorySwap int64 // Total memory usage (memory + swap); set `-1` to disable swap |
|
| 190 |
+ MemorySwappiness *int64 // Tuning container memory swappiness behaviour |
|
| 191 |
+ Ulimits []*ulimit.Ulimit // List of ulimits to be set in the container |
|
| 190 | 192 |
} |
| 191 | 193 |
|
| 192 | 194 |
// HostConfig the non-portable Config structure of a container. |
| ... | ... |
@@ -57,6 +57,8 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe |
| 57 | 57 |
flDeviceReadBps = opts.NewThrottledeviceOpt(opts.ValidateThrottleBpsDevice) |
| 58 | 58 |
flDeviceWriteBps = opts.NewThrottledeviceOpt(opts.ValidateThrottleBpsDevice) |
| 59 | 59 |
flLinks = opts.NewListOpts(ValidateLink) |
| 60 |
+ flDeviceReadIOps = opts.NewThrottledeviceOpt(opts.ValidateThrottleIOpsDevice) |
|
| 61 |
+ flDeviceWriteIOps = opts.NewThrottledeviceOpt(opts.ValidateThrottleIOpsDevice) |
|
| 60 | 62 |
flEnv = opts.NewListOpts(opts.ValidateEnv) |
| 61 | 63 |
flLabels = opts.NewListOpts(opts.ValidateEnv) |
| 62 | 64 |
flDevices = opts.NewListOpts(ValidateDevice) |
| ... | ... |
@@ -118,6 +120,8 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe |
| 118 | 118 |
cmd.Var(&flBlkioWeightDevice, []string{"-blkio-weight-device"}, "Block IO weight (relative device weight)")
|
| 119 | 119 |
cmd.Var(&flDeviceReadBps, []string{"-device-read-bps"}, "Limit read rate (bytes per second) from a device")
|
| 120 | 120 |
cmd.Var(&flDeviceWriteBps, []string{"-device-write-bps"}, "Limit write rate (bytes per second) to a device")
|
| 121 |
+ cmd.Var(&flDeviceReadIOps, []string{"-device-read-iops"}, "Limit read rate (IO per second) from a device")
|
|
| 122 |
+ cmd.Var(&flDeviceWriteIOps, []string{"-device-write-iops"}, "Limit write rate (IO per second) to a device")
|
|
| 121 | 123 |
cmd.Var(&flVolumes, []string{"v", "-volume"}, "Bind mount a volume")
|
| 122 | 124 |
cmd.Var(&flTmpfs, []string{"-tmpfs"}, "Mount a tmpfs directory")
|
| 123 | 125 |
cmd.Var(&flLinks, []string{"-link"}, "Add link to another container")
|
| ... | ... |
@@ -343,23 +347,25 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe |
| 343 | 343 |
} |
| 344 | 344 |
|
| 345 | 345 |
resources := Resources{
|
| 346 |
- CgroupParent: *flCgroupParent, |
|
| 347 |
- Memory: flMemory, |
|
| 348 |
- MemoryReservation: MemoryReservation, |
|
| 349 |
- MemorySwap: memorySwap, |
|
| 350 |
- MemorySwappiness: flSwappiness, |
|
| 351 |
- KernelMemory: KernelMemory, |
|
| 352 |
- CPUShares: *flCPUShares, |
|
| 353 |
- CPUPeriod: *flCPUPeriod, |
|
| 354 |
- CpusetCpus: *flCpusetCpus, |
|
| 355 |
- CpusetMems: *flCpusetMems, |
|
| 356 |
- CPUQuota: *flCPUQuota, |
|
| 357 |
- BlkioWeight: *flBlkioWeight, |
|
| 358 |
- BlkioWeightDevice: flBlkioWeightDevice.GetList(), |
|
| 359 |
- BlkioDeviceReadBps: flDeviceReadBps.GetList(), |
|
| 360 |
- BlkioDeviceWriteBps: flDeviceWriteBps.GetList(), |
|
| 361 |
- Ulimits: flUlimits.GetList(), |
|
| 362 |
- Devices: deviceMappings, |
|
| 346 |
+ CgroupParent: *flCgroupParent, |
|
| 347 |
+ Memory: flMemory, |
|
| 348 |
+ MemoryReservation: MemoryReservation, |
|
| 349 |
+ MemorySwap: memorySwap, |
|
| 350 |
+ MemorySwappiness: flSwappiness, |
|
| 351 |
+ KernelMemory: KernelMemory, |
|
| 352 |
+ CPUShares: *flCPUShares, |
|
| 353 |
+ CPUPeriod: *flCPUPeriod, |
|
| 354 |
+ CpusetCpus: *flCpusetCpus, |
|
| 355 |
+ CpusetMems: *flCpusetMems, |
|
| 356 |
+ CPUQuota: *flCPUQuota, |
|
| 357 |
+ BlkioWeight: *flBlkioWeight, |
|
| 358 |
+ BlkioWeightDevice: flBlkioWeightDevice.GetList(), |
|
| 359 |
+ BlkioDeviceReadBps: flDeviceReadBps.GetList(), |
|
| 360 |
+ BlkioDeviceWriteBps: flDeviceWriteBps.GetList(), |
|
| 361 |
+ BlkioDeviceReadIOps: flDeviceReadIOps.GetList(), |
|
| 362 |
+ BlkioDeviceWriteIOps: flDeviceWriteIOps.GetList(), |
|
| 363 |
+ Ulimits: flUlimits.GetList(), |
|
| 364 |
+ Devices: deviceMappings, |
|
| 363 | 365 |
} |
| 364 | 366 |
|
| 365 | 367 |
config := &Config{
|