1)指定 docker 容器可以使用的 cpu 份额

  查看配置份额的帮助命令

  docker run --help | grep cpu-shares
  cpu 配额参数:-c, --cpu-shares
  CPU shares (relative weight) 在创建容器时指定容器所使用的 CPU 份额值。

  cpu-shares 的值不能保证可以获得 1 个 vcpu 或者多少 GHz 的 CPU 资源,仅仅只是一个弹性的加权值。

  默认每个 docker 容器的 cpu 份额值都是 1024。

  在同一个 CPU 核心上,同时运行多个容器时,容器的cpu 加权的效果才能体现出来。

  例: 两个容器 A、B 的 cpu 份额分别为 1000 和 500,结果会怎么样?

  情况 1:A 和 B 正常运行,占用同一个 CPU,在 cpu 进行时间片分配的时候,容器 A 比容器 B 多一倍的机会获得 CPU 的时间片。
  情况 2:分配的结果取决于当时其他容器的运行状态。比如容器 A 的进程一直是空闲的,那么容器 B是可以获取比容器 A 更多的 CPU 时间片的;

   比如主机上只运行了一个容器,即使它的 cpu 份额只有50,它也可以独占整个主机的 cpu 资源。
 
  cgroups 只在多个容器同时争抢同一个 cpu 资源时,cpu 配额才会生效。

  因此,无法单纯根据某个容器的 cpu 份额来确定有多少 cpu 资源分配给它,

  资源分配结果取决于同时运行的其他容器的 cpu 分配和容器中进程运行情况。

例 1:给容器实例分配 512 权重的 cpu 使用份额 
参数: --cpu-shares 512

  docker run -it --cpu-shares 512 centos /bin/bash

  cat /sys/fs/cgroup/cpu/cpu.shares #查看结果:512

  通过-c 设置的 cpu share 并不是 CPU 资源的绝对数量,而是一个相对的权重值。某个容器最终能

  分配到的 CPU 资源取决于它的 cpu share 占所有容器 cpu share 总和的比例。通过 cpu share

  可以设置容器使用 CPU 的优先级。


  比如在 host 中启动了两个容器:

  docker run --name "container_A" -c 1024 ubuntu

  docker run --name "container_B" -c 512 ubuntu

  container_A 的 cpu share 1024,是 container_B 的两倍。当两个容器都需要 CPU 资源时,

  container_A 可以得到的 CPU 是 container_B 的两倍。

  需要注意的是,这种按权重分配 CPU 只会发生在 CPU 资源紧张的情况下。如果 container_A 处于空

  闲状态,为了充分利用 CPU 资源,container_B 也可以分配到全部可用的 CPU。

 

2)CPU core 核心控制

  参数:--cpuset 可以绑定 CPU

  对多核 CPU 的服务器,docker 还可以控制容器运行限定使用哪些 cpu 内核和内存节点,即使用--

  cpuset-cpus 和--cpuset-mems 参数。对具有 NUMA 拓扑(具有多 CPU、多内存节点)的服务器尤其有

  用,可以对需要高性能计算的容器进行性能最优的配置。

  如果服务器只有一个内存节点,则--cpuset-mems 的配置基本上不会有明显效果

3)CPU 配额控制参数的混合使用

 

  在上面这些参数中,cpu-shares 控制只发生在容器竞争同一个 cpu 的时间片时有效。

  如果通过 cpuset-cpus 指定容器 A 使用 cpu 0,容器 B 只是用 cpu1,在主机上只有这两个容器使用

  对应内核的情况,它们各自占用全部的内核资源,cpu-shares 没有明显效果。

 

  如何才能有效果?

 

  容器 A 和容器 B 配置上 cpuset-cpus 值并都绑定到同一个 cpu 上,然后同时抢占 cpu 资源,就可以看出效果了。

  例 1:测试 cpu-shares 和 cpuset-cpus 混合使用运行效果,就需要一个压缩力测试工具 stress 来让容器实例把 cpu 跑满。

  如何把 cpu 跑满?

  如何把 4 核心的 cpu 中第一和第三核心跑满?可以运行 stress,然后使用 taskset 绑定一下 cpu。


  linux 系统压力测试软件 Stress

yum install -y epel-release
 yum install stress -y

例 1:产生 2 个 cpu 进程,2 个 io 进程,20 秒后停止运行 
 stress -c 2 -i 2 --verbose --timeout 20s

 docker run -itd --name docker10 --cpuset-cpus 0,1 --cpu-shares 
512 centos /bin/bash 
#指定 docker10 只能在 cpu0 和 cpu1 上运行,而且 docker10 的使用 cpu 的份额 512 
#参数-itd 就是又能打开一个伪终端,又可以在后台运行着 docker 实例 

 docker run -itd --name docker20 --cpuset-cpus 0,1 --cpu-shares 
1024 centos /bin/bash
 #指定 docker20 只能在 cpu0 和 cpu1 上运行,而且 docker20 的使用 cpu 的份额 1024,比 dcker10 多一倍

测试 1: 进入 docker10,使用 stress 测试进程是不是只在 cpu0,1 上运行:
docker exec -it docker10 /bin/bash
yum install -y epel-release #安装 epel 扩展源
yum install stress -y #安装 stress 命令
stress -c 2 -v -t 10m #运行 2 个进程,把两个 cpu 占满 
在物理机另外一个虚拟终端上运行 top 命令,按 1 快捷键,可看到正常。只在 cpu0,1 上运行

测试 2: 然后进入 docker20,使用 stress 测试进程是不是只在 cpu0,1 上运行,且 docker20 上运行
的 stress 使用 cpu 百分比是 docker10 的 2 倍

docker exec -it docker20 /bin/bash
yum install -y epel-release #安装 epel 扩展源
yum install stress -y
stress -c 2 -v -t 10m

在另外一个虚拟终端上运行 top 命令,按 1 快捷键,查看每个 cpu 使用情况
两个容器只在 cpu0,1 上运行,说明 cpu 绑定限制成功。
而 docker20 是 docker10 使用 cpu 的 2倍。说明--cpu-shares 限制资源成功。