10、Docker 资源配额-cpu 份额

10、Docker 资源配额-cpu 份额

什么是cgroup?

	cgroups其名称源自控制组群(control groups)的简写,是Linux内核的一个功能,用来限制、控制与分离一个进程组(如CPU、内存、磁盘输入输出等)。

什么是Docker资源限制?

​ 默认情况下,Docker容器是没有资源限制的,它会尽可能地使用宿主机能够分配给它的资源。如果不对容器资源进行限制,容器之间就会相互影响,一些占用硬件资源较高的容器会吞噬掉所有的硬件资源,从而导致其它容器无硬件资源可用,发生停服状态。

​ Docker提供了限制内存,CPU或磁盘IO的方法, 可以对容器所占用的硬件资源大小以及多少进行限制,我们在使用docker create创建一个容器或者docker run运行一个容器的时候就可以来对此容器的硬件资源做限制。

​ Docker 通过 cgroup 来控制容器使用的资源配额,包括 CPU、内存、磁盘三大方面,基本覆盖了常见的资源配额和使用量控制。

限制Docker使用CPU

默认设置下,所有容器可以平等地使用宿主机的CPU资源并且没有限制。

设置CPU资源的选项如下:

  • -c 或 –cpu-shares: 在有多个容器竞争 CPU 时我们可以设置每个容器能使用的 CPU 时间比例。这个比例叫做共享权值。共享式CPU资源,是按比例切分CPU资源;Docker 默认每个容器的权值为 1024。如果不指定或将其设置为0,都将使用默认值。

  • –cpus: 限制容器运行的核数;从docker1.13版本之后,docker提供了–cpus参数可以限定容器能使用的CPU核数。这个功能可以让我们更精确地设置容器CPU使用量,是一种更容易理解也常用的手段。

  • –cpuset-cpus: 限制容器运行在指定的CPU核心; 运行容器运行在哪个CPU核心上,例如主机有4个CPU核心,CPU核心标识为0-3,我启动一台容器,只想让这台容器运行在标识0和3的两个CPU核心上,可以使用cpuset来指定。

​ 与内存限额不同,通过-c设置的cpu share 并不是CPU资源的绝对数量,而是一个相对的权重值。某个容器最终能分配到的CPU资源取决于它的cpu share占所有容器cpu share总和的比例。换句话说,通过cpu share可以设置容器使用CPU的优先级。

参数:-c 或 –cpu-shares

1
2
# 说白了,给他一个弹性的加权值,多个容器会进行分抢cup份额,权重越高,占用份额越多
docker run -it --cpu-shares 1024 centos /bin/bash

​ CPU shares (relative weight) 在创建容器时指定容器所使用的 CPU 份额值。cpu-shares 的值不能保证可以获得 1 个 vcpu 或者多少 GHz 的 CPU 资源,仅仅只是一个弹性的加权值。

参数:–cpus

1
docker run -itd --name docker10 --cpuset-cpus 0,1 --cpu-shares 512 centos /bin/bash

​ 对多核 CPU 的服务器,docker 还可以控制容器运行限定使用哪些 cpu 内核和内存节点,即使用–cpuset-cpus 和–cpuset-mems 参数。对具有 NUMA 拓扑(具有多 CPU、多内存节点)的服务器尤其有用,可以对需要高性能计算的容器进行性能最优的配置。如果服务器只有一个内存节点,则–cpuset-mems 的配置基本上不会有明显效果。

参数:–cpuset-cpus

1
docker run -itd --name docker10 --cpuset-cpus 0,1 --cpu-shares 512 centos /bin/bas

​ 对多核 CPU 的服务器,docker 还可以控制容器运行限定使用哪些 cpu 内核和内存节点,即使用–cpuset-cpus 和–cpuset-mems 参数。对具有 NUMA 拓扑(具有多 CPU、多内存节点)的服务器尤其有用,可以对需要高性能计算的容器进行性能最优的配置。如果服务器只有一个内存节点,则–cpuset-mems 的配置基本上不会有明显效果。

扩展:

服务器架构一般分: SMP、NUMA、MPP 体系结构介绍

从系统架构来看,目前的商用服务器大体可以分为三类:

  1. 即对称多处理器结构(SMP : Symmetric Multi-Processor) 例: x86 服务器,双路服务器。主板上有两个物理 cpu
  2. 非一致存储访问结构 (NUMA : Non-Uniform Memory Access) 例: IBM 小型机pSeries 690
  3. 海量并行处理结构 (MPP : Massive ParallelProcessing) 。 例: 大型机 Z14

CPU 资源的绝对限制

​ Linux 通过 CFS(Completely Fair Scheduler,完全公平调度器)来调度各个进程对 CPU 的使用。CFS 默认的调度周期是 100ms。

我们可以设置每个容器进程的调度周期,以及在这个周期内各个容器最多能使用多少 CPU 时间。

  • –cpu-period 设置每个容器进程的调度周期
  • –cpu-quota 设置在每个周期内容器能使用的 CPU 时间
1
docker run -it --cpu-period=50000 --cpu-quota=25000 Centos centos /bin/bash

​ 表示将 CFS 调度的周期设为 50000,将容器在每个周期内的 CPU 配额设置为 25000,表示该容器每 50ms 可以得到 50% 的 CPU 运行时间。

docker run -it –cpu-period=10000 –cpu-quota=20000 Centos centos /bin/bash 表示将容器的 CPU 配额设置为 CFS 周期的两倍,CPU 使用时间怎么会比周期大呢?其实很好解释,给容器分配两个 CPU 就可以了。该配置表示容器可以在每个周期内使用两个 CPU 的 100% 时间。

CFS 周期的有效范围是 1ms1s,对应的–cpu-period的数值范围是 10001000000。

而容器的 CPU 配额必须不小于 1ms,即–cpu-quota的值必须 >= 1000。可以看出这两个选项的单位都是 us。

如何正确的理解 “绝对”?

–cpu-quota 设置容器在一个调度周期内能使用的 CPU 时间时实际上设置的是一个上限。 并不是说容器一定会使用这么长的 CPU 时间。

​ 启动一个容器,将其绑定到 cpu 1 上执行,给其 –cpu-quota 和 –cpu-period 都设置为 50000。表示每个容器进程的调度周期为 50000,容器在每个周期内最多能使用 50000 CPU 时间。

1
docker run -d --name mongo1 --cpuset-cpus 1 --cpu-quota=50000 --cpu-period=50000 docker.io/mongo

​ 再docker stats mongo-1 mongo-2可以观察到这两个容器,每个容器对 cpu 的使用率在 50% 左右。说明容器并没有在每个周期内使用 50000 的 cpu 时间。

使用docker stop mongo2命令结束第二个容器,再加一个参数-c 2048 启动它:

1
docker run -d --name mongo2 --cpuset-cpus 1 --cpu-quota=50000 --cpu-period=50000 -c 2048 docker.io/mongo

​ 再用docker stats mongo-1 mongo-2命令可以观察到第一个容器的 CPU 使用率在 33% 左右,第二个容器的 CPU 使用率在 66% 左右。因为第二个容器的共享值是 2048,第一个容器的默认共享值是 1024,所以第二个容器在每个周期内能使用的 CPU 时间是第一个容器的两倍。

总结

  • CPU份额控制:-c或–cpu-shares
  • CPU核控制:–cpuset-cpus、–cpus
  • CPU周期控制:–cpu-period、–cpu-quota

内存限制-物理内存和Swap

与操作系统类似,容器可以使用的内存包括两部分:物理内存和Swap。

Docker通过下面两组参数来控制容器内存的使用量。

  • -m 或 –memory:设置内存的使用限额,例如:100MB,2GB。
  • –memory-swap:设置内存+swap的使用限额。

​ 默认情况下,上面两组参数为-1,即对容器内存和swap的使用没有限制。如果在启动容器时,只指定-m而不指定–memory-swap, 那么–memory-swap默认为-m的两倍。

Docker 提供参数-m, –memory=””限制容器的内存使用量。

例 1:允许容器使用的内存上限为 128M:

1
2
3
4
5
6
[root@master1 ~]# docker run -it -m 128m centos 
查看:
[root@40bf29765691 /]# cat /sys/fs/cgroup/memory/memory.limit_in_bytes
134217728

注:也可以使用 tress 进行测试,到现在,我可以限制 docker 实例使用 cpu 的核心数和权重,可以限制内存大小。

例 2:创建一个 docker,只使用 2 个 cpu 核心,只能使用 128M 内存

1
[root@master1 ~]# docker run -it --cpuset-cpus 0,1 -m 128m centos 

例3: 允许该容器最多使用200MB的内存和100MB 的swap。

1
docker run -m 200M --memory-swap=300M ubuntu


10、Docker 资源配额-cpu 份额
http://blog.kjiang.vip/posts/1950070039.html
作者
发布于
2025年7月25日
许可协议