Linux-Cgroup V2 初体验
本文主要记录 Linux Cgroup V2 版本基本使用操作,包括 cpu、memory 子系统演示。
1. 开启 Cgroup V2
版本检查
通过下面这条命令来查看当前系统使用的 Cgroups V1 还是 V2
stat -fc %T /sys/fs/cgroup/
如果输出是cgroup2fs
那就是 V2,就像这样
root@tezn:~# stat -fc %T /sys/fs/cgroup/
cgroup2fs
如果输出是tmpfs
那就是 V1,就像这样
[root@docker cgroup]# stat -fc %T /sys/fs/cgroup/
tmpfs
启用 cgroup v2
如果当前系统未启用 Cgroup V2,也可以通过修改内核 cmdline 引导参数在你的 Linux 发行版上手动启用 cgroup v2。
如果你的发行版使用 GRUB,则应在 /etc/default/grub
下的 GRUB_CMDLINE_LINUX
中添加 systemd.unified_cgroup_hierarchy=1
, 然后执行 sudo update-grub
。
具体如下:
1)编辑 grub 配置
vi /etc/default/grub
内容大概是这样的:
GRUB_DEFAULT=0
GRUB_TIMEOUT_STYLE=hidden
GRUB_TIMEOUT=0
GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
GRUB_CMDLINE_LINUX=""
对最后一行GRUB_CMDLINE_LINUX
进行修改
GRUB_CMDLINE_LINUX="quiet splash systemd.unified_cgroup_hierarchy=1"
2)然后执行以下命令更新 GRUB 配置
sudo update-grub
3)最后查看一下启动参数,确认配置修改上了
cat /boot/grub/grub.cfg | grep "systemd.unified_cgroup_hierarchy=1"
4)然后就是重启
reboot
重启后查看,不出意外切换到 cgroups v2 了
root@cgroupv2:~# stat -fc %T /sys/fs/cgroup/
cgroup2fs
发行版推荐
不过,推荐的方法仍是使用一个默认已启用 cgroup v2 的发行版。
有关使用 cgroup v2 的 Linux 发行版的列表,
- Container-Optimized OS(从 M97 开始)
- Ubuntu(从 21.10 开始,推荐 22.04+)
- Debian GNU/Linux(从 Debian 11 Bullseye 开始)
- Fedora(从 31 开始)
- Arch Linux(从 2021 年 4 月开始)
- RHEL 和类似 RHEL 的发行版(从 9 开始)
2. 基本使用
cgroup v2 使用上和 v1 版本基本一致,v2 版本也是默认在/sys/fs/cgroup/
目录。
root@mydocker:~# ls /sys/fs/cgroup/
cgroup.controllers cgroup.subtree_control init.scope system.slice
cgroup.max.depth cgroup.threads io.cost.model user.slice
cgroup.max.descendants cpu.pressure io.cost.qos
cgroup.procs cpuset.cpus.effective io.pressure
cgroup.stat cpuset.mems.effective memory.pressure
- 创建 sub-cgroup: 只需要创建一个子目录
cd /sys/fs/cgroup
mkdir $CGROUP_NAME
- 将进程移动到指定 cgroup:将 PID 写入到相应 cgroup 的 cgroup.procs 文件即可,就像这样:
echo 1001 > /sys/fs/cgroup/test/cgroup.procs
- 删除 cgroup/sub-cgroup: 也是直接删除对应目录即可
- 如果一个cgroup 已经没有任何children或活进程,那直接删除对应的文件夹就删除该cgroup了
- 如果一个cgroup已经没有children,但是还有僵尸进程,也认为这个cgroup是空的,可以直接删除
rmdir /sys/fs/cgroup/test
- 修改 cpu、memory 限制:往对应配置文件写入配置内容即可
- cpu.max 用于配置 cpu 使用限制
- memory.max 则用于配置 内存使用限制
- ...
创建 cgroup
接下来,以 cpu、memory 为例,简单演示一下 cgroup v2 版本使用
root@mydocker:~# cd /sys/fs/cgroup/
root@mydocker:/sys/fs/cgroup# mkdir test
root@mydocker:/sys/fs/cgroup# cd test
root@mydocker:/sys/fs/cgroup/test# ls
cgroup.controllers cpu.uclamp.max memory.current
cgroup.events cpu.uclamp.min memory.events
cgroup.freeze cpu.weight memory.events.local
cgroup.max.depth cpu.weight.nice memory.high
cgroup.max.descendants cpuset.cpus memory.low
cgroup.procs cpuset.cpus.effective memory.max
cgroup.stat cpuset.cpus.partition memory.min
cgroup.subtree_control cpuset.mems memory.oom.group
cgroup.threads cpuset.mems.effective memory.pressure
cgroup.type io.max memory.stat
cpu.max io.pressure pids.current
cpu.pressure io.stat pids.events
cpu.stat io.weight pids.max
CPU
启动一个死循环
root@mydocker:/sys/fs/cgroup/test# while : ; do : ; done &
[1] 90482
不出意外的话,应该占用了 100% cpu
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
90482 root 20 0 10160 1772 0 R 99.3 0.1 0:05.01 bash
接下来使用 cgroup v2 限制该进程只能使用 20% cpu
1)修改配置
echo 2000 10000 > cpu.max
含义是在 10000 微秒的 CPU 时间周期内,有 2000 微秒是分配给本 cgroup 的,也就是本 cgroup 管理的进程在单核 CPU 上的使用率不会超过 20%。
2)将进程加入当前 cgroup
echo 90482 > cgroup.procs
再次查看
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
90482 root 20 0 10160 1772 0 R 20.2 0.1 2:07.78 bash
可以看到,已经被限制到了 20%
Memory
接下来演示内存限制,使用以下代码来模拟内存消耗,
cat <<EOF > ~/mem-allocate.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define MB (1024 * 1024)
int main(int argc, char *argv[])
{
char *p;
int i = 0;
while(1) {
p = (char *)malloc(MB);
memset(p, 0, MB);
printf("%dM memory allocated\n", ++i);
sleep(1);
}
return 0;
}
EOF
编译
gcc ~/mem-allocate.c -o ~/mem-allocate
然后启动该文件
root@mydocker:/sys/fs/cgroup/test# ~/mem-allocate
1M memory allocated
2M memory allocated
3M memory allocated
4M memory allocated
5M memory allocated
6M memory allocated
7M memory allocated
8M memory allocated
9M memory allocated
10M memory allocated
11M memory allocated
12M memory allocated
^C
可以看到,每秒会消耗 1M 内存,若不停止会一直运行直到 OOM。
接下来使用 cgroup v2 限制最多消耗 10M 内存。
1)修改配置
单位为字节 10485760= 10 * 1024 * 1024
echo 10485760 > memory.max
也就是本 cgroup 管理的进程内存使用不会超过 10M
2)将进程加入当前 cgroup
#将当前bash加入到test中,这样这个bash创建的所有进程都会自动加入到test中
sh -c "echo $$ >> cgroup.procs"
再次查看
root@mydocker:/sys/fs/cgroup/test# ~/mem-allocate
1M memory allocated
2M memory allocated
3M memory allocated
4M memory allocated
5M memory allocated
6M memory allocated
7M memory allocated
8M memory allocated
9M memory allocated
Killed
可以看到,到 10M 时就因为达到内存上限而被 Kill 了。
删除 cgroup
演示完成,把 cgroup 删除。
首先把进程 kill 一下
root@mydocker:/sys/fs/cgroup# cat test/cgroup.procs
90444
90630
root@mydocker:/sys/fs/cgroup# kill -9 90630
root@mydocker:/sys/fs/cgroup# kill -9 90444
然后删除目录
root@mydocker:/sys/fs/cgroup# rmdir test
这样 cgroup 就删除了。
3. v1 v2 对比
v1 的 cgroup 为每个控制器都使用独立的树(目录)
[root@docker cgroup]# ls /sys/fs/cgroup/
blkio cpu cpuacct cpuacct,cpu cpu,cpuacct cpuset devices freezer hugetlb memory net_cls net_cls,net_prio net_prio perf_event pids rdma systemd
每个目录就代表了一个 cgroup subsystem,比如要限制 cpu 则需要到 cpu 目录下创建子目录(树),限制 memory 则需要到 memory 目录下去创建子目录(树)。
比如 Docker 就会在 cpu、memory 等等目录下都创建一个名为 docker 的目录,在 docker 目录下在根据 containerID 创建子目录来实现资源限制。
各个 Subsystem 各自为政,看起来比混乱,难以管理
因此最终的结果就是:
- 用户空间最后管理着多个非常类似的 hierarchy,
- 在执行 hierarchy 管理操作时,每个 hierarchy 上都重复着相同的操作。
v2 中对 cgroups 的最大更改是将重点放在简化层次结构上
- v1 为每个控制器使用独立的树(例如
/sys/fs/cgroup/cpu/GROUPNAME
和/sys/fs/cgroup/memory/GROUPNAME
)。 - v2 将统一
/sys/fs/cgroup/GROUPNAME
中的树,如果进程 X 加入/sys/fs/cgroup/test
,则启用 test 的每个控制器都将控制进程 X。
更多 v1 和 v2 差异见 v1
存在的问题及 v2
的设计考虑
【从零开始写 Docker 系列】持续更新中,搜索公众号【探索云原生】订阅,阅读更多文章。
4. 小结
本文主要分享了 Linux cgroup v2 版本的基本使用,以及 v1 和 v2 版本的差异。
更多 cgroup v2 信息推荐阅读:Control Group v2 及其译文 Control Group v2(cgroupv2 权威指南)(KernelDoc, 2021)
Linux-Cgroup V2 初体验的更多相关文章
- Kali Linux 2016.2初体验使用总结
Kali Linux 2016.2初体验使用总结 Kali Linux官方于8月30日发布Kali Linux 2016的第二个版本Kali Linux 2016.2.该版本距离Kali Linux ...
- Linux on window初体验
参照来源: https://www.cnblogs.com/enet01/p/7458767.html 1:liunx on window 的配置不多说(百度网上很多)启动开发这模式,在应用和程序中勾 ...
- Kali Linux 2016.2初体验
前言 Kali Linux官 方于8月30日发布Kali Linux 2016的第二个版本Kali Linux 2016.2.该版本距离Kali Linux 2016.1版本发布,已经有7个月.在这期 ...
- 【Linux】CentOS8 初体验
一.部署CentOS8虚拟机 1.下载Centos8镜像 下载地址: https://www.centos.org/download/ 可以选择国内的下载源,比较快,这里推荐清华的和阿里的 2.下载完 ...
- 在同一个硬盘上安装多个 Linux 发行版及 Fedora 21 、Fedora 22 初体验
在同一个硬盘上安装多个 Linux 发行版 以前对多个 Linux 发行版的折腾主要是在虚拟机上完成.我的桌面电脑性能比较强大,玩玩虚拟机没啥问题,但是笔记本电脑就不行了.要在我的笔记本电脑上折腾多个 ...
- Linux之初体验
预备作业03--我的Linux初体验 学习基于VirtualBox虚拟机安装Ubuntu图文教程在自己笔记本上安装Linux操作系统 一开始以为这个项目很简单,以往也在自己的笔记本上看教程安装过软件, ...
- 第三次随笔--安装虚拟机及学习linux系统初体验
第三次随笔--安装虚拟机及学习linux系统初体验 ·学习基于VirtualBox虚拟机安装Ubuntu图文教程在自己笔记本上安装Linux操作系统 首先按照老师的提示步骤进行VirtualBox虚拟 ...
- 20155226-虚拟机与Linux之初体验
虚拟机与Linux之初体验 虚拟机的安装 虚拟机对我来说不是很了解,但今天在安装过程中加深了我的理解.虚拟机是一个在原来系统基础上进行的又一个系统安装,可以在不影响前者的情况下完成一些其不能解决的问题 ...
- 20155315庄艺霖第三次作业之Linux初体验
Linux初体验 安装Linux三两事 老师的作业要求基于VirtualBox安装Linux系统,我一开始下载了VB但是电脑运行不了,后来看网上的教程下载了VMware,才算开始了我的Linux之旅. ...
- 虚拟机与Linux的初体验
很早的时候就知道虚拟机这个神奇东西的存在,但也仅仅是只闻其名,未见其身.后来在信息安全素质教育的这门课程上,为了做木马实验.暴力破解实验以及邮件窃取实验,这才比较直接的接触到了虚拟机.当我看着在另一个 ...
随机推荐
- uniapp去除button的边框
button { border: none !important; } button::after { border: none !important; }
- Java面试题:如果你这样做,你会后悔的,两次启动同一个线程~~~
当一个线程被启动后,如果再次调start()方法,将会抛出IllegalThreadStateException异常. 这是因为Java线程的生命周期只有一次.调用start()方法会导致系统在新线程 ...
- kubernetes运行应用Controller3之Job、CronJob详解
成功启动一个Job 1.Job.spec.template.metadata,没有空格符的错误 [machangwei@mcwk8s-master ~]$ cat mcwJob1.yml apiVer ...
- python计算机视觉学习笔记——PIL库的用法
如果需要处理的原图及代码,请移步小编的GitHub地址 传送门:请点击我 如果点击有误:https://github.com/LeBron-Jian/ComputerVisionPractice 这个 ...
- MySQL的索引优化
一.索引的使用场景 1.全值匹配 通过主键索引查询 mysql> explain select * from t_goods where id = 1 \G; ***************** ...
- 浅析MySQL 8.0直方图原理
本文分享自华为云社区<[MySQL技术专栏]MySQL8.0直方图介绍>,作者:GaussDB 数据库. 背景 数据库查询优化器负责将SQL查询转换为尽可能高效的执行计划,但因为数据环境不 ...
- Nginx 调试模块 echo-nginx-module
引言 Nginx 作为一个高性能的 HTTP 和反向代理 Web 服务器.如今很多项目都会选择 Nginx 作为反向代理服务器,但是避免不了在使用的过程中,会遇到各种各样的问题.因此 echo-ngi ...
- 将python文件转换成exe可执行文件
一.安装Pyinstaller pip install pyinstaller(Pyinstaller) 二.找到 .py文件的路径并执行如下命令 pyinstaller -F 要转换的文件.py 三 ...
- 【WPF】 BasedOn的用法
BasedOn 用于样式的继承. 这里的已经继承了一个样式 此时,我们想在Resource中让他附加新的样式,但是这样不成功 修改如下: 去掉了之前的样式选择 我们使用BasedOn让其叠加样式
- 安装、学习protobuf
Protobuf是什么? 类似于json的一种数据格式,独立于语言,而且是二进制方式,所以比json更快,而且还可以直接存储一些图.树 序列化和反序列化 持久化(存到磁盘硬盘)领域中,数据存到磁盘叫序 ...