centos cgroup,CentOS 7
配置cgroup时启动挂在有问题,求解答
cgroup配置
1、Cgroup安装
安装Cgroups需要libcap-devel和libcgroup两个相关的包
yum install gcc libcap-devel
2、Cgroup挂载配置
Cgroup对应服务名称为cgconfig,cgconfig默认采用“多挂载点”挂载。经过实际测试,发现在CentOS环境中应采用“单挂载点”进行挂载,因此应当卸载原有cgroup文件系统,并禁用cgconfig。
cgclear或者sudo service cgconfig stop#停止cgconfig,卸载cgroup目录
sudo chkconfig cgconfig off#禁用cgconfig服务,避免其开机启动
然后采用“单挂载点”方式重新挂载cgroup。
可以直接手动挂载,这样仅当次挂载成功。
mount-t cgroup none/cgroup
然后编辑/etc/fstab/,输入下列内容。这样每次开机后都会自动挂载。
none/cgroup cgroup defaults 0 0
3、常用的Cgroup相关命令和配置文件
service cgconfig status|start|stop|restart#查看已存在子系统
lssubsys–am#查看已存在子系统
cgclear#清除所有挂载点内部文件,相当于service cgconfig stop
cgconfigparser-l/etc/cgconfig.conf#重新挂载
Cgroup默认挂载点(CentOS):/cgroup
cgconfig配置文件:/etc/cgconfig.conf
Cgroup使用介绍
Cgroup,全称为Control Group,是Linux内核提供的资源管理和限制机制,用于对进程进行分组并对其资源进行限制和优先级调整。本文将从七个方面介绍Cgroup的基础知识:简介、安装与挂载、基本操作、日常内存CPU限制用法、其他使用、Cgroup嵌套使用以及注意事项。
一、简介
Cgroup的主要目标是提供一种统一的接口来管理系统资源,包括CPU、内存、磁盘I/O等。其核心组件包括:
- cpu:用于限制cgroup的CPU使用率。
- cpuacct:用于统计cgroup的CPU使用率。
- cpuset:用于绑定cgroup到指定的CPU和NUMAQ节点。
- freezer:用于挂起和恢复cgroup中的所有进程。
- memory:用于统计和限制cgroup的内存使用率。
二、安装与挂载
在Debian/Ubuntu系统上,可以使用以下命令安装Cgroup工具包:
sudo apt-get install cgroup-tools
在RHEL/CentOS系统上,可以使用以下命令安装:
sudo yum install libcgroup-tools
接下来,创建一个挂载点并挂载Cgroup文件系统:
sudo mkdir/sys/fs/cgroup
sudo mount-t cgroup-o none,name=cgroup/sys/fs/cgroup
三、基本操作
1.挂载与创建CGROUP树
创建一颗cgroup树关联所有subsystem,并挂载在/sys/fs/cgroup下(xxx为cgroup树名称):
sudo mount-t cgroup xxx/sys/fs/cgroup
也可以不关联任何subsystem,挂载在其他目录,例如创建名为demo树挂载在~/test_aa/demo目录:
sudo mount-t cgroup-o none,name=demo demo./demo/
查看当前cgroup中的所有进程ID和线程ID:
cgroup.procs
tasks
2.建立子Cgroup
通过在目录中创建文件夹的方式,建立子cgroup。
3.添加进程进入Cgroup
将进程添加到子cgroup中。
4.检查Cgroup状态
使用命令检查cgroup的状态。
5.创建控制组
使用cgcreate命令创建一个新的控制组:
sudo cgcreate-g cpu,memory:my_group
这将在/sys/fs/cgroup目录下创建一个名为my_group的控制组,并关联CPU和内存子系统。
6.添加进程到控制组
使用cgclassify命令将进程添加到控制组中:
sudo cgclassify-g cpu,memory:my_group PID
其中,PID是要添加的进程ID。
7.从控制组中移动进程
使用cgclassify命令将进程从一个控制组移动到另一个控制组:
sudo cgclassify-g cpu,memory:another_group PID
8.删除控制组
使用cgdelete命令删除一个控制组:
sudo cgdelete cpu,memory:my_group
四、日常内存CPU限制用法
1.限制CPU使用率
创建一个控制组,并设置CPU使用率限制:
sudo cgcreate-g cpu:cpu_limit
echo 10000>/sys/fs/cgroup/cpu/cpu_limit/cpu.cfs_quota_us
echo 200000>/sys/fs/cgroup/cpu/cpu_limit/cpu.cfs_period_us
将进程添加到控制组中:
sudo cgclassify-g cpu:cpu_limit PID
限制前后,CPU占用率对比:
未限制前:CPU占用率波动在20~45%之间
限制后:CPU占用率波动在10~23%之间,滑动/点击操作时应用出现卡顿
2.限制内存使用量
创建一个控制组,并设置内存使用量限制为300MB:
sudo cgcreate-g memory:mem_limit
echo$((300 1024 1024))>/sys/fs/cgroup/memory/mem_limit/memory.limit_in_bytes
将进程添加到控制组中:
sudo cgclassify-g memory:mem_limit PID
五、其他使用
1.限制磁盘I/O速率
创建一个控制组,并设置磁盘I/O限制为10MB/s:
sudo cgcreate-g blkio:io_limit
echo"8:0$(10 1024 1024)">/sys/fs/cgroup/blkio/io_limit/blkio.throttle.read_bps_device
将进程添加到控制组中:
sudo cgclassify-g blkio:io_limit PID
2.限制网络带宽
创建一个控制组,并设置网络带宽限制为1Mbps:
sudo cgcreate-g net_cls:net_limit
echo 0x10000>/sys/fs/cgroup/net_cls/net_limit/net_cls.classid
使用tc命令配置网络限制:
sudo tc qdisc add dev eth0 root handle 1: htb
sudo tc class add dev eth0 parent 1: classid 1:1 htb rate 1mbit
sudo tc filter add dev eth0 parent 1: protocol ip prio 1 handle 1: cgroup
将进程添加到控制组中:
sudo cgclassify-g net_cls:net_limit PID
六、Cgroup的嵌套使用
Cgroup支持嵌套使用,即在一个控制组内创建子控制组。例如:
-创建名为parent_group的控制组:
sudo cgcreate-g cpu,memory:parent_group
-在其中创建两个子控制组:
sudo cgcreate-g cpu,memory:parent_group/child_group1
sudo cgcreate-g cpu,memory:parent_group/child_group2
可以为每个子控制组分别设置资源限制和优先级。
七、额外需要注意的内容
欢迎点赞分享,搜索关注【鹅厂架构师】公众号,一起探索更多业界领先产品技术。
cgroup 内存泄露问题排查记录
出现内存泄漏的主机为集群机器,运行时间约5天,内存使用超90%,其上运行集群管理软件和 docker并执行测试脚本反复启停容器。
长时间运行后,集群主机内存占用逐渐增加,出现应用 OOM现象。
而实际查看时发现主机内存总占用高,但应用实际占用内存低或未见显著异常。
可以看到内存占用 83.6%,而实际top显示的内存占用最高也才 0.6%没有占用内存过高的应用。
内存占用除了用户应用占用还有内核占用,遂查看内核内存占用。
使用linux文件系统接口查看
可以看到占用超高的项目为 slab内核占用:
继续查看内核详细占用,按照缓存大小进行排序
可以看到此处:
kmalloc-2048,kmalloc-4096,kernfs_node_cache,kmalloc-1024,kmalloc-192,kmalloc-512均占用较高,对比了正常主机,已经严重超过正常值。
如果是内核缓存过高则可以尝试进行内核缓存释放:
但执行上述操作后,内存占用依旧无显著下降,也符合上面看到的 SUnreclaim: 2447108 kB//slab不可回收内存大小。这部分内存不能被释放。
kmalloc为内核进行分配的内存,参考价值较大的为 kernfs_node_cache占用高,遂搜索该项是作何作用。
很明显,该现象为内核占用严重超标,于是在搜索时加入了 memory leak关键字,很快发现了该 Issues docker-run--memory slab cache leak on centos7
该 issue表示 centos7在反复运行 docker run--rm--memory 1g hello-world时存在明显的内核内存占用升高,且无法被释放。且现象和当前现象一致。
最终指向内kernel c group内存泄露问题 slab leak causing a crash when using kmem control group
大致原因是在 3.10内核上如果使用了 kmem limit参数,会导致cgroup回收时无法释放部分已分配内存。至于更深入的了解,还需要其他时间,先解决目前的问题。
原因大概确定,为了再次确定这个问题,如果能够通过上述手段复则可以确定是该问题。
在一台仅运行docker的机器上执行上述语句,查看 slab内存占用,可以看见内存占用明显上升。且最终表现和已有环境上的问题一致,总内存占用高,用户态内存占用低,内核内存占用高且无法被释放。
既然是内核问题,且知道了明确复现路径,则可以通过两种方式进行解决:
最终,进过测试后,选择了更换内核版本,将使用 Ubuntu 18.04作为新的操作系统。
Linux内核使用层次化内存管理的方法,每一层解决不同的问题,从下至上的关键部分如下:
slab是Linux操作系统的一种内存分配机制。其工作是针对一些经常分配并释放的对象,如进程描述符等,这些对象的大小一般比较小,如果直接采用伙伴系统来进行分配和释放,不仅会造成大量的内碎片,而且处理速度也太慢。而slab分配器是基于对象进行管理的,相同类型的对象归为一类(如进程描述符就是一类),每当要申请这样一个对象,slab分配器就从一个slab列表中分配一个这样大小的单元出去,而当要释放时,将其重新保存在该列表中,而不是直接返回给伙伴系统,从而避免这些内碎片。slab分配器并不丢弃已分配的对象,而是释放并把它们保存在内存中。当以后又要请求新的对象时,就可以从内存直接获取而不用重复初始化。
Slab导致的占用内存过高,Slab可以对可回收缓存手动释放,操作如下:
其中drop_caches的4个值有如下含义: