容器基础(三): 使用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)是覆盖在父窗体上的子窗体.通常,目的是显示来自一个单独的源的内容,可以在不离开父窗体的情况下有一些互动.子窗体可提供信息.交互等. 如果您想要单独引用该插件的功能,那么您需要引用 ...
随机推荐
- 大白话解释IP多播
多播引入 比方说我是一个班主任,管着三个班,每个班30个人,每个班有自己的班长.领导让我宣传19大视 频报告,我这里有源文件.对于普通的单播我需要复制90个副本,给各个班长每人30份,然后班 长在自己 ...
- vue入门: 实现选中并显示修改功能
1.实现功能 2.工具 vue 3.代码 <!DOCTYPE html> <html lang="en"> <head> <meta ch ...
- poj_1306_Combinations
Computing the exact number of ways that N things can be taken M at a time can be a great challenge w ...
- html样式不兼容 详解(转)
网站对火狐不兼容的原因以及解决的方法 1.DOCTYPE 影响 CSS 处理 2.FF: div 设置 margin-left, margin-right 为 auto 时已经居中, IE 不行 3. ...
- jQuery(三)HTML
获得内容: text() - 设置或返回所选元素的文本内容 html() - 设置或返回所选元素的内容(包括 HTML 标记) val() - 设置或返回表单字段的值 <html> < ...
- I/O流、文件操作
1)操作文件 Path和Files是在JavaSE7中新添加进来的类,它们封装了在用户机器上处理文件系统所需的所有功能.Path表示的一个目录名序列,其后还可以跟着一个文件名.路径中的第一个参数可以是 ...
- python七类之列表元组
列表 一.关键字: list lst = [ , , , , , , ,] lst = [1,2,3,4] 二.方法: 1.增加: . append( ) #追加,添加元素进列表最后 ls ...
- linux进程篇 (一) 进程的基本概念
进程是系统资源分配的最小单位. 1.创建和执行 父进程通过 fork 系统调用创建子进程, 子进程被创建后,处于创建状态. linux为子进程配置数据结构,如果内存空间足够,子进程就在内核中就绪,成为 ...
- Python自动化运维——系统性能信息模块
Infi-chu: http://www.cnblogs.com/Infi-chu/ 模块:psutil psutil是一个跨平台库,可以很轻松的为我们实现获取系统运行的进程和资源利用率等信息. 功能 ...
- R语言绘图:ggplot2绘制ROC
使用ggplot2包绘制ROC曲线 rocplot<- function(pred, truth, ...){ predob<- prediction(pred, truth) #打印AU ...