容器基础(三): 使用Cgroups进行资源限制
Linux Cgroups
Linux Cgroups 是 Linux 内核中用来为进程设置资源限制的一个重要功能. Cgroups将进程进行分组, 然后对这一组进程进行统一的资源监控和限制。Cgroups当前有V1和V2版本,为了后续用于实现简单容器sdocker,这里只验证V1版本的cpu和memory子系统。
Linux可以通过如下命令来查看当前系统支持的cgroup子系统:
linux: # cat /proc/cgroups
#subsys_name hierarchy num_cgroups enabled
cpuset
cpu
cpuacct
blkio
memory
devices
freezer
net_cls
perf_event
net_prio
hugetlb
pids
linux: #
有的系统(debian8/suse12), cgroup.memory没有启用, 这时可能会影响到下面几个方面:
. 在/sys/fs/cgroup/memory下建立目录失败, 提示readonly;
. docker info里面也会有提示信息;
. 使用kubeadm安装kubernetes时会提示错误;
解决办法, 在/etc/default/grub文件中增加如下选项(debian使用update_grub, suse使用grub2-mkconfig, 然后reboot):
linux: # cat /etc/default/grub | grep cgroup_enable
GRUB_CMDLINE_LINUX="cgroup_enable=memory"
linux: #
Cgroup.CPU
对于Cgroup.CPU,限制cpu利用率主要通过修改下面两个文件来实现:
/sys/fs/cgroup/cpu/cpu.cfs_quota_us
/sys/fs/cgroup/cpu/cpu.cfs_period_us
把cpu.cfs_quota_us / cpu.cfs_period_us(默认100000)的值作为可以使用的CPU的百分比。使用方法举例如下(摘录自附录网页):
Examples
--------
. Limit a group to CPU worth of runtime. If period is 250ms and quota is also 250ms, the group will get
CPU worth of runtime every 250ms. # echo > cpu.cfs_quota_us /* quota = 250ms */
# echo > cpu.cfs_period_us /* period = 250ms */ . Limit a group to CPUs worth of runtime on a multi-CPU machine. With 500ms period and 1000ms quota, the group can get CPUs worth of
runtime every 500ms. # echo > cpu.cfs_quota_us /* quota = 1000ms */
# echo > cpu.cfs_period_us /* period = 500ms */ The larger period here allows for increased burst capacity. . Limit a group to % of CPU. With 50ms period, 10ms quota will be equivalent to % of CPU. # echo > cpu.cfs_quota_us /* quota = 10ms */
# echo > cpu.cfs_period_us /* period = 50ms */ By using a small period here we are ensuring a consistent latency
response at the expense of burst capacity.
针对Cgroup.CPU进行测试,对于如下的cpu密集型程序, 启动后从top中可以看到cpu占用100%:
linux: # cat cpu.c
int main(void) {
for (; ;); return ;
}
linux: #
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
root R 100.00 0.002 :33.02 cpu
通过给cpu.cfs_quota_us赋值20000,同时把程序pid赋值给tasks文件,让程序只能使用1/5的cpu。
linux: # mkdir /sys/fs/cgroup/cpu/sdocker
linux: # mkdir /sys/fs/cgroup/cpu/sdocker/
linux: # echo > /sys/fs/cgroup/cpu/sdocker//cpu.cfs_quota_us
linux: # echo > /sys/fs/cgroup/cpu/sdocker//tasks
设置后立即生效,top可以看到进程cpu占用率在20%左右波动:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
root R 20.202 0.002 :57.80 cpu
退出程序并清理cgroup资源:
linux: # kill -
linux: # rmdir /sys/fs/cgroup/cpu/sdocker//
Cgroup.Memory
/sys/fs/cgroup/memory下定义了Cgroup.Memory子系统的相关文件, 各文件含义如下:
cgroup.event_control #用于eventfd的接口
memory.usage_in_bytes #显示当前已用的内存字节数
memory.limit_in_bytes #设置/显示当前限制的内存额度, 当usage_in_bytes超限时, 如果memory.swappiness配置可使用swap, kernel会优先把内存数据转移到swap空间, 最后若转移swap失败, 则根据memory.oom_control判断是否触发oom
memory.failcnt #显示内存使用量达到限制值的次数, 当usage_in_bytes超限时, 会触发该值增加
memory.max_usage_in_bytes #历史内存最大使用量
memory.soft_limit_in_bytes #设置/显示当前限制的内存软额度
memory.stat #显示当前cgroup的内存使用情况
memory.use_hierarchy #设置/显示是否将子cgroup的内存使用情况统计到当前cgroup里面
memory.force_empty #触发系统立即尽可能的回收当前cgroup中可以回收的内存
memory.pressure_level #设置内存压力的通知事件,配合cgroup.event_control一起使用
memory.swappiness #设置和显示当前的swappiness
memory.move_charge_at_immigrate #设置当进程移动到其他cgroup中时,它所占用的内存是否也随着移动过去
memory.oom_control #设置/显示oom controls相关的配置, 默认0启用
memory.numa_stat #显示numa相关的内存
针对Cgroup.Memory进行测试,如下的测试代码通过不断分配内存来触发内存限制功能:
linux: # cat memory.cpp
#include <unistd.h> #include <csignal>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <vector>
using std::vector; vector<int *> g_mem_pointer; void sig_handler(int sig) {
printf("\n%d handle\n", sig);
for (auto p : g_mem_pointer) {
free(p);
} exit(-);
} int main(void) {
unsigned total_mem = , chunk_size = * ; signal(SIGTERM, sig_handler);
signal(SIGINT, sig_handler); int *p;
while () {
if (NULL == (p = (int *)malloc(chunk_size))) {
printf("[-] malloc failed!\n");
kill(getpid(), );
} memset(p, 0xff, chunk_size);
g_mem_pointer.push_back(p);
total_mem += chunk_size;
printf("[+] malloc size: %u\n", total_mem);
sleep();
} return ;
}
linux: #
memory.cpp
设置内存限制6m到memory.limit_in_bytes,同时把进程pid设置到tasks文件, 一段时间后可以看到进程oom-kill.
测试发现进程实际打印分配的总内存远远大于设置的内存上限时, memory.usage_in_bytes中的数值才会慢慢趋近于memory.limit_in_bytes,即使设置memory.swappiness为0也如此;
linux:~ # mkdir /sys/fs/cgroup/memory/sdocker
linux:~ # mkdir /sys/fs/cgroup/memory/sdocker/
linux:~ # echo 6m > /sys/fs/cgroup/memory/sdocker//memory.limit_in_bytes
linux:~ # cat /sys/fs/cgroup/memory/sdocker//memory.limit_in_bytes linux:~ # echo > /sys/fs/cgroup/memory/sdocker//tasks
linux:~ # rmdir /sys/fs/cgroup/memory/sdocker/
参考网址:
https://segmentfault.com/u/wuyangchun
https://www.kernel.org/doc/Documentation/cgroup-v1/memory.txt
https://www.kernel.org/doc/Documentation/scheduler/sched-bwc.txt
容器基础(三): 使用Cgroups进行资源限制的更多相关文章
- linux(centos8):使用cgroups做资源限制
一,什么是cgroups? 1,cgroups是资源的控制组,它提供了一套机制用于控制一组特定进程对资源的使用. cgroups绑定一个进程集合到一个或多个限制资源使用的子系统上. 2, cg ...
- docker容器基础
一.docker容器基础6种名称空间:UTS.MOunt.IPC.PID.User.Net (1) Linux Namespaces:namespace 系统调用参数 隔离内容 内核版本 UTS ...
- C++ 顺序容器基础知识总结
0.前言 本文简单地总结了STL的顺序容器的知识点.文中并不涉及具体的实现技巧,对于细节的东西也没有提及.一来不同的标准库有着不同的实现,二来关于具体实现<STL源码剖析>已经展示得全面细 ...
- Bootstrap <基础三十>Well
Well 是一种会引起内容凹陷显示或插图效果的容器 <div>.为了创建 Well,只需要简单地把内容放在带有 class .well 的 <div> 中即可.下面的实例演示了 ...
- day 53-1 Django基础三之视图函数
Django基础三之视图函数 本节目录 一 Django的视图函数view 二 CBV和FBV 三 使用Mixin 四 给视图加装饰器 五 Request对象 六 Response对象 一 Dja ...
- day 67 Django基础三之视图函数
Django基础三之视图函数 本节目录 一 Django的视图函数view 二 CBV和FBV 三 使用Mixin 四 给视图加装饰器 五 Request对象 六 Response对象 一 Dja ...
- Django基础三之路由、视图、模板
Django基础三之路由.视图.模板 目录 Django基础三之路由.视图.模板 1. Django 请求和返回周期 1.1 路由层之路由匹配 1.2 有名分组 1.3 无名分组 2. 反射解析 3. ...
- Python全栈开发【基础三】
Python全栈开发[基础三] 本节内容: 函数(全局与局部变量) 递归 内置函数 函数 一.定义和使用 函数最重要的是减少代码的重用性和增强代码可读性 def 函数名(参数): ... 函数体 . ...
- Bootstrap <基础三十二>模态框(Modal)插件
模态框(Modal)是覆盖在父窗体上的子窗体.通常,目的是显示来自一个单独的源的内容,可以在不离开父窗体的情况下有一些互动.子窗体可提供信息.交互等. 如果您想要单独引用该插件的功能,那么您需要引用 ...
随机推荐
- POJ 2533 Longest Ordered Subsequence(裸LIS)
传送门: http://poj.org/problem?id=2533 Longest Ordered Subsequence Time Limit: 2000MS Memory Limit: 6 ...
- JS JavaScript闭包和作用域
JavaScript高级程序设计中对闭包的定义:闭包是指有权访问另外一个函数作用域中变量的函数. 从概念上,闭包有两个特点: 1.函数 2.能访问另外一个函数的作用域中的变量 在ES6之前,JavaS ...
- 与JSON相关的问题
1.JSON.stringify 与 JSON.parse 相关的问题 JSON.stringify 把字符串转化为字符串,JSON.parse把字符串转化为JSON格式 会出现的问题Unexpect ...
- Java 依赖、关联、聚合和组合
必须转一个,写的太好了! https://blog.csdn.net/zhengzhb/article/details/7190158
- update、commit、trancate,delete
update 用于更新表的数据,使用方式为: update table_name set column_name=值 条件 顺便一提:date数据插入更新应该使用 to_date()格式转换函数例如: ...
- 初学oracle遇到些小麻烦
前段时间学习了Oracle数据库,在超级用户sys下运行一些基本语句的时候都没有发现有什么问题,但是却发现不能执行删除字段的的命令,老师检查说可能是权限不够,但是在授权之后依旧不能完成该语句,所以就另 ...
- jquery mobile 移动web(2)
button 按钮 data-role="button" 将超链接变成button. 具有icon 图标的button 组件. 提供了18常用的图标 data-icon =&quo ...
- VUE插件整理
转自:https://blog.csdn.net/miaozhenzhong/article/details/80138174 1.VsCode官方插件地址: https://marketplace. ...
- js日期相减得到分钟数
const date1 = new Date(fieldsValue.examStartTime); const date2 = new Date(fieldsValue.examEndTime); ...
- JS定时器和单线程异步特性
首先要说的是,定时器相关的方法都是属于BOM方法,而定时器呢,它是用于在设定的时间执行一段代码,或者在给定的时间间隔内重复该代码.具体函数: setTimeout(callback, delay);/ ...