Docker 之 使用cgroups实现资源限制

Docker 之 使用cgroups实现资源限制

参考:Docker cgroup

cgroups是什么

cgroup是一个强大的内核工具。通俗的来说,cgroups 可以限制、记录、隔离进程组所使用的物理资源(包括:CPU、memory、IO 等),为容器实现虚拟化提供了基本保证,是构建 Docker 等一系列虚拟化管理工具的基石。

本质上来说,cgroups 是内核附加在程序上的一系列钩子(hooks),通过程序运行时对资源的调度触发相应的钩子以达到资源追踪和限制的目的

cgroups的作用

资源限制、优先级分配、资源统计、进程控制

术语表

  • task(任务):cgroups 的术语中,task 就表示系统的一个进程。
  • cgroup(控制组):cgroups 中的资源控制都以 cgroup 为单位实现。cgroup 表示按某种资源控制标准划分而成的任务组,包含一个或多个子系统。一个任务可以加入某个 cgroup,也可以从某个 cgroup 迁移到另外一个 cgroup。
  • subsystem(子系统):cgroups 中的 subsystem 就是一个资源调度控制器(Resource Controller)。比如 CPU 子系统可以控制 CPU 时间分配,内存子系统可以限制 cgroup 内存使用量。
  • hierarchy(层级树):hierarchy 由一系列 cgroup 以一个树状结构排列而成,每个 hierarchy 通过绑定对应的 subsystem 进行资源调度。hierarchy 中的 cgroup 节点可以包含零或多个子节点,子节点继承父节点的属性。整个系统可以有多个 hierarchy
    在这里插入图片描述

子系统

subsystem 实际上就是 cgroups 的资源控制系统,每种 subsystem 独立地控制一种资源,目前 Docker 使用如下八种 subsystem

  • blkio: 这个 subsystem 可以为块设备设定输入 / 输出限制,比如物理驱动设备(包括磁盘、固态硬盘、USB 等)。
  • cpu: 这个 subsystem 使用调度程序控制 task 对 CPU 的使用。
  • cpuacct: 这个 subsystem 自动生成 cgroup 中 task 对 CPU 资源使用情况的报告。
  • cpuset: 这个 subsystem 可以为 cgroup 中的 task 分配独立的 CPU(此处针对多处理器系统)和内存。
  • devices 这个 subsystem 可以开启或关闭 cgroup 中 task 对设备的访问。
  • freezer 这个 subsystem 可以挂起或恢复 cgroup 中的 task。
  • memory 这个 subsystem 可以设定 cgroup 中 task 对内存使用量的限定,并且自动生成这些 task 对内存资源使用情况的报告。
  • perf_event_ _ 这个 subsystem 使用后使得 cgroup 中的 task 可以进行统一的性能测试。
  • net_cls 这个 subsystem Docker 没有直接使用,它通过使用等级识别符 (classid) 标记网络数据包,从而允许 Linux 流量控制程序(TC:Traffic Controller)识别从具体 cgroup 中生成的数据包。

cgroup实现方式及工作原理简介

cgroups 的实现本质上是给系统进程挂上钩子(hooks),当 task 运行的过程中涉及到某个资源时就会触发钩子上所附带的 subsystem 进行检测,最终根据资源类别的不同使用对应的技术进行资源限制和优先级分配

cgroup使用方法

包括:

  • 安装cgroups 工具库
  • 查询 cgroup 及子系统挂载状态
  • 创建 hierarchy 层级并挂载子系统
  • 卸载 cgroup
  • 设置 cgroups 参数
  • 添加 task 到 cgroup
    其中,设置cgroup参数即是对资源的控制参数设置。直接对之前创建的 cgroup 对应文件夹下的文件写入即可,举例如下。
设置 task 允许使用的 cpu 为 0 和 1:
echo 0-1 > /sys/fs/cgroup/cg1/cpuset.cpus

或用cgset命令

cgset -r cpuset.cpus=0-1 cpu,memory:/

子系统参数配置用法

1)CPU资源控制

两种策略:

  1. 完全公平调度 (CFS:Completely Fair Scheduler)策略,体现在限额和比例分配。docker中使用的似乎是这个策略
  2. 实时调度(Real-Time Scheduler)策略,体现在实时进程按周期分配固定的运行时间,单位为微秒(μs)。

针对1——CFS:
1)设置限额

  • cpu.cfs_period_us:设定周期时间,必须与cfs_quota_us配合使用。
  • cpu.cfs_quota_us :设定周期内最多可使用的时间。这里的配置指 task 对单个 cpu 的使用上限,若cfs_quota_us是cfs_period_us的两倍,就表示在两个核上完全使用。数值范围为 1000 - 1000,000(微秒)。
  • cpu.stat:统计信息,包含nr_periods(表示经历了几个cfs_period_us周期)、nr_throttled(表示 task 被限制的次数)及throttled_time(表示 task 被限制的总时长)。
    2)设置比例
  • cpu.shares:设定一个整数(必须大于等于 2)表示相对权重,最后除以权重总和算出相对比例,按比例分配 CPU 时间。
    针对2——RT:
    与公平调度策略中的按周期分配时间的方法类似:
  • cpu.rt_period_us :设定周期时间。
  • cpu.rt_runtime_us:设定周期中的运行时间。
2)CPU绑定

为 task 分配独立 CPU 资源的子系统,参数较多,这里只选讲两个必须配置的参数,同时 Docker 中目前也只用到这两个。

  • cpuset.cpus:在这个文件中填写cgroup可使用的 CPU 编号,如0-2,16代表 0、1、2 和 16 这 4 个 CPU。
  • cpuset.mems:与CPU类似,表示 cgroup 可使用的memory node,格式同上
3)内存资源管理

限额类

  • memory.limit_bytes:强制限制最大内存使用量,单位有k、m、g三种,填-1则代表无限制。
  • memory.soft_limit_bytes:软限制,只有比强制限制设置的值小时才有意义。填写格式同上。当整体内存紧张的情况下,task 获取的内存就被限制在软限制额度之内,以保证不会有太多进程因内存挨饿。可以看到,加入了内存的资源限制并不代表没有资源竞争。
  • memory.memsw.limit_bytes:设定最大内存与 swap 区内存之和的用量限制。填写格式同上。
    报警与自动控制
  • memory.oom_control:改参数填 0 或 1, 0表示开启,当 cgroup 中的进程使用资源超过界限时立即杀死进程,1表示不启用。默认情况下,包含 memory 子系统的 cgroup 都启用。当oom_control不启用时,实际使用内存超过界限时进程会被暂停直到有空闲的内存资源。

补充

Linux cgroups的使用

主要就是限制某个cgroups的资源,并把某个task加入都该cgroup中,具体看原文

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值