Docker核心技术—Cgroup

  • cgroup是linux对进程进行资源控制和监控的机制
  • 对CPU,内存,磁盘IO等资源进行限制
  • 针对不同类型的资源限制,只要限制策略在不同的子系统上进行关联
  • cgroup在不同管理子系统中以层级树方式进行组织,cgroup可以包含其他cgroup,使用的资源限制受本层级cgroup影响,还受父cgroup的资源限制

image.png

cgroup实现对资源的配额和度量

  • blkio 设置块设备的输入输出控制,例如磁盘光盘
  • cpu 提供cpu限制
  • cpuacct 产生Cgroup的CPU资源报告
  • cpuset 如果是多核心,这个系统会为Cgroup任务分配单独的CPU和内存资源
  • devices 允许或禁止cgroup对设备的访问
  • freezer 暂停和恢复cgroup任务
  • memory 设置Cgroup的内存限制和资源报告
  • net_cls 标记每个网络包,以供cgroup使用
  • ns 名称空间子系统
  • pid 进程标识子系统

CPU子系统

  • cpu.shares 可出让的能获得CPU时间的相对值,默认值是1024

如果有竞争,则按两个cgroup内此值的比例分配CPU时间;如果没有竞争则独占
image.png

  • cpu.cfs_period_us 配置时间周期长度
  • cpu.cfs_quota_us 配置 cgroup在cfs_period_us内最多使用多少CPU时间数,默认值是-1,表示不限制

有无竞争对于时间片的分配没有影响
image.png

  • cpu.stat cgroup 使用CPU的时间统计
  • nr_periods 经过cfs_period_us的时间周期数
  • nr_throttled 在经过的周期内,进程用光配额时间而受到限制的次数
  • throttled_time cgroup中进程被限制使用CPU的总用时,单位ns

    cpuacct子系统

    用于统计cgroup及其子cgroup下进程CPU使用情况

  • cpuacct.usage

包含cgroup及其子cgroup下进程CPU使用时间,单位ns

  • cpuacct.stat

包含cgroup及其子cgroup下进程CPU使用时间,以及用户态和内核态时间

Memory子系统

  • memory.usage_in_bytes

包含cgroup及其子cgroup下进程使用的内存

  • memory.max_usage_in_bytes

cgroup下进程使用内存的最大值,包含子cgroup内存使用量

  • memory.limit_in_bytes

设置cgroup下进程内存最大使用量,-1 表示不限制

  • memory.oom_control

cgroup内进程使用量大于limit_in_bytes时,则会被kill

调度器

  • RT调度器优先级最高
  • CFS调度器,完全公平调度器(Completely Fair Scheduler)

引入了虚拟运行时间, 使用最多

  • 怎么理解vruntime?

CFS中的就绪队列是一棵以vruntime为键值的红黑树,虚拟时间越小的进程越靠近整个红黑树的最左端。因此,调度器每次选择位于红黑树最左端的那个进程,该进程的vruntime最小。
虚拟运行时间是通过进程的实际运行时间和进程的权重(weight)计算出来的。
在CFS调度器中,将进程优先级这个概念弱化,而是强调进程的权重。一个进程的权重越大,则说明这个进程更需要运行,因此它的虚拟运行时间就越小,这样被调度的机会就越大。
vruntime=实际运行时间*1024/进程权重

Cgroup Driver

  • systemd

当操作系统使用systemd作为init system,初始化进程生成一个根cgroup目录并作为cgroup管理器
systemd与cgroup紧密结合,并且为每个systemd unit分配cgroup

  • cgroupfs

docker默认使用cgroupfs作为cgroup驱动

需要将docker的cgroup driver改为systemd,否则会出现 一鱼两吃 的情况。
kubelet默认会使用--cgroup-driver=systemd,若运行时cgroup不一致,则kubelet会报错