Docker资源管理【CPU篇】

前言

cgroups 是Docker的两大核心之一,另一个是namespace ,在讲解网络篇时有提到。cgroups是控制群组,是linux 内核用来限制资源,如内存,磁盘,网络等。

CPU 限制

认识参数

docker 是通过 CPU cgroups 来限制容器使用的cpu上限,而和CPU groups 三个比较重要的参数是: cpu.cfs_quota_us、cpu.cfs_period_us、cpu.shares.

在 linux 中,使用top查看的时候,可以看到几个 %Cpu(s) 开头的这一行

类型

说明

us

用户态cpu

sy

内核态cpu时间

ni

nice 值1-19的进程用户态cpu时间,代表优化级比较低的进程运行占用的时间

id

系统空闲时间

wa

iowait,系统等待io的cpu时间

hi

hardware irq,处理硬中断时间

si

softirq,处理软中断时间

st

steal,同一个宿主机上的其他虚拟机抢走的时间

从上面可以看出来,cpu时间分成 用户态(us,ni) 与 内核态(sy,wa,hi,si),而内核态中的 wa,hi,si 等这些,cpu groups 不是会进行限制的。

Cgroup 子系统是通过一个虚拟文件挂载点进行管理的,通常是在 /sys/fs/cgroup/cpu 这个目录下。

Linux 通过 CFS(完全公平调度器) 来对调度进程对cpu的使用,默认调度周期是 100ms。影响CFS的有三个参数

  • cpu.cfs_period_us ,是CFS 调度的周期,默认是 100000,单位是 microseconds 也就是 100ms
  • cpu.cfs_quota_us 在一个调度周期里,这个控制组被允许的运行时间,比如 30000 ,就是 30ms

这两个参数进行除法
cpu.cfs_quota_us/cpu.cfs_period_us ,比如 30ms /100ms = 0.3 ,表示这个控制组被允许使用的CPU最大配额是 0.3个cpu

  • cpu.shares 这个值是在 CPU 被占满时,CPU Cgroup 子系统控制组可用CPU的相对比例

这里有一个比较有意思的现象,如果启动两个容器,容器A与容器B,而 A与B的 cpu.shares值分别是1024与512 ,如果B启动后,没有运行任何线程,这时候B自己的 cpu会使用不完,而A 里有很多的线程在跑,这时候就会将容器B的空闲资源占用,也就是CPU是共享的; 后面如果B里也开始跑线程了,就会把自己的资源进行要回来,这时候docker就会按 1024: 512进行划分,也就是 A 会占用 2/3 ,说明cpu是可压缩的资源。

cpu cgroup 数据

查看 cpu的 cgroup 数据,在 /sys/fs/cgroup/cpu下

在目录下有

cgroup.procs 文件,里面当前控制组要控制哪些进程的PID列表

cgroup.cfs_quota_us 这里默认是-1,也就是不限制

当我们创建一个受限制的docker 容器时,会在 /sys/fs/cgroup/cpu/docker下创建一个容器id为名的控制组

启动 docker 时,可以指定参数

-c 或是 --cpu-shares 有多个容器竞争cpu时的比例 (调整 cpu.shares)

--cpus 在docker 1.13 以后,可以限定使用的容器核心数(也就是调整 cpu.cfs_quota_us的值)

也可以通过

--cpu-period、--cpu-quota 分别调整 cpu.cfs_period_us 和 cpu.cfs_quota_us

举例:

进入到对应的控制组里,查看对应的 cgroup.procs 和 cgroup.cfs_quota_us 的值

这些也是当前启动的nginx 容器对应的进程 id,和刚才启动参数里设置的参数 --cpus=0.3的值

原文链接:,转发请注明来源!