cgroup 介绍(1)
cgroup 介绍(1)
cgroups (abbreviated from control groups) is a Linux kernel feature that limits, accounts for and isolates the resource usage (CPU, memory, disk I/O, network, etc.) of a collection of processes.
cgroup 在内核的发展是从从2007年 2.6.24内核引入的机制。经过这些年的发展,已经发展成为docker /LXC 中间力量
cgroup定义,很多中文资料已经说明非常详细了,我这里就过多赘述.
值得注意的是,cgroup最初是依靠sysfs作为与用户的控制接口,因为会存在很多hierarchy 。
vfs在cgroup这里受到一些滥用,因此cgroup也积累的很多的问题,在vfs中可能会出现重名死锁。 在3.14的版本后,也就是2013之后,kernel对cgroup进行了巨大的修改。很多的数据结构都有了巨大的变化。其中提出来一种 Unified hierarchy 。
缺点[1][2]:
1)虽然这种树型结构可以带来一定的灵活性,但是在实际应用中可能存在一些问题,比如每个子系统在一个hierarchy只能有一 个实例,显然freezer也只能有一个实例,freezer不得不移动去控制其他进程 2)所有子系统绑定在hierarchy中,一旦hierarchy与具体pid绑定,控制granularity不好把握。 3)因为是树型结构,所以树的深度是无限的,这就使得在一个有限的资源中,子hierarchy可能会分配出有限资源外的资源。也使得管理更 加复杂 4)对多hierarchy支持限制了cgroup的使用,因为我们可以知道我们可以有12个hierarchy绑定12个子系统,也可以只有一个hierarhy绑定12个子统统
在kernel 3.16中开发了Unified hierarchy。它的目的是通过使用其他的结构,同时解决了上述缺点,保持足够的灵活性,对于大多数用例 。这个还没有被讨论。
这种新的unified hierarchy不允许remount/rename
——————-
由于从3.14后cgroup大改,放弃使用sysfs,创建一个kernfs (http://en.wikipedia.org/wiki/Kernfs_%28Linux%29)
这种方式说白了就是抽出了sysfs的核心,创建了一种新的文件系统,可以进行复用。但是这个kernfs目前只是由cgroup在使用
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=2bd59d48ebfb3df41ee56938946ca0dd30887312
这个里面对于3.14之后的更改说的比较清晰。因为使用kernfs,vfs被移除,也就是说super_block dentry, inode 和 bdi 被移除,使用cgroup_mount()直接挂载根由vfs管理的注册结构体转移到 kernfs_ops and kernfs_syscall_ops
具体的子系统,我这里简单的提一下:
- blkio — 这个子系统为块设备设定输入/输出限制,比如物理设备(磁盘,固态硬盘,USB 等 等)。
- cpu — 这个子系统使用调度程序提供对 CPU 的 cgroup 任务访问。说白了就是时间片大小!
- cpuacct — 这个子系统自动生成 cgroup 中任务所使用的 CPU 报告。
- cpuset — 这个子系统为 cgroup 中的任务分配独立 CPU(在多核系统)和内存节点。
- devices — 这个子系统可允许或者拒绝 cgroup 中的任务访问设备。
- freezer — 这个子系统挂起或者恢复 cgroup 中的任务。
- memory — 这个子系统设定 cgroup 中任务使用的内存限制,并自动生成由那些任务使用的内存资源报告。
- net_cls — 这个子系统使用等级识别符(classid)标记网络数据包,可允许 Linux 流量控制程序(tc)识别从具体 cgroup 中生成的数据包。
- ns — 名称空间子系统。
比如我们要创建一个cpu核数和memory大小受限的cgroup:
1)创建一个目录mkdir
2)挂载新的文件系统,如果我们在/sys/fs/cgroup挂载,我们要先挂载一个tmpfs,因为sysfs下不允许创建文件夹,其他允许创建文件夹的文件系统,不需要挂载tmpfs
3)$mount -t cgroup -o cpuset,memory cgroup_cpu_mem /mnt/cgroup_cpu_mem
4))我们挂载到root_cgroup的文件系统成功
5)
[lzz@localhost cgroup_cpu_mem]$ ls
cgroup.clone_children cpuset.memory_pressure_enabled memory.kmem.slabinfo memory.pressure_level
cgroup.event_control cpuset.memory_spread_page memory.kmem.tcp.failcnt memory.soft_limit_in_bytes
cgroup.procs cpuset.memory_spread_slab memory.kmem.tcp.limit_in_bytes memory.stat
cgroup.sane_behavior cpuset.mems memory.kmem.tcp.max_usage_in_bytes memory.swappiness
cgroup_test cpuset.sched_load_balance memory.kmem.tcp.usage_in_bytes memory.usage_in_bytes
cpuset.cpu_exclusive cpuset.sched_relax_domain_level memory.kmem.usage_in_bytes memory.use_hierarchy
cpuset.cpus memory.failcnt memory.limit_in_bytes notify_on_release
cpuset.mem_exclusive memory.force_empty memory.max_usage_in_bytes release_agent
cpuset.mem_hardwall memory.kmem.failcnt memory.move_charge_at_immigrate tasks
cpuset.memory_migrate memory.kmem.limit_in_bytes memory.numa_stat
cpuset.memory_pressure memory.kmem.max_usage_in_bytes memory.oom_control
我们发现在这个root cgroup里面,包括两个系统的相关设置,分别以cpuset/memory开头,上面就是建立一个hierarchy.是一个cpusset与memory的资源集合
6)在这个hierarchy下面,建立文件夹,就是建立新的cgroup,进入cgroup_test
7)然后这个cgroup_test中的设置都为0
8)具体每个字段含义,可以查看document https://www.kernel.org/doc/Documentation/cgroups/
9)我们简单的限定一下:
$echo 16M > memory.memory.limit_in_bytes
$echo 1 > cpuset.cpus
$echo 0 > cpus.mems
10)这个cgroup就可以往里面添加进程了,我们可以先添加一个shell终端 echo $$ > tasks ,然后通过这个终端启动的都会添加到该cgroup!
[1] http://lwn.net/Articles/606699/
[2] https://www.kernel.org/doc/Documentation/cgroups/unified-hierarchy.txt