发布网友 发布时间:2022-04-22 08:08
共1个回答
热心网友 时间:2022-04-14 06:20
Cgroup和Namespace在测试中的使用(上)
很多时候需要测试程序在资源受限情况下的表现,普通的做法可能是不断对系统加压使能够分配给目标程序的资源变少,换另一个思路思考,可以尝试*分配给目标程序的资源总数,使得机器状态健康的情况下让程序资源使用达到饱和。
作为一个正在做着容器项目的人,知道容器技术是依靠Cgroup和Namespace来实现的。在容器中,cpu和内存资源是使用Cgroup来控制,PID、IPC、网络等资源是通过Namespace来划分。在程序没有部署在容器的情况下,我们仍可以利用Cgoup和Namespace来构造场景完成一些异常测试,如利用Cgroup的资源控制功能做资源满载的测试;利用Namespace的资源隔离特性做一些网络异常测试而不影响其他程序的运行。
Cgroup介绍
Cgroup是进行分组化管理的Linux内核功能,具体的资源管理是通过子系统来完成的。可以理解为子系统就是资源控制器,每种子系统就是一个资源的分配器,比如cpu子系统是控制cpu时间分配的,使用方式如下
安装(ubuntu)
#apt-get install cgroup-bin
基本命令
cgclassify -- cgclassify命令是用来将运行的任务移动到一个或者多个cgroup。
cgclear -- cgclear 命令是用来删除层级中的所有cgroup。
cgconfig.conf -- 在cgconfig.conf文件中定义cgroup。
cgconfigparser -- cgconfigparser命令解析cgconfig.conf文件和并挂载层级。
cgcreate -- cgcreate在层级中创建新cgroup。
cgdelete -- cgdelete命令删除指定的cgroup。
cgexec -- cgexec命令在指定的cgroup中运行任务。
cgget -- cgget命令显示cgroup参数。
cgred.conf -- cgred.conf是cgred服务的配置文件。
cgrules.conf -- cgrules.conf 包含用来决定何时任务术语某些 cgroup的规则。
cgrulesengd -- cgrulesengd 在 cgroup 中发布任务。
cgset -- cgset 命令为 cgroup 设定参数。
lscgroup -- lscgroup 命令列出层级中的 cgroup。
lssubsys -- lssubsys 命令列出包含指定子系统的层级
子系统说明
可以使用lssubsys -a来列出系统支持多少种子系统,和:比如cpu是控制cpu时间片的,memory是控制内存使用的
#lssubsys -a
cpuset
cpu,cpuacct
memory
devices
freezer
net_cls,net_prio
blkio
perf_event
hugetlb
主要的几种子系统说明如下:
blkio 这个子系统设置*每个块设备的输入输出控制。例如:磁盘,光盘以及usb等等。
cpu 这个子系统使用调度程序为cgroup任务提供cpu的访问。
cpuacct 产生cgroup任务的cpu资源报告。
cpuset 如果是多核心的cpu,这个子系统会为cgroup任务分配单独的cpu和内存。
devices 允许或拒绝cgroup任务对设备的访问。
freezer 暂停和恢复cgroup任务。
memory 设置每个cgroup的内存*以及产生内存资源报告。
net_cls 标记每个网络包以供cgroup方便使用。
ns 名称空间子系统
perf_event: 增加了对每group的监测跟踪的能力,即可以监测属于某个特定的group的所有线程以及运行在特定CPU上的线程
要为Cgroup分配*的资源,首先要挂载子系统,然后才有控制组,比如想要对目标程序进行内存*,那就需要挂载memory子系统
使用lssubsys -am来显示已经挂载的子系统
#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
可以手动挂载或者卸载子系统,如执行umount /sys/fs/cgroup/memory,memory子系统就被卸载了,这时候手动执行# mount -t cgroup -o memory memory /sys/fs/cgroup/memory就又挂载上了。
要确保需要的子系统都挂上了,不然创建控制组的时候会报错 is not mounted
#cgcreate -g memory,cpu:/hzmali_test
cgcreate: can't create cgroup /hzmali_test: Cgroup one of theneeded subsystems is not mounted
如何创建control group(即需要资源管理的组)呢, 这里用cgcreate命令,当然也有其他方法, 如cgconfig.conf等
#cgcreate -g memory,cpu:/hzmali_test
这里有个重要特性:一个组可以同时做多个资源的*,如这里我同时*了memory和cpu,然后memory和cpu子系统目录下会自动生成这个组的目录和些文件,如memory
#/sys/fs/cgroup/memory/hzmali_test$ ls -lrt
-rw-r--r-- 1 root root 0 Jul 26 20:56 tasks
-rw-r--r-- 1 root root 0 Jul 26 20:56 notify_on_release
-rw-r--r-- 1 root root 0 Jul 26 20:56 memory.use_hierarchy
-r--r--r-- 1 root root 0 Jul 26 20:56 memory.usage_in_bytes
-rw-r--r-- 1 root root 0 Jul 26 20:56 memory.swappiness
-r--r--r-- 1 root root 0 Jul 26 20:56 memory.stat
-rw-r--r-- 1 root root 0 Jul 26 20:56 memory.soft_limit_in_bytes
---------- 1 root root 0 Jul 26 20:56 memory.pressure_level
-rw-r--r-- 1 root root 0 Jul 26 20:56 memory.oom_control
-r--r--r-- 1 root root 0 Jul 26 20:56 memory.numa_stat
-rw-r--r-- 1 root root 0 Jul 26 20:56memory.move_charge_at_immigrate
-rw-r--r-- 1 root root 0 Jul 26 20:56 memory.max_usage_in_bytes
-rw-r--r-- 1 root root 0 Jul 26 20:56 memory.limit_in_bytes
-r--r--r-- 1 root root 0 Jul 26 20:56 memory.kmem.usage_in_bytes
-r--r--r-- 1 root root 0 Jul 26 20:56memory.kmem.tcp.usage_in_bytes
-rw-r--r-- 1 root root 0 Jul 26 20:56memory.kmem.tcp.max_usage_in_bytes
-rw-r--r-- 1 root root 0 Jul 26 20:56memory.kmem.tcp.limit_in_bytes
-rw-r--r-- 1 root root 0 Jul 26 20:56 memory.kmem.tcp.failcnt
-r--r--r-- 1 root root 0 Jul 26 20:56 memory.kmem.slabinfo
-rw-r--r-- 1 root root 0 Jul 26 20:56memory.kmem.max_usage_in_bytes
-rw-r--r-- 1 root root 0 Jul 26 20:56 memory.kmem.limit_in_bytes
-rw-r--r-- 1 root root 0 Jul 26 20:56 memory.kmem.failcnt
--w------- 1 root root 0 Jul 26 20:56 memory.force_empty
-rw-r--r-- 1 root root 0 Jul 26 20:56 memory.failcnt
-rw-r--r-- 1 root root 0 Jul 26 20:56 cgroup.procs
--w--w--w- 1 root root 0 Jul 26 20:56 cgroup.event_control
-rw-r--r-- 1 root root 0 Jul 26 20:56 cgroup.clone_children
文件很多,选几个重要的讲下:
tasks 可以将想要*资源的进程都加到这个文件中
memory.max_usage_in_bytes内存的最大使用量,用来*资源
-memory.soft_limit_in_bytes 和 memory.limit_in_bytes 的差异是,这个*并不会阻止进程使用超过限额的内存,只是在系统内存不足时,会优先回收超过限额的进程占用的内存,使之向限定值靠拢。
memory.oom_control
包含一个标志(0或1)来开启或者关闭cgroup的OOM killer。如果开启(1),任务如果尝试申请内存超过允许,就会被系统OOM killer终止。OOM killer在每个使用cgroup内存子系统中都是默认开启的。如果需要关闭,则可以向memory.oom_control文件写入1:
# echo 1 > /sys/fs/cgroup/memory.oom_control
如果OOM killer关闭,那么进程尝试申请的内存超过允许,那么它就会被暂停,直到额外的内存被释放
memory.mem.usage_in_bytes 当前进程内存用量,因为现在还没有进程加到组里,就是0了
memory.mem.failcnt显示内存达到*值的次数