5.Linux CGroups 资源控制实战(CPU+内存)超详细教程

Linux CGroups 资源控制实战(CPU+内存)超详细教程

🔥 前言:在Linux容器化技术(如Docker、K8s)中,CGroups(Control Groups)是实现资源隔离与控制的核心内核特性,它能精准限制进程对CPU、内存、IO等系统资源的使用,避免单个进程过度占用资源导致系统崩溃。本文将基于实战视角,从基础工具安装、CGroups信息查看,到CPU、内存的精准控制,一步步拆解操作流程,每一步均附带完整命令、注释及效果说明,新手也能轻松上手,全程可直接复制执行!

📌 适用场景:Linux运维、容器学习入门、资源管控实战、面试相关实操准备

💻 环境说明:Ubuntu 20.04 LTS / CentOS 7/8(两种系统命令均提供,适配不同环境)

一、实战准备:核心工具安装

本次实战需用到两个核心工具:pidstat(资源监控工具,用于查看进程CPU、内存占用)和stress(压力测试工具,用于模拟高CPU、高内存负载),先完成工具安装,避免后续实操报错。

1. pidstat 工具(资源监控)

工具概述

pidstat 是 sysstat 工具集的一员,核心作用是监控全部或指定进程的CPU、内存、线程、设备IO等系统资源占用情况。其特点是:第一次采样显示自系统启动开始的统计信息,后续采样显示自上次运行命令后的统计信息,可通过指定采样间隔和次数,精准获取所需监控数据。

语法格式

shell 复制代码
pidstat [ 选项 ] [ <时间间隔> ] [ <次数> ]

常用参数(实战高频)

  • -u:默认参数,显示各进程的CPU使用统计(重点,CPU控制实战必用);

  • -r:显示各进程的内存使用统计(重点,内存控制实战必用);

  • -d:显示各进程的IO使用情况(本次实战暂不用);

  • -p:指定进程号,ALL 表示监控所有进程;

  • -C:指定命令,仅监控与该命令相关的进程(实战高频,精准过滤);

  • -l:显示命令名和所有参数(辅助排查,避免混淆进程)。

安装命令(Ubuntu + CentOS)

shell 复制代码
# ================== Ubuntu 系统 ==================
# 卸载旧版本(若有)
apt remove sysstat -y
# 安装新版本
apt install sysstat -y

# ================== CentOS 系统 ==================
# 卸载旧版本(若有)
yum remove sysstat -y
# 安装新版本
yum install sysstat -y

2. stress 工具(压力测试)

工具概述

stress 是Linux常用的压力测试工具,核心作用是模拟进程对CPU、内存、IO、磁盘的高负载场景,用于验证CGroups资源控制策略是否生效。本次实战将用它模拟高CPU占用、高内存占用的进程,配合pidstat监控控制效果。

语法格式

shell 复制代码
stress [OPTION [ARG]]

常用参数(实战高频)

  • -c, --cpu N:产生N个进程,每个进程循环调用sqrt函数,模拟CPU高负载(CPU控制实战必用);

  • -i, --io N:产生N个进程,循环调用sync函数(将内存缓冲区内容写入磁盘),模拟IO压力(本次暂不用);

  • -m, --vm N:产生N个进程,每个进程循环调用malloc/free函数,模拟内存分配与释放(内存控制实战必用);

  • --vm-bytes B:指定每个内存压力进程分配的内存大小(如50M、100M,内存控制实战必用);

  • --vm-keep:一直占用内存,区别于默认的"不断释放并重新分配内存"(可选,增强内存压力);

  • -d, --hdd N:产生N个进程,循环执行write/unlink函数(创建文件→写入内容→删除文件),模拟磁盘压力(本次暂不用);

  • -t, --timeout N:指定压力测试持续时间(单位:秒),到期后自动结束程序(可选,避免进程长期占用资源);

  • -q, --quiet:压力测试过程中不输出多余信息(可选,简化终端输出)。

注意:使用-i(IO压力)时,若SSD磁盘环境或内存缓冲区数据较少,可能无法产生明显IO压力,反而会导致系统CPU的sys使用率升高,属于正常现象。

安装命令(Ubuntu + CentOS)

shell 复制代码
# ================== Ubuntu 系统 ==================
# 卸载旧版本(若有)
apt remove stress -y
# 安装新版本
apt install stress -y

# ================== CentOS 系统 ==================
# 卸载旧版本(若有)
yum remove stress -y
# 安装新版本
yum install stress -y

工具验证

安装完成后,执行以下命令,确认工具可正常使用(无报错即生效):

shell 复制代码
# 验证pidstat(查看版本/帮助,无需复杂操作)
pidstat --help
# 验证stress(查看版本/帮助)
stress --help

二、基础认知:CGroups 核心概念

在开始实操前,先快速了解CGroups的核心基础,避免只懂操作、不懂原理:

  • CGroups 全称 Control Groups,是Linux内核提供的一种资源隔离机制,用于限制、记录、隔离进程组(process groups)所使用的系统资源(CPU、内存、IO、磁盘等);

  • CGroups 支持两种版本:v1 和 v2,目前主流Linux系统(Ubuntu 20.04+、CentOS 8+)均支持v2版本,本文实操兼容两种版本;

  • CGroups 核心组成:子系统(subsystem)控制组(control group)。子系统对应具体的资源类型(如cpu子系统控制CPU,memory子系统控制内存),控制组是进程组的集合,用于应用具体的资源控制策略;

  • CGroups 默认挂载路径:/sys/fs/cgroup,所有子系统的配置文件、控制组目录均在此路径下,实操核心就是操作该路径下的文件。

三、实操一:CGroups 信息查看(必做,了解系统环境)

在进行资源控制前,先查看系统的CGroups版本、子系统、挂载信息,确认系统支持情况,为后续实操铺垫。全程使用root用户执行(切换root:su -,输入root密码即可)。

1. 查看CGroups版本

通过查看系统文件系统,判断是否支持CGroups v2版本(核心看是否有cgroup2):

shell 复制代码
root@localhost:~# cat /proc/filesystems | grep cgroup

执行效果说明

正常输出如下(不同系统略有差异,核心看cgroup2):

shell 复制代码
nodev
nodev cgroup
nodev cgroup2
nodev

若输出中包含cgroup2,表示系统支持CGroups v2;若仅包含cgroup,表示仅支持v1,两种版本实操流程一致,无需额外调整。

2. 查看CGroups子系统

子系统对应具体的可控制资源,查看系统支持的所有CGroups子系统,重点关注cpu(CPU控制)和memory(内存控制):

shell 复制代码
root@localhost:~# cat /proc/cgroups

执行效果说明

输出为表格形式,各列含义如下:

  • subsys_name:子系统名称(核心关注cpu、memory);

  • hierarchy:子系统对应的层级ID;

  • num_cgroups:该子系统下的控制组数量;

  • enabled:是否启用(1=启用,0=未启用)。

正常输出示例(重点关注cpu和memory的enabled为1,即已启用):

shell 复制代码
#subsys_name hierarchy num_cgroups enabled
cpuset 8 2 1
cpu 2 100 1
cpuacct 2 100 1
blkio 6 98 1
memory 10 124 1
devices 12 98 1
freezer 7 2 1
net_cls 4 2 1
perf_event 3 2 1
net_prio 4 2 1
hugetlb 9 2 1
pids 5 107 1
rdma 11 2 1

3. 查看CGroups挂载信息

查看CGroups在系统中的挂载路径、挂载类型,确认默认挂载位置(核心是/sys/fs/cgroup):

shell 复制代码
root@localhost:~# mount | grep cgroup

执行效果说明

正常输出会包含多个挂载记录,核心信息如下:

  • 默认挂载路径:/sys/fs/cgroup,挂载类型为tmpfs;

  • cgroup2 挂载路径:/sys/fs/cgroup/unified(v2版本特有);

  • 各子系统挂载路径:如cpu子系统挂载到/sys/fs/cgroup/cpu,cpuacct,memory子系统挂载到/sys/fs/cgroup/memory(后续实操的核心路径)。

输出示例(简化版):

shell 复制代码
tmpfs on /sys/fs/cgroup type tmpfs (ro,nosuid,nodev,noexec,mode=755)
cgroup2 on /sys/fs/cgroup/unified type cgroup2 (rw,nosuid,nodev,noexec,relatime,nsdelegate)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpu,cpuacct)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)

4. 查看单个进程的CGroups限制

以当前shell进程为例,查看该进程所属的所有CGroups控制组,了解进程默认的资源限制情况:

shell 复制代码
# 查看当前shell进程的CGroups信息($$ 表示当前shell进程的PID)
root@localhost:~# cat /proc/$$/cgroup

执行效果说明

输出每一行对应一个子系统,格式为「子系统ID:子系统名称:控制组路径」,示例如下:

shell 复制代码
11:hugetlb:/
10:memory:/user.slice
9:freezer:/
8:cpuset:/
7:perf_event:/
6:net_prio,net_cls:/
5:devices:/user.slice/user-0.slice
4:pids:/user.slice
3:cpuacct,cpu:/user.slice
2:blkio:/user.slice
1:name=systemd:/user.slice/user-0.slice/session-354304.scope

重点关注:cpu子系统对应的控制组路径为/user.slice,memory子系统对应的控制组路径也为/user.slice,表示当前shell进程默认受/user.slice控制组的资源限制。

可进一步查看该控制组的详细限制配置(以cpu为例):

shell 复制代码
root@localhost:~# ll /sys/fs/cgroup/cpu/user.slice/

输出会包含该控制组的所有CPU配置文件(如cpu.cfs_period_us、cpu.cfs_quota_us),后续实操会详细讲解这些文件的作用。

四、实操二:使用CGroups 对内存进行控制(核心实操)

本次实操目标:创建一个内存控制组,限制该组内的进程最大只能使用20M内存,通过stress模拟高内存进程,验证控制策略是否生效(进程超过内存限制后会被系统终止)。

📌 实操逻辑:创建内存控制组 → 配置内存限制策略 → 启动高内存压力进程 → 将进程加入控制组 → 监控进程状态(验证控制效果)。

步骤1:创建内存控制组

CGroups的控制组本质是/sys/fs/cgroup/对应子系统下的目录,创建目录即可自动生成该控制组的所有配置文件(系统自动创建,无需手动新建)。

shell 复制代码
# 1. 进入内存子系统的挂载目录(核心路径)
cd /sys/fs/cgroup/memory

# 2. 创建内存控制组目录(控制组名称:test_memory,可自定义)
mkdir test_memory

# 3. 查看控制组目录下的配置文件(系统自动生成)
ll test_memory/

执行效果说明

  1. 执行mkdir test_memory后,无报错即表示控制组创建成功;

  2. 执行ll test_memory/后,会看到大量配置文件,这些文件对应内存控制的各项策略,核心配置文件如下:

  • memory.limit_in_bytes:内存最大使用限制(核心配置文件,本次实操重点);

  • memory.usage_in_bytes:当前控制组内进程的内存实际使用量(只读,用于查看);

  • memory.max_usage_in_bytes:当前控制组内进程的内存最大使用峰值(只读);

  • tasks:该控制组内的进程ID列表(将进程PID写入该文件,即可让进程受该控制组限制);

  • cgroup.procs:该控制组内的进程组ID列表(本次暂不用)。

配置文件输出示例(简化版):

shell 复制代码
total 0
-rw-r--r-- 1 root root 0 Mar 12 14:14 cgroup.clone_children
--w--w--w- 1 root root 0 Mar 12 14:14 cgroup.event_control
-rw-r--r-- 1 root root 0 Mar 12 14:14 cgroup.procs
-rw-r--r-- 1 root root 0 Mar 12 14:14 memory.failcnt
--w------- 1 root root 0 Mar 12 14:14 memory.force_empty
-rw-r--r-- 1 root root 0 Mar 12 14:14 memory.limit_in_bytes
-rw-r--r-- 1 root root 0 Mar 12 14:14 memory.max_usage_in_bytes
-r--r--r-- 1 root root 0 Mar 12 14:14 memory.usage_in_bytes
-rw-r--r-- 1 root root 0 Mar 12 14:14 tasks

步骤2:配置内存限制策略

本次目标是限制进程最大使用20M内存,需将内存大小(单位:字节)写入memory.limit_in_bytes文件中。

计算逻辑:20M = 20 × 1024 × 1024 = 20971520 字节(可通过命令自动计算,避免手动算错)。

shell 复制代码
# 1. 计算20M对应的字节数(可选,手动输入20971520也可)
expr 20 \* 1024 \* 1024

# 2. 查看当前内存限制(默认无限制,值为9223372036854771712)
cat test_memory/memory.limit_in_bytes

# 3. 配置内存限制为20M(写入字节数)
echo "20971520" > test_memory/memory.limit_in_bytes

# 4. 验证配置是否生效(查看配置文件,确认值为20971520)
cat test_memory/memory.limit_in_bytes

执行效果说明

  1. 执行expr 20 \* 1024 \* 1024后,输出20971520,确认计算正确;

  2. 配置前,memory.limit_in_bytes的值为9223372036854771712(表示无内存限制);

  3. 配置后,再次查看该文件,输出20971520,表示内存限制策略配置生效(最大只能使用20M内存)。

步骤3:启动高内存压力进程

使用stress工具启动一个内存压力进程,模拟进程占用50M内存(超过我们配置的20M限制),用于验证控制效果。

shell 复制代码
# 启动1个内存压力进程,每个进程占用50M内存(--vm-bytes 50M)
stress -m 1 --vm-bytes 50M

执行效果说明

命令执行后,终端会输出如下信息,表示压力进程启动成功(进程正在占用50M内存):

shell 复制代码
stress: info: [62106] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd

⚠️ 注意:此时不要关闭该终端窗口(该窗口为窗口A,用于运行压力进程),打开一个新的终端窗口(窗口B),用于后续监控。

步骤4:查看压力进程的PID

在窗口B(新终端)中,使用pidstat命令查看stress压力进程的PID(后续需将该PID加入控制组):

shell 复制代码
# 监控所有stress相关进程的内存使用情况,采样间隔1秒,持续采样(直到手动终止)
pidstat -r -C stress -p ALL 1

执行效果说明

输出会持续刷新,重点关注PID列(进程ID)和RSS列(实际占用内存),示例如下:

shell 复制代码
Linux 5.4.0-100-generic (139-159-150-152)  03/12/2023  _x86_64_ (1 CPU)

02:47:02 PM  UID       PID  minflt/s  majflt/s     VSZ    RSS %MEM Command
02:47:02 PM    0     62517      0.00      0.00    3856     988  0.05 stress
02:47:02 PM    0     62518  476597.03      0.00   55060   15156  0.75 stress

重点记录:内存占用较高的进程PID(本例中为62518),该进程就是我们启动的高内存压力进程,后续将其加入控制组。

步骤5:将压力进程加入内存控制组

打开一个新的终端窗口(窗口C),将步骤4记录的PID写入控制组的tasks文件,让该进程受内存限制策略管控:

shell 复制代码
# 1. 进入内存控制组目录(确保路径正确)
cd /sys/fs/cgroup/memory

# 2. 将压力进程PID(62518)写入tasks文件(替换为自己的PID)
echo 62518 >> test_memory/tasks

# 3. 验证进程是否已加入控制组(查看tasks文件,确认PID存在)
cat test_memory/tasks

执行效果说明

  1. 执行echo 62518 >> test_memory/tasks后,无报错即表示进程已成功加入控制组;

  2. 执行cat test_memory/tasks后,输出62518,确认进程已在控制组内。

步骤6:验证内存控制效果(核心验证)

此时,压力进程的内存占用超过了控制组配置的20M限制,系统会自动终止该进程,我们通过三个窗口观察效果:

  1. 窗口A(压力进程窗口):会输出报错信息,表示进程被终止(无法申请到足够内存),示例如下:
    stress: FAIL: [62517] (415) <-- worker 62518 got signal 9 stress: WARN: [62517] (417) now reaping child worker processes stress: FAIL: [62517] (451) failed run completed in 176s说明:signal 9 表示进程被系统强制终止,原因是内存占用超过限制。

  2. 窗口B(pidstat监控窗口):会发现PID为62518的进程消失,不再输出该进程的内存占用信息,说明进程已被终止;

  3. 窗口C(控制组窗口):查看控制组的内存使用情况,确认进程终止后内存释放:
    # 查看控制组内进程的内存实际使用量(已释放,值会大幅降低) cat test_memory/memory.usage_in_bytes

步骤7:清理环境(可选,避免占用资源)

实操完成后,可删除创建的内存控制组,清理残留资源:

shell 复制代码
# 进入内存子系统目录
cd /sys/fs/cgroup/memory

# 删除内存控制组目录(需确保控制组内无进程,否则无法删除)
rm -rf test_memory

内存控制实战总结(重点记)

  • 核心路径:/sys/fs/cgroup/memory(内存子系统挂载目录);

  • 核心配置文件:memory.limit_in_bytes(内存最大限制,单位:字节);

  • 核心操作:创建控制组目录 → 配置内存限制 → 将进程PID写入tasks文件;

  • 控制效果:进程内存占用超过限制后,会被系统强制终止(signal 9);

  • 避坑点:配置内存限制时,单位必须是字节,避免手动计算错误(可通过expr命令自动计算)。

五、实操三:使用CGroups 对CPU进行控制(核心实操)

本次实操目标:创建一个CPU控制组,限制该组内的进程CPU使用率最大为30%,通过stress模拟CPU满负载进程,验证控制策略是否生效(进程CPU使用率从100%降至30%)。

📌 实操逻辑:创建CPU控制组 → 配置CPU限制策略 → 启动CPU满负载进程 → 将进程加入控制组 → 监控进程CPU使用率(验证控制效果)。

CPU控制核心原理:CGroups通过cpu.cfs_period_uscpu.cfs_quota_us两个配置文件控制CPU使用率,计算公式为:CPU使用率 = cfs_quota_us / cfs_period_us × 100%

先理解两个核心配置文件

CPU控制的核心是两个配置文件(位于CPU控制组目录下),必须先理解其含义,否则无法正确配置:

  1. cpu.cfs_period_us:CPU带宽周期,单位为微秒(μs),默认值为100000(即100毫秒),表示系统每100毫秒为该控制组分配一次CPU带宽;

  2. cpu.cfs_quota_us:该控制组可使用的CPU带宽,单位为微秒(μs),默认值为-1(表示无限制)。取值范围:最小值1000(1毫秒),最大值100000(100毫秒)。

示例计算:本次目标是限制CPU使用率为30%,则:

cfs_quota_us = 30% × cfs_period_us = 0.3 × 100000 = 30000(微秒),因此将cfs_quota_us配置为30000即可。

步骤1:创建CPU控制组

与内存控制组类似,CPU控制组也是/sys/fs/cgroup/cpu目录下的一个子目录,创建目录即可自动生成所有配置文件。

shell 复制代码
# 1. 进入CPU子系统的挂载目录(核心路径)
cd /sys/fs/cgroup/cpu

# 2. 创建CPU控制组目录(控制组名称:test_cpu,可自定义)
mkdir test_cpu

# 3. 查看控制组目录下的配置文件(系统自动生成)
ll test_cpu/

执行效果说明

  1. 执行mkdir test_cpu后,无报错即表示CPU控制组创建成功;

  2. 执行ll test_cpu/后,核心配置文件如下(重点关注两个cfs文件):

  • cpu.cfs_period_us:CPU带宽周期(默认100000微秒);

  • cpu.cfs_quota_us:CPU带宽配额(默认-1,无限制);

  • tasks:控制组内的进程PID列表(将进程写入该文件,即可受控制);

  • cpuacct.usage:控制组内进程的CPU总使用时间(只读,用于查看)。

步骤2:启动CPU满负载压力进程

打开一个新的终端窗口(窗口A),使用stress工具启动一个CPU满负载进程(占用1个CPU核心,使用率100%):

shell 复制代码
# 启动1个CPU压力进程,模拟CPU满负载(-c 1 表示1个进程)
stress -c 1

执行效果说明

命令执行后,终端输出如下信息,表示CPU压力进程启动成功:

shell 复制代码
stress: info: [62576] dispatching hogs: 1 cpu, 0 io, 0 vm, 0 hdd

⚠️ 注意:不要关闭该窗口,打开新的终端窗口(窗口B),用于监控CPU使用率。

步骤3:监控CPU压力进程的使用率和PID

在窗口B中,使用pidstat命令监控stress进程的CPU使用率,确认进程当前CPU使用率为100%,并记录进程PID:

shell 复制代码
# 监控所有stress相关进程的CPU使用情况,采样间隔1秒,持续采样
pidstat -u -C stress -p ALL 1

执行效果说明

输出持续刷新,重点关注PID列(进程ID)和%CPU列(CPU使用率),示例如下:

shell 复制代码
Linux 5.4.0-100-generic (139-159-150-152)  03/12/2023  _x86_64_ (1 CPU)

02:59:39 PM  UID       PID    %usr %system  %guest    %wait     %CPU CPU Command
02:59:39 PM    0     62576    0.00    0.00    0.00    0.00     0.00   0 stress
02:59:39 PM    0     62577   99.01    0.00    0.00    0.99    99.01   0 stress

重点记录:

  • CPU使用率:%CPU列值为99.01%(接近100%,符合预期);

  • 进程PID:CPU占用较高的进程PID(本例中为62577),后续将其加入控制组。

步骤4:配置CPU限制策略(限制使用率30%)

打开一个新的终端窗口(窗口C),进入CPU控制组目录,配置cpu.cfs_quota_us的值为30000(对应30%使用率):

shell 复制代码
# 1. 进入CPU控制组目录
cd /sys/fs/cgroup/cpu/test_cpu

# 2. 查看当前CPU带宽配额(默认-1,无限制)
cat cpu.cfs_quota_us

# 3. 配置CPU带宽配额为30000微秒(对应30%使用率)
echo 30000 > cpu.cfs_quota_us

# 4. 验证配置是否生效(查看配置文件,确认值为30000)
cat cpu.cfs_quota_us

# 5. 查看CPU带宽周期(默认100000微秒,无需修改)
cat cpu.cfs_period_us

执行效果说明

  1. 配置前,cpu.cfs_quota_us的值为-1(无限制);

  2. 配置后,再次查看该文件,输出30000,表示CPU限制策略配置生效;

  3. cpu.cfs_period_us的值为100000(默认值,无需修改),验证计算公式:30000 / 100000 = 0.3 → 30%使用率。

步骤5:将CPU压力进程加入控制组

在窗口C中,将步骤3记录的CPU压力进程PID(62577)写入控制组的tasks文件,让该进程受CPU限制策略管控:

shell 复制代码
# 1. 将进程PID(62577)写入tasks文件(替换为自己的PID)
echo 62577 > tasks

# 2. 验证进程是否已加入控制组(查看tasks文件,确认PID存在)
cat tasks

步骤6:验证CPU控制效果(核心验证)

此时,回到窗口B(pidstat监控窗口),观察进程的CPU使用率变化,核心验证效果:进程CPU使用率从100%降至30%左右。

执行效果说明

监控窗口输出示例(简化版):

shell 复制代码
03:12:51 PM  UID       PID    %usr %system  %guest    %wait     %CPU CPU Command
03:12:51 PM    0     62577   30.00    0.00    0.00   70.00    30.00   0 stress
03:12:52 PM    0     62577   29.80    0.20    0.00   70.00    30.00   0 stress
03:12:53 PM    0     62577   30.20    0.00    0.00   69.80    30.20   0 stress

可以看到,进程的CPU使用率稳定在30%左右,与我们配置的限制策略一致,说明CPU控制生效。

步骤7:清理环境(可选,避免占用资源)

实操完成后,停止压力进程,删除创建的CPU控制组,清理残留资源:

shell 复制代码
# 1. 停止stress压力进程(窗口A中按Ctrl+C,或在任意窗口执行kill命令)
kill -9 62577(替换为自己的PID)

# 2. 进入CPU子系统目录
cd /sys/fs/cgroup/cpu

# 3. 删除CPU控制组目录
rm -rf test_cpu

CPU控制实战总结(重点记)

  • 核心路径:/sys/fs/cgroup/cpu(CPU子系统挂载目录);

  • 核心配置文件:cpu.cfs_period_us(周期,默认100000微秒)、cpu.cfs_quota_us(配额,配置30000对应30%使用率);

  • 核心公式:CPU使用率 = cfs_quota_us / cfs_period_us × 100%;

  • 核心操作:创建控制组目录 → 配置配额文件 → 将进程PID写入tasks文件;

  • 控制效果:进程CPU使用率被限制在配置值以内(稳定在30%左右);

  • 避坑点:配置文件单位是微秒(μs),不要误写为毫秒或秒,否则控制效果异常。

六、实战总结与拓展思考

1. 核心总结

  • CGroups 是Linux内核的资源控制机制,核心作用是限制、隔离进程组的系统资源,是Docker、K8s等容器技术的底层核心;

  • 本次实战重点:CPU控制(限制使用率)和内存控制(限制最大占用),两者实操流程相似,核心都是「创建控制组 → 配置策略 → 加入进程 → 验证效果」;

  • 关键认知:CGroups的控制组本质是/sys/fs/cgroup/子系统下的目录,配置文件是该目录下的系统文件,操作这些文件即可实现资源控制。

2. 拓展思考(对接容器技术)

我们手动配置CGroups的过程较为繁琐(需创建目录、写入配置、加入进程),而Docker本质上就是对CGroups的封装,简化了资源控制操作。

例如,使用Docker启动容器时,只需通过参数即可实现CPU、内存限制,无需手动操作CGroups文件:

shell 复制代码
# Docker限制容器CPU使用率30%、内存20M
docker run -it --cpus 0.3 --memory 20M centos:7 /bin/bash

该命令底层就是创建了CPU、内存控制组,配置了对应的策略,将容器进程加入控制组,与我们本次手动实操的逻辑完全一致------掌握CGroups,就能理解Docker资源控制的底层原理。

3. 常见问题与避坑指南

  • 问题1:执行命令时报「Permission denied」(权限不足)?

    解决方案:切换到root用户执行(su -),或在命令前加sudo(需配置sudo权限)。

  • 问题2:配置内存限制后,进程未被终止?

    解决方案:检查内存限制值是否正确(单位是否为字节),检查进程是否已加入控制组(查看tasks文件)。

  • 问题3:配置CPU限制后,使用率未降至目标值?

    解决方案:检查cfs_quota_us和cfs_period_us的值是否正确,计算是否有误,进程是否已加入控制组。

  • 问题4:删除控制组时,报错「Device or resource busy」?

    解决方案:先终止控制组内的所有进程(kill PID),再删除控制组目录。

4. 后续学习方向

本次实战仅覆盖了CGroups的CPU和内存控制,后续可深入学习:

  • CGroups 其他子系统:IO控制(blkio子系统)、磁盘控制(hdd子系统)、进程数控制(pids子系统);

  • CGroups v2 版本特性:与v1的差异、新的配置方式;

  • Docker 资源控制:结合本次实操,理解Docker参数与CGroups配置的对应关系,实操Docker的CPU、内存、IO限制。

📝 结尾:本文实操全程基于真实Linux环境,所有命令均可直接复制执行,新手建议一步步跟着操作,重点理解"控制组"和"配置文件"的核心逻辑,避免只记命令、不懂原理。如果操作过程中遇到问题,欢迎在评论区留言交流~

相关推荐
礼拜天没时间.4 小时前
Docker 部署分布式 Hadoop(超详细实战版)
linux·hadoop·分布式·docker·容器
小小前端--可笑可笑10 小时前
Vue / React 单页应用刷新 /login 无法访问问题分析
运维·前端·javascript·vue.js·nginx·react.js
DeeplyMind10 小时前
第1章 Docker入门:容器化技术简介
docker·容器·eureka
IP搭子来一个11 小时前
2026年动态IP代理怎么选:共享好还是独享好?
服务器·网络协议·tcp/ip
比奇堡派星星11 小时前
awk命令
linux·运维·服务器
WW、forever11 小时前
【服务器】上传百度网盘数据至服务器
运维·服务器
清水白石00811 小时前
Python 柯里化完全指南:从函数式思想到工程实践
linux·服务器·python
m0_6948455712 小时前
netcut 是什么?简单安全的在线剪贴板搭建与使用教程
运维·服务器·安全·开源·云计算·github
女王大人万岁12 小时前
Golang标准库 CGO 介绍与使用指南
服务器·开发语言·后端·golang