1. Docker CPU 限制

     Docker 的资源限制和隔离完全基于 Linux CGroups 。对容器最多能使用的 CPU 时间有两种限制方式。

     (1) 一是有多个 CPU 密集型的容器竞争 CPU 时,设置各个容器能使用的 CPU 时间 相对比例 。

      (2) 二是以绝对的方式设置容器 在每个调度周期内最多 能使用的 CPU 时间。

--cpuset-cpus //允许使用的 vCPU 核,格式为“0-3”、“0,1,2,3”
--cpu-shares //CPU 共享权值(相对权重)
--cpu-period //设定 CPU CFS 调度周期,范围从 1ms~1s,即 1000~1000000(单位:us)
--cpu-quota //限制在每个周期内容器能使用的 CPU 时间,必须不小于 1ms,即>=1000

我们可以设置容器可以在哪些 CPU 核上运行。例如:

docker run -it --cpuset-cpus="0,3" --name centos1 centos /bin/bash

设置容器中的进程可以在 cpu0 和 cpu3 上执行。

2. CPU 资源的相对限制

       默认情况下,所有的容器得到同等比例的 CPU 周期。在有多个容器竞争 CPU 时我们可以设置每个容器

能使用的 CPU 时间比例。这个比例叫作 共享权值 ,通过 --cpu-shares 设置。 Docker 默认每个容器的权值为 1024 ,不设置或将其设置为 0 ,都将使用这个默认值。系统会根据每个容器的共享权值和所有容器共享权

值的比例来给容器分配 CPU 时间。

例如,多任务按比例分享 CPU :

  • docker run --cpu-shares 512 容器 A
  • docker run --cpu-shares 512 容器 B
  • docker run --cpu-shares 1024 容器 C

    此时, CPU 的分配比例为 25%:25%:50% ( 1:1:2 )。倘若此后又多了一个容器竞争 CPU :

docker run --cpu-shares 512 容器 D

CPU 的分配比例将变为 20%:20%:40%:20% ( 1:1:2:1 )。

3. CPU 资源的绝对限制

Linux 通过 CFS ( Completely Fair Scheduler ,完全公平调度器) 来调度各个进程对 CPU 的使用。

CFS 默认的调度周期是 100ms 。 设置每个容器进程的调度周期,以及在这个周期内各个容器最多能使 用多少 CPU 时间。

例如:

docker run -it --cpu-period=50000 --cpu-quota=25000 centos3 centos /bin/bash

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

docker run -it --cpu-period=10000 --cpu-quota=20000 centos4 centos /bin/bash

      将容器的 CPU 配额设置为 CFS 周期的两倍, CPU 使用时间怎么会比周期大呢?其实很好解释,给容器 分配两个 vCPU 就可以了。该配置表示容器可以 在每个周期内使用两个 vCPU 的 100% 时间 。

CFS 周期的有效范围是 1ms~1s ,对应的 --cpu-period 的数值范围是 1000~1000000 。而容器的 CPU 配额 必须不小于 1ms ,即 --cpu-quota 的值必须 >=1000 。可以看出这两个选项的单位都是 us 。

注意: --cpu-quota 设置容器在一个调度周期内能使用的 CPU 时间时实际上设置的是一个上限,并不是

说容器一定会使用这么长的 CPU 时间。例如,启动一个容器,将其绑定到 cpu1 上执行,

给其 --cpu-quota 和--cpu-period 都设置为 50000 。

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

调度周期为 50000us ,容器在每个周期内最多能使用 50000us 的 cpu 时间。

4.实操:

1. 限制 CPU 使用率

(1) 利用 centos:7 镜像分别生成名为 centos1 和 centos2 的容器,其中 centos1 容器不限制 cpu 的使用率,

centos2 容器将 cpu 的使用率限制为 20% 。

docker 限制cpu docker限制cpu频率_docker

 使用--cpu-quota 选项来限制 cpu 的使用率,CFS 默认的调度周期是 100ms ,即 100000us。

20000/100000*100%=20%

(2) 通过查看对应的 cgroup 配置文件/sys/fs/cgroup/cpu/docker/容器编号/cpu.cfs_quota_us 来查看各容器 cpu 的使用率。

docker 限制cpu docker限制cpu频率_docker_02

 查看 centos1 容器的 cpu 使用率,值为-1 表示没有限制,查看 centos2 容器的 cpu 使用率,值为 20000

表示 cpu 使用率为 20%。

(3) 如需修改对应容器的 cpu 使用率,可以直接修改 cgroup 配置文件/sys/fs/cgroup/cpu/docker/容器编号

/cpu.cfs_quota_us 的值来实现。

将 centos1 的 cpu 使用率设置为 40%。

docker 限制cpu docker限制cpu频率_linux_03

值为 40000 表示 cpu 使用率为 40%。

docker 限制cpu docker限制cpu频率_docker 限制cpu_04

删除 centos1 和 centos2 容器。

2. 多任务按比例分享 CPU

(1) 利用 centos:7 镜像创建 centos3 和 centos4 容器。设置容器权重,使用 centos3 和 centos4 的 cpu 占比

为 33.3%和 66.7%。

docker 限制cpu docker限制cpu频率_docker_05

(2) 打开另一个终端,使用 docker stats 命令查看状态。

docker 限制cpu docker限制cpu频率_学习_06

 

(3) 分别再打开两个终端,利用两个终端分别进行 centos3 和 centos4 容器,安装压力测试包 stress。

新开一个终端登录:

docker 限制cpu docker限制cpu频率_docker_07

在该容器内启用 4 个线程:

docker 限制cpu docker限制cpu频率_centos_08

 使用stress -c4进行测试

新开另一个终端登录:

docker 限制cpu docker限制cpu频率_centos_09

 同样也安装stress命令

docker 限制cpu docker限制cpu频率_学习_10

在该容器内启用 4 个线程:

docker 限制cpu docker限制cpu频率_学习_11

(4) 再次利用 docker stats 命令查看。

docker 限制cpu docker限制cpu频率_学习_12

可以看到此时 centos3 和 centos4 的 cpu 组员占比为 33%和 66.7%。

3. 查看 cpu 内核使用

通过查看 Cgroup 配置文件为/sys/fs/cgroup/cpuset/docker/容器编号/cpuset.cpus。

docker 限制cpu docker限制cpu频率_学习_13

0-1 //表示有两个核心

4.对内存使用限制技术

1. 创建测试容器

利用 centos:7 镜像创建 centos5 和 centos6 容器。

docker 限制cpu docker限制cpu频率_docker_14

2. 查看容器状态  

打开一个终端,使用 docker stats 命令查看状态

docker 限制cpu docker限制cpu频率_docker_15

 

从显示结果可以看到 centos5 容器内存限制在 512M,而 centos6 容器内存无限制。

3. 查看容器内存限制

查看 centos5 容器对应的 Cgroup 配置文件可查看容器内存限制。

docker 限制cpu docker限制cpu频率_linux_16

536870912 //536870912=512×1024×1024 即 512M