Linux Cgroups使用

Cgroups是linux内核的一个功能,用来限制,控制与分离一个进程组群的资源(如CPU、内存等)。Cgroups是管理虚拟化资源手段。它提供了一个虚拟的文件系统,是进行分组管理和各子系统设置的接口,所以要使用cgroups,必须挂载cgroups文件系统。通过挂载选项指定使用哪个子系统。

cgroups介绍

相关概念

任务(task) 任务就是系统的一个进程。
控制群(control group) 控制群是一组按照某种标准划分的进程。cgroups的资源控制都是以控制群为单位实现。一个进程可以加入到某个控制群,也可以迁移到另一个控制群。
层级(hierarchy) 控制群可以组织成层级的树形式。控制群上的子节点控制群是父节点控制群的孩子,继承父控制族群的特定属性。
子系统(subsystem) 子系统是一个资源控制器,比如cpu子系统就是控制cpu时间分配的控制器。子系统必须附加到一个层级上才能起作用,一个子系统附加到某个层级以后,这个层级上的控制群都收到这个子系统的控制。

相互关系

一个子系统最多只能添加到一个层级。
一个层级可以附加到多个子系统。
一个任务是多个cgroup的成员,但是这些cgroup必须在不同的层级。
系统中的进程的子进程,自动成为其父进程所在cgroup的成员。可根据需要将子进程移动到不同的cgroup中。

一个典型的hierarchy挂载目录如下

/cgroup/
├── blkio                           <--------------- hierarchy/root cgroup                   
│   ├── blkio.io_merged             <--------------- subsystem parameter
... ...
│   ├── blkio.weight
│   ├── blkio.weight_device
│   ├── cgroup.event_control
│   ├── cgroup.procs
│   ├── lxc                         <--------------- cgroup
│   │   ├── blkio.io_merged         <--------------- subsystem parameter
│   │   ├── blkio.io_queued
... ... ...
│   │   └── tasks                   <--------------- task list
│   ├── notify_on_release
│   ├── release_agent
│   └── tasks
...

cgroup -关联一组task和一组subsystem的配置参数。一个task对应一个进程,cgroup是资源分片的最小单位。
subsystem -资源管理器,一个subsystem对应一项资源的管理,如:cpu、memory等。
hierarchy -关联一个到多个subsystem和一组树形结构的cgroup,和cgroup不同,hierarchy包含的是可管理的subsystem而非具体参数。

作用

资源限制(Resource Limitation):cgroups可以对进程组使用的资源总额进行限制。如设定应用运行时使用内存的上线,一旦超过这个配额就触发OOM。
优先级分配(Prioritization):通过分配CPU和硬盘IO各group的权重比,实际上相当于控制了进行运行的优先级。
资源统计(Accounting):cgroups可以统计系统的资源使用量,如CPU使用时长、内存用量等等,适用于计费。
进程控制(Control):cgroups可以对进程组执行挂起、恢复等操作。

cgroups子系统介绍

cpu         控制对cpu的访问
cpuacct  产生cgroup任务的cpu资源报告
cpuset    为cgroup中的任务分配单独的cpu核
memory 设置cgroup中任务的内存限制以及产生内存资源报告
blkio       设置块设备的输入输出控制
net_cls    设置网络的控制
devices   允许或拒绝cgroup任务对设备的访问
freezer   暂停或回复cgroup任务
ns           名称空间子系统

安装使用

# 安装
$ sudo yum install libcgroup
# 启用
$ sudo service cgconfig start
$ sudo service cgred start
# 查看已经存在的子系统
$ lssubsys –am
cpuset /sys/fs/cgroup/cpuset
cpu,cpuacct /sys/fs/cgroup/cpu,cpuacct
memory /sys/fs/cgroup/memory
devices /sys/fs/cgroup/devices
freezer /sys/fs/cgroup/freezer
net_cls,net_prio /sys/fs/cgroup/net_cls,net_prio
blkio /sys/fs/cgroup/blkio
perf_event /sys/fs/cgroup/perf_event
hugetlb /sys/fs/cgroup/hugetlb
pids /sys/fs/cgroup/pids

配置文件

$ vi /etc/cgconfig.conf
$ vi /etc/cgrules.conf

# 或者在/etc/cgconfig.d创建文件,配置cgroup
$ sudo touch /etc/cgconfig.d/gpdb.conf
# 重启cgconfig,就可以在 /sys/fs/cgroup/cpu下面看到gpdb目录

# 查看挂载点
$ grep cgroup /proc/mounts
tmpfs /sys/fs/cgroup tmpfs ro,nosuid,nodev,noexec,mode=755 0 0
cgroup /sys/fs/cgroup/systemd cgroup rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd 0 0
cgroup /sys/fs/cgroup/cpu,cpuacct cgroup rw,nosuid,nodev,noexec,relatime,cpuacct,cpu 0 0
cgroup /sys/fs/cgroup/memory cgroup rw,nosuid,nodev,noexec,relatime,memory 0 0
cgroup /sys/fs/cgroup/freezer cgroup rw,nosuid,nodev,noexec,relatime,freezer 0 0
cgroup /sys/fs/cgroup/net_cls,net_prio cgroup rw,nosuid,nodev,noexec,relatime,net_prio,net_cls 0 0
cgroup /sys/fs/cgroup/hugetlb cgroup rw,nosuid,nodev,noexec,relatime,hugetlb 0 0
cgroup /sys/fs/cgroup/blkio cgroup rw,nosuid,nodev,noexec,relatime,blkio 0 0
cgroup /sys/fs/cgroup/cpuset cgroup rw,nosuid,nodev,noexec,relatime,cpuset 0 0
cgroup /sys/fs/cgroup/perf_event cgroup rw,nosuid,nodev,noexec,relatime,perf_event 0 0
cgroup /sys/fs/cgroup/pids cgroup rw,nosuid,nodev,noexec,relatime,pids 0 0
cgroup /sys/fs/cgroup/devices cgroup rw,nosuid,nodev,noexec,relatime,devices 0 0

常用命令

cgclassify -将运行的任务迁移到一个或多个cgroup,例如:cgclassify -g cpu::yy [pid]
cgclear -删除层级中的所有cgroup
cgconfigparser -解析cgconfig.conf文件并挂载层级
cggreate -cgcreate在曾几种创建新cgroup
cgdelete -cgdelete命令删除指定的cgroup
cgexec -在指定的cgroup中运行任务,例如;cgexec -g "blkio:foo" dd if=/dev/zero of=/dev/null &。
cgget -查看cgroup组里面设置的资源的限制。
cgrulesengd -在cgroup中发布任务
cgset -为cgroup设定参数。路径相对于根的/cgroup,如果想设置根的参数使用gset命令
lscgroup -列出层级中的cgroup
lssubsys -列出包含子系统的层级,使用-am参数可以看到未挂载的所有子系统。

CPU限制

1. 针对CPU核心进行资源隔离

cpuset.cpus -配置使用cpu的编号,比如:0-2,5 表示使用0,1,2,和5号CPU。查看cpu可使用命令 cat /proc/cpuinfo。
cpuset.mems – 必选 – cgroup可使用的memory node

2. 针对CPU时间进行资源隔离

cfs调度策略
cpu.cfs_period_us -设定周期时间,与cfs_quota_us配置使用
cpu.cfs_quota_us -设定周期内最多可饲用的时间。该配置是task对单个cpu的使用上限,如果cfs_quota_us是cfs_period_us的两倍,就表示在两个核上完全使用
cpuset.memory_migrate – 可选 – 当cpuset.mems变化时page上的数据是否迁移, default 0
cpuset.cpu_exclusive – 可选 – 是否独占cpu, default 0
cpuset.mem_exclusive – 可选 – 是否独占memory,default 0
cpuset.mem_hardwall – 可选 – cgroup中task的内存是否隔离, default 0
cpuset.memory_pressure – 可选 – a read-only file that contains a running average of the memory pressure created by the processes in this cpuset
cpuset.memory_pressure_enabled – 可选 – cpuset.memory_pressure开关,default 0
cpuset.memory_spread_page – 可选 – contains a flag (0 or 1) that specifies whether file system buffers should be spread evenly across the memory nodes allocated to this cpuset, default 0
cpuset.memory_spread_slab – 可选 – contains a flag (0 or 1) that specifies whether kernel slab caches for file input/output operations should be spread evenly across the cpuset, default 0
cpuset.sched_load_balance – 可选 – cgroup的cpu压力是否会被平均到cpu set中的多个cpu, default 1
cpuset.sched_relax_domain_level – 可选 – cpuset.sched_load_balance的策略
-1 = Use the system default value for load balancing
0 = Do not perform immediate load balancing; balance loads only periodically
1 = Immediately balance loads across threads on the same core
2 = Immediately balance loads across cores in the same package
3 = Immediately balance loads across CPUs on the same node or blade
4 = Immediately balance loads across several CPUs on architectures with non-uniform memory access (NUMA)
5 = Immediately balance loads across all CPUs on architectures with NUMA

RT调度策略
cpu.rt_period_us -设定周期时间。
cpu.rt_runtime_us -设定周期中该cgroup运行的时间。

3. 权重CPU资源隔离

​cpu.shares -设定一个整数表示相对权重,最后的分配是该整数除以权重总和来计算相对比例,按比例分配CUP时间。比如:cgroup A设置100,cgroup B设置300,那么cgroup A中的task运行25%的CPU时间。对于一个4核的CPU系统来说,cgroup A中的task可以100%占有某一个CPU,即这个值是相对整体的一个值。

4. CPU资源隔离在sys较高的情况下是什么表现
内核资源不冲突的情况
内核资源冲突的情况

CPU使用资源统计

cpu.stat -统计信息,包含nr_periods(表示经历了几个cfs_period_us周期)、nr_throttled(表示task被限制的次数)及throttled_time(表示task被限制的总时长)
cpuacct.usage -统计cgroup中所有task的使用时长
cpuacct.stat -统计cgroup中所有task的用户态和内核态分别使用cpu的时长
cpuacct.usage_percpu -统计cgroup中所有task使用每个cpu的时长

内存限制

内存限制
memory.limit_in_bytes –内存使用量限制。
memory.memsw.limit_in_bytes –内存+swap空间使用的总量限制

OOM控制
memory.oom_control -内存超限之后的oom行为控制

内存资源审计
memory.usage_in_bytes -当前cgroup的内存使用量
memory.memsw.usage_in_bytes -当前cgroup的内存+swap的使用量
memory.max_usage_in_bytes -cgroup最大的内存+swap的使用量
memory.memsw.max_usage_in_bytes -cgroup的最大内存使用量
memory.failcnt – 报告达到最大允许内存的次数
memory.memsw.failcnt – 报告达到最大允许内存+swap的次数
memory.force_empty – 设为0且无task时,清除cgroup的内存页
memory.swappiness – 换页策略,60基准,小于60降低换出机率,大于60增加换出机率
memory.use_hierarchy – 是否影响子group
memory.stat – 报告cgroup限制状态
  cache – page cache, including tmpfs (shmem), in bytes
  rss – anonymous and swap cache, not including tmpfs (shmem), in bytes
  mapped_file – size of memory-mapped mapped files, including tmpfs (shmem), in bytes
  pgpgin – number of pages paged into memory
  pgpgout – number of pages paged out of memory
  swap – swap usage, in bytes
  active_anon – anonymous and swap cache on active least-recently-used (LRU) list, including tmpfs (shmem), in bytes
  inactive_anon – anonymous and swap cache on inactive LRU list, including tmpfs (shmem), in bytes
  active_file – file-backed memory on active LRU list, in bytes
  inactive_file – file-backed memory on inactive LRU list, in bytes
  unevictable – memory that cannot be reclaimed, in bytes
  hierarchical_memory_limit – memory limit for the hierarchy that contains the memory cgroup, in bytes
  hierarchical_memsw_limit – memory plus swap limit for the hierarchy that contains the memory cgroup, in bytes

内存软限制及内存超卖
memory.soft_limit_in_bytes -内存软限制。

进程迁移时的内存charge
memory.move_charge_at_immigrate -打开或者关闭进程迁移时的内存记账信息。

IO限制

linux的io体系层次结构

VFS层:是虚拟文件系统转换,是一个内核软件层,用来处理与Unix标准文件的所有系统调用。VFS对用户提供统一的读写等文件操作调用接口,当用户调用读写等函数时,内核则调用特定的文件系统实现。具体而言,文件在内核内存中用一个file数据结构来表示。这个数据结构包含一个f_op字段,该字段中包含了一组指向特定文件系统实现的函数指针。当用户执行read()操作时,内核调用sys_read(),然后sys_read()查找到执行该文件属于的文件系统的读函数指针,并调用它,即 file->f_op->read()。
文件系统层:不同的文件系统实现自己的操作过程,提供自己特有的特征。
页缓存层:缓存磁盘的数据页。
通用块层:由于绝大多数情况的io操作是跟块设备打交道,所以linux在此提供了一个类似vfs层的块设备操作抽象层。下层对接各种不同属性的块设备,对上提供统一的block IO请求标准。
IO调度层:因为绝大多数的块设备都是类似磁盘这样的设备,所以有必要根据这类设备的特点以及应用的不同特点来设置一些不同的调度算法和队列,以便在不同的应用环境下有针对性的提高磁盘的读写效率。针对机械硬盘的各种调度方法就是在层实现的。
块设备驱动层:驱动层对外提供相对比较高级的设备操作接口。
块设备层:这层就是具体的物理设备,定义了各种针对设备操作方法和规范。

统计信息

blkio.time -统计相关设备的分配给本组IO处理时间,单位为ms。权重是依据此时间比例进行分配的。
blkio.sectors -统计本cgroup对设备的读写扇区个数
blkio.io_service_bytes -报告CFQ scheduler统计的此cgroup对特定设备的IO操作(read, write, sync, or async)数据量
blkio.io_serviced -报告CFQ scheduler统计的此cgroup对特定设备的IO操作(read, write, sync, or async)次数
blkio.io_service_time -报告CFQ scheduler统计的此cgroup对特定设备的IO操作(read, write, sync, or async)时间(单位ns)
blkio.io_wait_time – 此cgroup对特定设备的特定操作(read, write, sync, or async)的等待时间(单位ns)
blkio.io_merged -统计本cgroup对设备的各种操作的合并处理次数,此cgroup的BIOS requests merged into IO请求的操作(read, write, sync, or async)的次数
blkio.io_queued -统计本cgroup对设备的各种操作的当前正在排队的请求个数,此cgroup的queued IO 操作(read, write, sync, or async)的请求次数
blkio.reset_stats -对本文件写入int可以对以上所有文件的值置零,重新开始累积。
blkio.avg_queue_size – 统计平均IO队列大小(需要CONFIG_DEBUG_BLK_CGROUP=y)
blkio.group_wait_time – 统计cgroup等待总时间(需要CONFIG_DEBUG_BLK_CGROUP=y, 单位ns)
blkio.empty_time – 统计cgroup无等待io总时间(需要CONFIG_DEBUG_BLK_CGROUP=y, 单位ns)
blkio.idle_time – reports the total time (in nanoseconds — ns) the scheduler spent idling for a cgroup in anticipation of a better request than those requests already in other queues or from other groups.
blkio.dequeue – 此cgroup IO操作被设备dequeue次数(需要CONFIG_DEBUG_BLK_CGROUP=y) – device_types:node_numbers number
blkio.*_recursive -对应的不带_recursive的文件的递归显示版本。
blkio.reset_stats – 重置统计信息,写int到此文件

按权重分配IO资源

blkio.weight -100-1000的相对权重,会被blkio.weight_device的特定设备权重覆盖
blkio.weight_device -特定设备的权重 – device_types:node_numbers weight

设定IO上限

每秒读写数据上限
blkio.throttle.read_bps_device
blkio.throttle.write_bps_device

每秒读写次数上限
blkio.throttle.read_iops_device
blkio.throttle.write_iops_device

每秒具体操作((read, write, sync, or async)的控制
blkio.throttle.io_serviced
blkio.throttle.io_service_bytes

网络限制

AQM

RED算法

CoDel算法

fq-codel队列规则

SFQ随机公平队列

PIE比例积分控制队列

TBF队列

HTB

网络相关的数据包处理过程

Cgroup – 从CPU资源隔离说起 
Cgroup – Linux内存资源管理 
Cgroup – Linux的IO资源隔离 
Cgroup – Linux的网络资源隔离 

cgroups介绍及安装配置使用详解 
Linux中使用cgroup来限制资源使用 
Linux Cgroup系列(04):限制cgroup的内存使用(subsystem之memory) 
Docker背后的内核知识——cgroups资源限制 
how to use cgroup  

分享到: 更多