Docker 限制容器资源
一个 docker host 上会运行若干容器,每个容器都需要 CPU、内存和 IO 资源。对于 KVM,VMware 等虚拟化技术,用户可以控制分配多少 CPU、内存资源给每个虚拟机。对于容器,Docker 也提供了类似的机制避免某个容器因占用太多资源而影响其他容器乃至整个 host 的性能。 |
内存限额
与操作系统类似,容器可使用的内存包括两部分:物理内存和 swap。 Docker 通过下面两组参数来控制容器内存的使用量
-m或--memory:设置内存的使用限额,例如 100M, 2G。
--memory-swap:设置内存+swap的使用限额
Eg1:
docker run -it -m 200M --memory-swap=300M --name test ubuntu:16.04 |
其含义是允许该容器最多使用 200M 的内存和 100M 的 swap。默认情况下,上面两组参数为 -1,即对容器内存和 swap 的使用没有限制。
Eg2:
docker run -it -m 300M --memory-swap -1 --name con1 u-stress /bin/bash |
上面的 docker run 命令中通过 -m 选项限制容器使用的内存上限为 300M。同时设置 memory-swap 值为 -1,它表示容器程序使用内存的受限,而可以使用的 swap 空间使用不受限制(宿主机有多少 swap 容器就可以使用多少),把 --memory-swap 设置为 0 和不设置是一样的
Eg3:
--memory="300m" --memory-swap="1g" 的含义为: |
容器可以使用 300M 的物理内存,并且可以使用 700M(1G -300M) 的 swap。--memory-swap 居然是容器可以使用的物理内存和可以使用的 swap 之和!
压力测试工具 stress
安装:apt-get install stress
下面的 stress 命令会创建一个进程并通过 malloc 函数分配内存:
stress --vm 1 --vm-bytes 500M
Docker对cpu的限制和使用
1.CPU份额控制:
Docker 提供了 -c或者–cpu-shares参数,在创建容器时指定容器所使用的 CPU 份额值。如果不指定,默认值为1024。
docker run -tid --cpu-shares 100 ubuntu:stress
两个容器A、B的 CPU 份额分别为1000和500,在 CPU 进行时间片分配的时候,容器 A 比容器 B 多一倍的机会获得 CPU 的时间片,但分配的结果取决于当时主机和其他容器的运行状态,实际上也无法保证容器A一定能获得 CPU 时间片。比如容器A的进程一直是空闲的,那么容器B是可以获取比容器A更多的 CPU 时间片的。极端情况下,比如说主机上只运行了一个容器,即使它的 CPU 份额只有 50,它也可以独占整个主机的 CPU 资源。
cgroups 只在容器分配的资源紧缺时,也就是说在需要对容器使用的资源进行限制时,才会生效。因此,无法单纯根据某个容器的 CPU 份额来确定有多少 CPU 资源分配给它,资源分配结果取决于同时运行的其他容器的 CPU 分配和容器中进程运行情况。
换句话说:通过 cpu share 可以设置容器使用 CPU 的优先级。
2.CPU周期控制
docker 提供了--cpu-period、--cpu-quota两个参数控制容器可以分配到的 CPU 时钟周期。 --cpu-period是用来指定容器对 CPU 的使用要在多长时间内做一次重新分配。
--cpu-quota是用来指定在这个周期内,最多可以有多少时间用来跑这个容器。跟 –cpu-shares 不同的是这种配置是指定一个绝对值,而且没有弹性在里面,容器对 CPU 资源的使用绝对不会超过配置的值。
使用示例:[ cpu-period 设置为1000000(即1秒),cpu-quota 设置为 200000(0.2秒)]
docker run -tid --cpu-period 100000 --cpu-quota 200000 ubuntu
3.限制CPU个数:
在 docker 1.13 及更高的版本上,能够很容易的限制容器可以使用的主机 CPU 个数。只需要通过 --cpus 选项指定容器可以使用的 CPU 个数就可以了,并且还可以指定如 1.5 之类的小数。
通过下面的命令创建容器,--cpus=2 表示容器最多可以使用主机上两个 CPU:
$ docker run -it --rm --cpus=1.5 ubuntu:16.04 /bin/bash
使用特定0-1的cpu:
docker run -idt --name a1 --cpuset-cpus=0-1 ubuntu:18.04 /bin/bash
安装压力测试工具:
# apt-get install stress
然后由 stress 命令创建四个繁忙的进程消耗 CPU 资源:
# stress -c 4
如果多个容器使用,可能会平均分配cpu [同时压力测试]
一个结束后,另外那个会使用尽可能使用cpu,直到到限制的cpu为止
对 Block IO 的限制[https://blog.51cto.com/wzlinux/2046566?source=drt]
Block IO 是另一种可以限制容器使用的资源。Block IO 指的是磁盘的读写,docker 可通过设置权重、限制 bps 和 iops 的方式控制容器读写磁盘的带宽
block IO 权重
默认情况下,所有容器能平等地读写磁盘,可以通过设置--blkio-weight参数来改变容器 block IO 的优先级。
--blkio-weight 与 --cpu-shares 类似,设置的是相对权重值,默认为 500。在下面的例子中,container_A 读写磁盘的带宽是 container_B 的两倍。
docker run -it --name container_A --blkio-weight 600 ubuntu
docker run -it --name container_B --blkio-weight 300 ubuntu
限制 bps 和 iops
同样的,我们可以在 /sys/fs/cgroup/blkio/docker 看到 block IO 的数值。
bps 是 byte per second,每秒读写的数据量。
iops 是 io per second,每秒 IO 的次数。
可通过以下参数控制容器的 bps 和 iops:
--device-read-bps,限制读某个设备的 bps。
--device-write-bps,限制写某个设备的 bps。
--device-read-iops,限制读某个设备的 iops。
--device-write-iops,限制写某个设备的 iops。
例子:【限制容器写 /dev/sda 的速率为 30 MB/s】
docker run -it --device-write-bps /dev/sda:30MB --name u2 ubuntu:18.04
通过 dd 测试在容器中写磁盘的速度。因为容器的文件系统是在 host /dev/sda 上的,在容器中写文件相当于对 host /dev/sda 进行写操作。另外,oflag=direct 指定用 direct IO 方式写文件,这样 --device-write-bps 才能生效。
结果表明,bps 23.4 MB/s 没有超过 30 MB/s 的限速。
测试对比:
docker run -it --name u1 ubuntu:18.04