Skip to content

物理资源限制

对于一个容器,在某些情况下我们可能并不希望它占据所有的系统资源来运行,我们只希望分配一部分资源给容器,比如只分配给容器 2G 内存,最大只允许使用 2G,不允许再占用更多的内存,此时我们就需要对容器的资源进行限制。

bash
docker run -m 内存限制 --memory-swap=内存和交换分区总共的内存限制 镜像名称

其中-m参数是对容器的物理内存的使用限制,而--memory-swap是对内存和交换分区总和的限制,它们默认都是-1,也就是说没有任何的限制(如果在一开始仅指定-m 参数,那么交换内存的限制与其保持一致,内存+交换等于-m 的两倍大小)默认情况下跟宿主主机一样,都是 2G 内存,现在我们可以将容器的内存限制到 100M 试试看,其中物理内存 50M,交换内存 50M,尝试启动一下 SpringBoot 程序:

bash
docker run -it -m 50M --memory-swap=100M nagocoler/springboot-test:1.0

可以看到,上来就因为内存不足无法启动了:

当然除了对内存的限制之外,我们也可以对 CPU 资源进行限额,默认情况下所有的容器都可以平等地使用 CPU 资源,我们可以调整不同的容器的 CPU 权重(默认为 1024),来按需分配资源,这里需要使用到-c 选项,也可以输入全名--cpu-share:

bash
docker run -c 1024 ubuntu
docker run -c 512 ubuntu

这里容器的 CPU 权重比例为 16 比 8,也就是 2 比 1(注意多个容器时才会生效),那么当 CPU 资源紧张时,会按照此权重来分配资源,当然如果 CPU 资源并不紧张的情况下,依然是有机会使用到全部的 CPU 资源的。

这里我们使用一个压力测试工具来进行验证:

bash
docker run -c 1024 --name=cpu1024 -it ubuntu
docker run -c 512 --name=cpu512 -it ubuntu

接着我们分别进入容器安装 stress 压力测试工具:

bash
apt update && apt install -y stress

接着我们分别在两个容器中都启动压力测试工具,产生 4 个进程不断计算随机数的平方根:

bash
stress -c 4

接着我们进入 top 来看看 CPU 状态(看完之后记得赶紧去 kill 掉容器,不然 CPU 拉满很卡的):

可以看到权重高的容器中,分配到了更多的 CPU 资源,而权重低的容器中,只分配到一半的 CPU 资源。

当然我们也可以直接限制容器使用的 CPU 数量:

bash
docker run -it --cpuset-cpus=1 ubuntu

--cpuset-cpus选项可以直接限制在指定的 CPU 上运行,比如现在我们的宿主机是 2 核的 CPU,那么就可以分 0 和 1 这两个 CPU 给 Docker 使用,限制后,只会使用 CPU 1 的资源了:

可以看到,4 个进程只各自使用了 25%的 CPU,加在一起就是 100%,也就是只能占满一个 CPU 的使用率。如果要分配多个 CPU,则使用逗号隔开:

bash
docker run -it --cpuset-cpus=0,1 ubuntu

这样就会使用这两个 CPU 了:

当然也可以直接使用--cpus来限制使用的 CPU 资源数:

bash
docker run -it --cpus=1 ubuntu

限制为 1 后,只能使用一个 CPU 提供的资源,所以这里加载一起只有一个 CPU 的资源了。当然还有更精细的--cpu-period 和--cpu-quota,这里就不做介绍了。

最后我们来看一下对磁盘 IO 读写性能的限制,我们首先使用 dd 命令来测试磁盘读写速度:

bash
dd if=/dev/zero of=/tmp/1G bs=4k count=256000 oflag=direct

可以不用等待跑完,中途 Ctrl+C 结束就行:

可以看到当前的读写速度为 86.4 MB/s,我们可以通过--device-read/write-bps--device-read/write-iops参数对其进行限制。

这里要先说一下区别:

  • bps:每秒读写的数据量。
  • iops:每秒 IO 的次数。

为了直观,这里我们直接使用 BPS 作为限制条件:

bash
docker run -it --device-write-bps=/dev/sda:10MB ubuntu

因为容器的文件系统是在/dev/sda 上的,所以这我们就/dev/sda:10MB 来限制对/dev/sda 的写入速度只有 10MB/s,我们来测试一下看看:

可以看到现在的速度就只有 10MB 左右了。

提示

本文转载自青空の霞光的笔记物理资源管理