容器基础(三): 使用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)是覆盖在父窗体上的子窗体.通常,目的是显示来自一个单独的源的内容,可以在不离开父窗体的情况下有一些互动.子窗体可提供信息.交互等. 如果您想要单独引用该插件的功能,那么您需要引用 ...
随机推荐
- bootstrapTable 问题
bootstrapTable引用问题 $("#table").bootstrapTable({ // 对应table标签的id method: 'post', url: 'abc' ...
- xcode运行时候 You don’t have permission.
xcode 不能运行,提示没有权限 是因为使用第三方框架有plist文件存在
- 工具类(过滤接口空值, value 或 空字符串) - iOS
为了便于日常开发效率,因此创建了一些小的工具类便于使用.具体 code 如下:声明: #import <Foundation/Foundation.h> #import <UIKit ...
- BZOJ3277: 串(广义后缀自动机)
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1196 Solved: 478[Submit][Status][Discuss] Descripti ...
- GIt+jenkins代码自动上线
代码自动上线功能 企业部署代码上线是件比较麻烦的事情,还好我们有jenkins这个持续集成的软件可以帮助我们做很多的事情,现在我们就 来测试用jenkins推送代码上线. 我们这里测试的是一个html ...
- 搭建ssm框架经验
要想搭建好ssm框架的开发环境.首先我们需要知道ssm是什么?ssm就是spring,springmvc,mybatis. 然后我们要知道,他们分别都是怎样实现的和做什么用的,充当什么角色?这样我们就 ...
- Layabox进阶之资源加载
资源加载失败,图片资源默认类型是image 如果是sprite可能找不到. 资源的加载顺序,场景被加载出来时,要判断该场景的资源是否都已经加载到. 点击A界面弹出来B界面,A界面的资源要在B界面之前加 ...
- scala映射和元组
scala映射,是一对键值对,相当于java中的Map 对偶:由两个值构成的组,形式 : 值1->值2,值1和值2类型不一定要相同,可以理解为对偶就是一个key/value 映射就是对偶的集合 ...
- JavaSE基础复习---Class类与反射机制
---恢复内容开始--- 目录: 1.java.lang.class类 2.Java中的反射机制 3.运行时与编译时概念 1. java.lang.class类 Java程序在运行时,Java运行时系 ...
- git 本地分支与远程分支 新建/删除/合并
github上已经有master分支 和dev分支 在本地 git checkout -b dev 新建并切换到本地dev分支 git pull origin dev 本地分支与远程分支相关联 在本地 ...