容器虚拟化基础--CGroups资源控制

目录

[1. pidstat](#1. pidstat)

[2. stress](#2. stress)

[3. 实操一:CGroups 信息查看](#3. 实操一:CGroups 信息查看)

[3.1 CGroups 版本查看:](#3.1 CGroups 版本查看:)

[3.2 CGroups 子系统查看](#3.2 CGroups 子系统查看)

[3.3 CGroups 挂载信息查看](#3.3 CGroups 挂载信息查看)

[3.4 查看一个进程上的 cgroup 限制](#3.4 查看一个进程上的 cgroup 限制)

[4. 实操二:使用cgroups对内存进行控制](#4. 实操二:使用cgroups对内存进行控制)

[4.1 cgroupv1 操作:](#4.1 cgroupv1 操作:)

[4.2 cgroupv2 操作:](#4.2 cgroupv2 操作:)

[5. 实操三:使用 cgroups 对CPU进行控制](#5. 实操三:使用 cgroups 对CPU进行控制)

[5.1 cgroupv1 操作](#5.1 cgroupv1 操作)

[5.2 cgroupv2 操作](#5.2 cgroupv2 操作)


望读者通过此文,能够查看 cgroups 基本信息,了解容器化中,操作系统是真正的资源控制层,对 cpu 和内存的控制有一定的理解。

正文开始:

1. pidstat

概述:

pidstat 是 sysstat 的一个命令,用于监控全部或指定进程的 CPU、内存、线程、设备IO 等系统资源的占用情况。Pidstat 第一次采样显示自系统启动开始的各项统计信息,后续采样将显示自上次运行命令后的统计信息。用户可以通过指定统计的次数和时间来获得所需的统计信息

语法:

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

参数:

  • -u:默认参数,显示各进程的 CPU 使用统计

  • -r:显示各进程的内存使用统计

  • -d:显示各进程的 IO 使用情况

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

  • -C:指定命令

  • -l:显示命令名和所有参数

bash 复制代码
# 默认:查看所有进程的 CPU 使用
pidstat

# 每隔 1 秒采样,共 5 次,查看 CPU 使用
pidstat 1 5
# 或显式指定:
pidstat -u 1 5

# 查看指定 PID 的 CPU 使用
pidstat -p 1234 1 5
# 多个 PID 用逗号分隔:
pidstat -p 1234,5678 1 5

# 查看所有进程(包括没有活动但存在的)
pidstat -p ALL 1 3

Ubuntu环境下安装:

bash 复制代码
#卸载
apt remove sysstat -y

#安装
apt install sysstat -y

CentOS环境下安装:

bash 复制代码
#卸载
yum remove sysstat -y

#安装
yum install sysstat -y

2. stress

概述:

stress 是 Linux 的一个压力测试工具,可以对 CPU、Memory、IO、磁盘进行压力测试

语法:

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

参数:

  • -c, --cpu N:产生 N 个进程,每个进程都循环调用 sqrt 函数产生 CPU 压力。

  • -i, --io N:产生 N 个进程,每个进程循环调用 sync 将内存缓冲区内容写到磁盘上,产生 IO 压力。通过系统调用 sync 刷新内存缓冲区数据到磁盘中,以确保同步。如果缓冲区内数据较少,写到磁盘中的数据也较少,不会产生 IO 压力。在 SSD 磁盘环境中尤为明显,很可能 iowait 总是 0,却因为大量调用系统调用 sync,导致系统 CPU 使用率 sys 升高。

  • -m, --vm N:产生 N 个进程,每个进程循环调用 malloc/free 函数分配和释放内存。

  • --vm-bytes B:指定分配内存的大小

  • --vm-keep:一直占用内存,区别于不断的释放和重新分配(默认是不断释放并重新分配内存)

  • -d, --hdd N:产生 N 个不断执行 write 和 unlink 函数的进程(创建文件,写入内容,删除文件)

  • --hdd-bytes B:指定文件大小

  • -t, --timeout N:在 N 秒后结束程序

  • -q, --quiet:程序在运行的过程中不输出信息

Ubuntu环境下安装:

bash 复制代码
#卸载
apt remove stress -y

#安装
apt install stress -y

CentOS环境下安装:

bash 复制代码
#卸载
yum remove stress -y

#安装
yum install stress -y

3. 实操一:CGroups 信息查看

3.1 CGroups 版本查看:

bash 复制代码
root@139-159-150-152:/sys/fs/cgroup# cat /proc/filesystems |grep cgroup
nodev cgroup
nodev cgroup2

如果看到 cgroup2,表示支持 cgroup v2

如何确定系统使用的版本?:

bash 复制代码
#输出 cgroup2fs 表示系统使用的是 cgroup v2;输出 tmpfs 表示使用cgroup v1。
stat -fc %T /sys/fs/cgroup/

3.2 CGroups 子系统查看

cgroupv1 查看

bash 复制代码
root@139-159-150-152:/sys/fs/cgroup# cat /proc/cgroups
#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

cgroupv2 查看

bash 复制代码
root@maxhou-VMware-Virtual-Platform:~# cat 
/sys/fs/cgroup/cgroup.controllers
cpuset cpu io memory hugetlb pids rdma misc dmem

3.3 CGroups 挂载信息查看

cgroupv1 挂载:

可以看到默认存储位置为 /sys/fs/cgroup

bash 复制代码
root@139-159-150-152:/sys/fs/cgroup# mount |grep cgroup
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/systemd type cgroup 
(rw,nosuid,nodev,noexec,relatime,xattr,name=systemd)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup 
(rw,nosuid,nodev,noexec,relatime,cpu,cpuacct)
cgroup on /sys/fs/cgroup/perf_event type cgroup 
(rw,nosuid,nodev,noexec,relatime,perf_event)
cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup 
(rw,nosuid,nodev,noexec,relatime,net_cls,net_prio)
cgroup on /sys/fs/cgroup/pids type cgroup 
(rw,nosuid,nodev,noexec,relatime,pids)
cgroup on /sys/fs/cgroup/blkio type cgroup 
(rw,nosuid,nodev,noexec,relatime,blkio)
cgroup on /sys/fs/cgroup/freezer type cgroup 
(rw,nosuid,nodev,noexec,relatime,freezer)
cgroup on /sys/fs/cgroup/cpuset type cgroup 
(rw,nosuid,nodev,noexec,relatime,cpuset)
cgroup on /sys/fs/cgroup/hugetlb type cgroup 
(rw,nosuid,nodev,noexec,relatime,hugetlb)
cgroup on /sys/fs/cgroup/memory type cgroup 
(rw,nosuid,nodev,noexec,relatime,memory)
cgroup on /sys/fs/cgroup/rdma type cgroup 
(rw,nosuid,nodev,noexec,relatime,rdma)
cgroup on /sys/fs/cgroup/devices type cgroup 
(rw,nosuid,nodev,noexec,relatime,device

3.4 查看一个进程上的 cgroup 限制

cgroupv1 版本查看:

  1. 以当前 shell 进程为例,查看进程的 cgroup
bash 复制代码
[root@VM-8-12-centos ~]# cat /proc/$$/cgroup
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
  1. 比如 cpu 在 user.slice,我们可以找到这个目录,里面有对 init 进程的详细限制信息
bash 复制代码
[root@VM-8-12-centos ~]# ll /sys/fs/cgroup/cpu/user.slice/
total 0
-rw-r--r-- 1 root root 0 Nov 21 15:30 cgroup.clone_children
--w--w--w- 1 root root 0 Nov 21 15:30 cgroup.event_control
-rw-r--r-- 1 root root 0 Nov 21 15:30 cgroup.procs
-r--r--r-- 1 root root 0 Nov 21 15:30 cpuacct.stat
-rw-r--r-- 1 root root 0 Nov 21 15:30 cpuacct.usage
-r--r--r-- 1 root root 0 Nov 21 15:30 cpuacct.usage_percpu
-rw-r--r-- 1 root root 0 Nov 21 15:30 cpu.cfs_period_us
-rw-r--r-- 1 root root 0 Nov 21 15:30 cpu.cfs_quota_us
-rw-r--r-- 1 root root 0 Nov 21 15:30 cpu.rt_period_us
-rw-r--r-- 1 root root 0 Nov 21 15:30 cpu.rt_runtime_us
-rw-r--r-- 1 root root 0 Nov 21 15:30 cpu.shares
-r--r--r-- 1 root root 0 Nov 21 15:30 cpu.stat
-rw-r--r-- 1 root root 0 Nov 21 15:30 notify_on_release
-rw-r--r-- 1 root root 0 Nov 21 15:30 tasks
-rw-r--r-- 1 root root 0 Oct 21 11:16 cgroup.threads
-rw-r--r-- 1 root root 0 Oct 21 11:16 cgroup.type
-rw-r--r-- 1 root root 0 Oct 21 11:16 cpu.idle
-rw-r--r-- 1 root root 0 Oct 21 11:16 cpu.max
-rw-r--r-- 1 root root 0 Oct 21 11:16 cpu.max.burst
-rw-r--r-- 1 root root 0 Oct 21 11:16 cpu.pressure
-r--r--r-- 1 root root 0 Oct 21 11:16 cpu.stat
-r--r--r-- 1 root root 0 Oct 21 11:16 cpu.stat.local
-rw-r--r-- 1 root root 0 Oct 21 11:16 cpu.uclamp.max
-rw-r--r-- 1 root root 0 Oct 21 11:16 cpu.uclamp.min
-rw-r--r-- 1 root root 0 Oct 21 11:16 cpu.weight
-rw-r--r-- 1 root root 0 Oct 21 11:16 cpu.weight.nice
-rw-r--r-- 1 root root 0 Oct 21 11:16 io.pressure
-r--r--r-- 1 root root 0 Oct 21 11:16 memory.current
-r--r--r-- 1 root root 0 Oct 21 11:16 memory.events
-r--r--r-- 1 root root 0 Oct 21 11:16 memory.events.local
-rw-r--r-- 1 root root 0 Oct 21 11:16 memory.high
-rw-r--r-- 1 root root 0 Oct 21 11:16 memory.low
-rw-r--r-- 1 root root 0 Oct 21 11:16 memory.max
-rw-r--r-- 1 root root 0 Oct 21 11:16 memory.min
-r--r--r-- 1 root root 0 Oct 21 11:16 memory.numa_stat
-rw-r--r-- 1 root root 0 Oct 21 11:16 memory.oom.group
-rw-r--r-- 1 root root 0 Oct 21 11:16 memory.peak
-rw-r--r-- 1 root root 0 Oct 21 11:16 memory.pressure
--w------- 1 root root 0 Oct 21 11:16 memory.reclaim
-r--r--r-- 1 root root 0 Oct 21 11:16 memory.stat
-r--r--r-- 1 root root 0 Oct 21 11:16 memory.swap.current
-r--r--r-- 1 root root 0 Oct 21 11:16 memory.swap.events
-rw-r--r-- 1 root root 0 Oct 21 11:16 memory.swap.high
-rw-r--r-- 1 root root 0 Oct 21 11:16 memory.swap.max
-rw-r--r-- 1 root root 0 Oct 21 11:16 memory.swap.peak
-r--r--r-- 1 root root 0 Oct 21 11:16 memory.zswap.current
-rw-r--r-- 1 root root 0 Oct 21 11:16 memory.zswap.max
-rw-r--r-- 1 root root 0 Oct 21 11:16 memory.zswap.writeback
-r--r--r-- 1 root root 0 Oct 21 11:16 pids.current
-r--r--r-- 1 root root 0 Oct 21 11:16 pids.events
-r--r--r-- 1 root root 0 Oct 21 11:16 pids.events.local
-rw-r--r-- 1 root root 0 Oct 21 11:16 pids.max
-r--r--r-- 1 root root 0 Oct 21 11:16 pids.peak

4. 实操二:使用cgroups对内存进行控制

4.1 cgroupv1 操作:

  1. 创建内存的 cgroup,很简单我们进入到 cgroup 的内存控制目录/sys/fs/cgroup/memory,我们创建目录 test_memory
bash 复制代码
root@139-159-150-152:/sys/fs/cgroup/memory# mkdir test_memory
root@139-159-150-152:/sys/fs/cgroup/memory# ll
total 0
dr-xr-xr-x 7 root root 0 Mar 10 14:13 ./
drwxr-xr-x 15 root root 380 Mar 10 14:13 ../
-rw-r--r-- 1 root root 0 Mar 12 14:13 cgroup.clone_children
--w--w--w- 1 root root 0 Mar 12 14:13 cgroup.event_control
-rw-r--r-- 1 root root 0 Mar 12 14:13 cgroup.procs
-r--r--r-- 1 root root 0 Mar 12 14:13 cgroup.sane_behavior
drwxr-xr-x 2 root root 0 Mar 12 14:13 docker/
drwxr-xr-x 2 root root 0 Mar 12 14:13 init.scope/
-rw-r--r-- 1 root root 0 Mar 12 14:13 memory.failcnt
--w------- 1 root root 0 Mar 12 14:13 memory.force_empty
-rw-r--r-- 1 root root 0 Mar 12 14:13 memory.kmem.failcnt
-rw-r--r-- 1 root root 0 Mar 12 14:13 
memory.kmem.limit_in_bytes
-rw-r--r-- 1 root root 0 Mar 12 14:13 
memory.kmem.max_usage_in_bytes
-r--r--r-- 1 root root 0 Mar 12 14:13 memory.kmem.slabinfo
-rw-r--r-- 1 root root 0 Mar 12 14:13 memory.kmem.tcp.failcnt
-rw-r--r-- 1 root root 0 Mar 12 14:13 
memory.kmem.tcp.limit_in_bytes
-rw-r--r-- 1 root root 0 Mar 12 14:13 
memory.kmem.tcp.max_usage_in_bytes
-r--r--r-- 1 root root 0 Mar 12 14:13 
memory.kmem.tcp.usage_in_bytes
-r--r--r-- 1 root root 0 Mar 12 14:13 
memory.kmem.usage_in_bytes
-rw-r--r-- 1 root root 0 Mar 12 14:13 memory.limit_in_bytes
-rw-r--r-- 1 root root 0 Mar 12 14:13 memory.max_usage_in_bytes
-rw-r--r-- 1 root root 0 Mar 12 14:13 
memory.move_charge_at_immigrate
-r--r--r-- 1 root root 0 Mar 12 14:13 memory.numa_stat
-rw-r--r-- 1 root root 0 Mar 12 14:13 memory.oom_control
---------- 1 root root 0 Mar 12 14:13 memory.pressure_level
-rw-r--r-- 1 root root 0 Mar 12 14:13 
memory.soft_limit_in_bytes
-r--r--r-- 1 root root 0 Mar 12 14:13 memory.stat
-rw-r--r-- 1 root root 0 Mar 12 14:13 memory.swappiness
-r--r--r-- 1 root root 0 Mar 12 14:13 memory.usage_in_bytes
-rw-r--r-- 1 root root 0 Mar 12 14:13 memory.use_hierarchy
-rw-r--r-- 1 root root 0 Mar 12 14:13 notify_on_release
-rw-r--r-- 1 root root 0 Mar 12 14:13 release_agent
drwxr-xr-x 95 root root 0 Mar 12 13:22 system.slice/
-rw-r--r-- 1 root root 0 Mar 12 14:13 tasks
drwxr-xr-x 2 root root 0 Mar 12 14:14 test_memory/
drwxr-xr-x 3 root root 0 Mar 12 13:58 user.slice/
  1. 可以看到内存限制文件已经自动在 test_memory 中创建完成了,cgroups 文件系统会在创建文件目录的时候自动创建相应的配置文件
bash 复制代码
root@139-159-150-152:/sys/fs/cgroup/memory/test_memory# ll
total 0
drwxr-xr-x 2 root root 0 Mar 12 14:14 ./
dr-xr-xr-x 7 root root 0 Mar 10 14:13 ../
-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.kmem.failcnt
-rw-r--r-- 1 root root 0 Mar 12 14:14 memory.kmem.limit_in_bytes
-rw-r--r-- 1 root root 0 Mar 12 14:14 
memory.kmem.max_usage_in_bytes
-r--r--r-- 1 root root 0 Mar 12 14:14 memory.kmem.slabinfo
-rw-r--r-- 1 root root 0 Mar 12 14:14 memory.kmem.tcp.failcnt
-rw-r--r-- 1 root root 0 Mar 12 14:14 
memory.kmem.tcp.limit_in_bytes
-rw-r--r-- 1 root root 0 Mar 12 14:14 
memory.kmem.tcp.max_usage_in_bytes
-r--r--r-- 1 root root 0 Mar 12 14:14 
memory.kmem.tcp.usage_in_bytes
-r--r--r-- 1 root root 0 Mar 12 14:14 memory.kmem.usage_in_bytes
-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
-rw-r--r-- 1 root root 0 Mar 12 14:14 
memory.move_charge_at_immigrate
-r--r--r-- 1 root root 0 Mar 12 14:14 memory.numa_stat
-rw-r--r-- 1 root root 0 Mar 12 14:14 memory.oom_control
---------- 1 root root 0 Mar 12 14:14 memory.pressure_level
-rw-r--r-- 1 root root 0 Mar 12 14:14 memory.soft_limit_in_bytes
-r--r--r-- 1 root root 0 Mar 12 14:14 memory.stat
-rw-r--r-- 1 root root 0 Mar 12 14:14 memory.swappiness
-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 memory.use_hierarchy
-rw-r--r-- 1 root root 0 Mar 12 14:14 notify_on_release
-rw-r--r-- 1 root root 0 Mar 12 14:14 tasks
  1. 配置 cgroup 的策略为最大使用 20M 内存
bash 复制代码
root@139-159-150-152:/sys/fs/cgroup/memory# expr 20 \* 1024 \* 1024
20971520
root@139-159-150-152:/sys/fs/cgroup/memory# cat test_memory/memory.limit_in_bytes 
9223372036854771712
root@139-159-150-152:/sys/fs/cgroup/memory# echo "20971520" > 
test_memory/memory.limit_in_bytes
root@139-159-150-152:/sys/fs/cgroup/memory# cat test_memory/memory.limit_in_bytes 
20971520
  1. 启动 1 个消耗内存的进程,每个进程占用 50M 内存
bash 复制代码
stress -m 1 --vm-bytes 50M
stress: info: [62106] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
  1. 打开一个新的 shell 窗口 B 窗口,使用 pidstat 查看状态,PID为62518是进程 id
bash 复制代码
cd "/sys/fs/cgroup/memory/test_memlimit"

pidstat -r -C stress -p ALL 1 10000
Linux 5.4.0-100-generic (139-159-150-152) 03/12/2025 _x86_64_ (1 CPU)

02:47:01 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

02:47:02 PM UID PID   minflt/s    majflt/s VSZ   RSS %MEM Command
02:47:03 PM 0   62517 0.00        0.00     3856  988 0.05 stress
02:47:03 PM 0   62518 483459.00   0.00     55060 3540 0.17 stress
 
02:47:03 PM UID PID   minflt/s    majflt/s VSZ   RSS %MEM Command
02:47:04 PM 0   62517 0.00        0.00     3856  988 0.05  stress
02:47:04 PM 0   62518 489336.00   0.00     55060 15156 0.75 stress
  1. 打开一个新的 shell C 窗口,将进程 id 移动到我们的 cgroup 策略
bash 复制代码
cd /sys/fs/cgroup/memory
echo "62518" > test_memory/tasks
  1. 可以看到进程无法申请到足够内存退出

可以看到进程消失了:

4.2 cgroupv2 操作:

  1. 查看当前的控制,确认 memory 是支持的
bash 复制代码
# 确认系统版本
root@maxhou-VMware-Virtual-Platform:~# stat -fc %T /sys/fs/cgroup/
cgroup2fs

root@maxhou-VMware-Virtual-Platform:~# cat /sys/fs/cgroup/cgroup.controllers
cpuset cpu io memory hugetlb pids rdma misc
  1. cgroup v2 挂载在/sys/fs/cgroup,创建子 cgroup 目录
bash 复制代码
root@maxhou-VMware-Virtual-Platform:~# mkdir /sys/fs/cgroup/test_memory
root@maxhou-VMware-Virtual-Platform:~# ll 
/sys/fs/cgroup/test_memory/
total 0
drwxr-xr-x 2 root root 0 Oct 21 11:28 ./
dr-xr-xr-x 13 root root 0 Oct 21 11:28 ../
-r--r--r-- 1 root root 0 Oct 21 11:28 cgroup.controllers
-r--r--r-- 1 root root 0 Oct 21 11:28 cgroup.events
-rw-r--r-- 1 root root 0 Oct 21 11:28 cgroup.freeze
--w------- 1 root root 0 Oct 21 11:28 cgroup.kill
-rw-r--r-- 1 root root 0 Oct 21 11:28 cgroup.max.depth
-rw-r--r-- 1 root root 0 Oct 21 11:28 cgroup.max.descendants
-rw-r--r-- 1 root root 0 Oct 21 11:28 cgroup.pressure
-rw-r--r-- 1 root root 0 Oct 21 11:28 cgroup.procs
-r--r--r-- 1 root root 0 Oct 21 11:28 cgroup.stat
-rw-r--r-- 1 root root 0 Oct 21 11:28 cgroup.subtree_control
-rw-r--r-- 1 root root 0 Oct 21 11:28 cgroup.threads
-rw-r--r-- 1 root root 0 Oct 21 11:28 cgroup.type
-rw-r--r-- 1 root root 0 Oct 21 11:28 cpu.idle
-rw-r--r-- 1 root root 0 Oct 21 11:28 cpu.max
-rw-r--r-- 1 root root 0 Oct 21 11:28 cpu.max.burst
-rw-r--r-- 1 root root 0 Oct 21 11:28 cpu.pressure
-rw-r--r-- 1 root root 0 Oct 21 11:28 cpuset.cpus
-r--r--r-- 1 root root 0 Oct 21 11:28 cpuset.cpus.effective
-rw-r--r-- 1 root root 0 Oct 21 11:28 cpuset.cpus.exclusive
-r--r--r-- 1 root root 0 Oct 21 11:28 
cpuset.cpus.exclusive.effective
-rw-r--r-- 1 root root 0 Oct 21 11:28 cpuset.cpus.partition
-rw-r--r-- 1 root root 0 Oct 21 11:28 cpuset.mems
-r--r--r-- 1 root root 0 Oct 21 11:28 cpuset.mems.effective
-r--r--r-- 1 root root 0 Oct 21 11:28 cpu.stat
-r--r--r-- 1 root root 0 Oct 21 11:28 cpu.stat.local
-rw-r--r-- 1 root root 0 Oct 21 11:28 cpu.uclamp.max
-rw-r--r-- 1 root root 0 Oct 21 11:28 cpu.uclamp.min
-rw-r--r-- 1 root root 0 Oct 21 11:28 cpu.weight
-rw-r--r-- 1 root root 0 Oct 21 11:28 cpu.weight.nice
-rw-r--r-- 1 root root 0 Oct 21 11:28 io.max
-rw-r--r-- 1 root root 0 Oct 21 11:28 io.pressure
-rw-r--r-- 1 root root 0 Oct 21 11:28 io.prio.class
-r--r--r-- 1 root root 0 Oct 21 11:28 io.stat
-rw-r--r-- 1 root root 0 Oct 21 11:28 io.weight
-r--r--r-- 1 root root 0 Oct 21 11:28 memory.current
-r--r--r-- 1 root root 0 Oct 21 11:28 memory.events
-r--r--r-- 1 root root 0 Oct 21 11:28 memory.events.local
-rw-r--r-- 1 root root 0 Oct 21 11:28 memory.high
-rw-r--r-- 1 root root 0 Oct 21 11:28 memory.low
-rw-r--r-- 1 root root 0 Oct 21 11:28 memory.max
-rw-r--r-- 1 root root 0 Oct 21 11:28 memory.min
-r--r--r-- 1 root root 0 Oct 21 11:28 memory.numa_stat
-rw-r--r-- 1 root root 0 Oct 21 11:28 memory.oom.group
-rw-r--r-- 1 root root 0 Oct 21 11:28 memory.peak
-rw-r--r-- 1 root root 0 Oct 21 11:28 memory.pressure
--w------- 1 root root 0 Oct 21 11:28 memory.reclaim
-r--r--r-- 1 root root 0 Oct 21 11:28 memory.stat
-r--r--r-- 1 root root 0 Oct 21 11:28 memory.swap.current
-r--r--r-- 1 root root 0 Oct 21 11:28 memory.swap.events
-rw-r--r-- 1 root root 0 Oct 21 11:28 memory.swap.high
-rw-r--r-- 1 root root 0 Oct 21 11:28 memory.swap.max
-rw-r--r-- 1 root root 0 Oct 21 11:28 memory.swap.peak
-r--r--r-- 1 root root 0 Oct 21 11:28 memory.zswap.current
-rw-r--r-- 1 root root 0 Oct 21 11:28 memory.zswap.max
-rw-r--r-- 1 root root 0 Oct 21 11:28 memory.zswap.writeback
-r--r--r-- 1 root root 0 Oct 21 11:28 pids.current
-r--r--r-- 1 root root 0 Oct 21 11:28 pids.events
-r--r--r-- 1 root root 0 Oct 21 11:28 pids.events.local
-rw-r--r-- 1 root root 0 Oct 21 11:28 pids.max
-r--r--r-- 1 root root 0 Oct 21 11:28 pids.peak
  1. 配置 cgroup 的策略为最大使用 20M 内存
bash 复制代码
root@maxhou-VMware-Virtual-Platform:/sys/fs/cgroup/test_memory# cd /sys/fs/cgroup/test_memory
root@maxhou-VMware-Virtual-Platform:/sys/fs/cgroup/test_memory# 
echo 20M > memory.max
  1. 启动 1 个消耗内存的进程,每个进程占用 50M 内存
bash 复制代码
stress -m 1 --vm-bytes 50M
stress: info: [4006] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
  1. 打开一个新的 shell 窗口 B 窗口,使用 pidstat 查看状态,PID:4746为进程 id
bash 复制代码
pidstat -r -C stress -p ALL 1 10000
Linux 6.14.0-33-generic (maxhou-VMware-Virtual-Platform) 
10/21/2025     _x86_64_     (4 CPU)

12:08:43 PM UID  PID    minflt/s    majflt/s   VSZ   RSS    %MEM   Command
12:08:44 PM 0    4745     0.00       0.00     3620   2004   0.02   stress
12:08:44 PM 0    4746   108256.60    0.00    54824   28264  0.35   stress

12:08:44 PM UID  PID    minflt/s    majflt/s   VSZ   RSS    %MEM   Command
12:08:45 PM 0    4745   0.00         0.00      3620  2004   0.02    stress
12:08:45 PM 0    4746   108356.00    0.00     54824  896    0.01    stress

12:08:45 PM UID  PID    minflt/s    majflt/s   VSZ   RSS    %MEM   Command
12:08:46 PM 0   4745    0.00        0.00       3620  2004   0.02   stress 
12:08:46 PM 0   4746  108372.00     0.00       54824 24784  0.31   stress
  1. 打开一个新的 shell C 窗口,将进程 id 移动到我们的 cgroup 策略
bash 复制代码
cd /sys/fs/cgroup/test_memory
root@maxhou-VMware-Virtual-Platform:/sys/fs/cgroup/test_memory# 
echo 4745 >> cgroup.procs 
root@maxhou-VMware-Virtual-Platform:/sys/fs/cgroup/test_memory# 
echo 4746 >> cgroup.procs
  1. 可以看到进程无法申请到足够内存退出

可以看到进程消失了

5. 实操三:使用 cgroups 对CPU进行控制

5.1 cgroupv1 操作

  1. 创建内存的 cgroup,很简单我们进入到 cgroup 的内存控制目录/sys/fs/cgroup/cpu,我们创建目录 test_cpu,可以看到系统会自动为我们创建 cgroup的 cpu 策略
bash 复制代码
# 若忘记了cgroup的内存控制目录,可执行下面命令查找
mount | grep cgrou

root@139-159-150-152:/sys/fs/cgroup/cpu# cd /sys/fs/cgroup/cpu
root@139-159-150-152:/sys/fs/cgroup/cpu# mkdir test_cpu
root@139-159-150-152:/sys/fs/cgroup/cpu# ll test_cpu
total 0
drwxr-xr-x 2 root root 0 Mar 12 14:54 ./
dr-xr-xr-x 9 root root 0 Mar 10 14:13 ../
-rw-r--r-- 1 root root 0 Mar 12 14:54 cgroup.clone_children
-rw-r--r-- 1 root root 0 Mar 12 14:54 cgroup.procs
-r--r--r-- 1 root root 0 Mar 12 14:54 cpuacct.stat
-rw-r--r-- 1 root root 0 Mar 12 14:54 cpuacct.usage
-r--r--r-- 1 root root 0 Mar 12 14:54 cpuacct.usage_all
-r--r--r-- 1 root root 0 Mar 12 14:54 cpuacct.usage_percpu
-r--r--r-- 1 root root 0 Mar 12 14:54 cpuacct.usage_percpu_sys
-r--r--r-- 1 root root 0 Mar 12 14:54 cpuacct.usage_percpu_user
-r--r--r-- 1 root root 0 Mar 12 14:54 cpuacct.usage_sys
-r--r--r-- 1 root root 0 Mar 12 14:54 cpuacct.usage_user
-rw-r--r-- 1 root root 0 Mar 12 14:54 cpu.cfs_period_us
-rw-r--r-- 1 root root 0 Mar 12 14:54 cpu.cfs_quota_us
-rw-r--r-- 1 root root 0 Mar 12 14:54 cpu.shares
-r--r--r-- 1 root root 0 Mar 12 14:54 cpu.stat
-rw-r--r-- 1 root root 0 Mar 12 14:54 cpu.uclamp.max
-rw-r--r-- 1 root root 0 Mar 12 14:54 cpu.uclamp.min
-rw-r--r-- 1 root root 0 Mar 12 14:54 notify_on_release
-rw-r--r-- 1 root root 0 Mar 12 14:54 tasks
  1. 打开新的 shell 窗口 B 窗口,使用 stress 模拟一个任务,cpu 使用率为 100
bash 复制代码
root@139-159-150-152:/sys/fs/cgroup# stress -c 1
stress: info: [62576] dispatching hogs: 1 cpu, 0 io, 0 vm, 0 hdd
  1. 转回窗口A,执行下列命令可以看到 cpu 的使用率
bash 复制代码
cd "/sys/fs/cgroup/cpu/test_cpu"

pidstat -u -C stress -p ALL 1 10000
Linux 5.4.0-100-generic (139-159-150-152) 03/12/2025 _x86_64_ (1 CPU)

02:59:38 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

02:59:39 PM UID   PID   %usr   %system  %guest   %wait  %CPU CPU Command
02:59:40 PM 0    62576  0.00   0.00     0.00     0.00   0.00  0  stress
02:59:40 PM 0    62577  99.00  0.00     0.00     1.00   99.00 0  stress
  1. 打开新的 shell 窗口 C 窗口,我们设置 cproup 的 cpu 使用率为 30%,cpu 使用率的计算公式 cfs_quota_us/cfs_period_us
  • cfs_period_us:cfs_period_us 表示一个 cpu 带宽,单位为微秒。系统总 CPU 带宽 ,默认值 100000。

  • cfs_quota_us:cfs_quota_us 表示 Cgroup 可以使用的 cpu 的带宽,单位为微秒。cfs_quota_us 为-1,表示使用的 CPU 不受 cgroup 限制。cfs_quota_us 的最小值为1ms(1000),最大值为 1s。

所以我们将 cfs_quota_us的值设置为30000**,从理论上讲就可以限制test_cpu控制的进程的cpu利用率最多是30%****。**

bash 复制代码
# 可先查看其默认值
cat cpu.cfs_period_us
100000

cat cpu.cfs_quota_us
-1

cd /sys/fs/cgroup/cpu
echo 30000 > test_cpu/cpu.cfs_quota_us
  1. 我们可以看到进程的 PID 为 62577,我们将该进程放到 tasks 文件进行控制
bash 复制代码
cd /sys/fs/cgroup/cpu
echo 62577 > test_cpu/tasks
  1. B 窗口中可以看到我们监控的 cpu 的使用率由 100%降低为 30%

5.2 cgroupv2 操作

  1. 创建内存的 cgroup,很简单我们进入到 cgroup 的内存控制目录/sys/fs/cgroup/,我们创建目录 test_cpu,可以看到系统会自动为我们创建 cgroup 的 cpu 策略
bash 复制代码
root@maxhou-VMware-Virtual-Platform:/sys/fs/cgroup# cd /sys/fs/cgroup/
root@maxhou-VMware-Virtual-Platform:/sys/fs/cgroup# mkdir test_cpu
root@maxhou-VMware-Virtual-Platform:/sys/fs/cgroup# ll test_cpu/
total 0
drwxr-xr-x 2 root root 0 Oct 21 12:13 ./
dr-xr-xr-x 14 root root 0 Oct 21 12:12 ../
-r--r--r-- 1 root root 0 Oct 21 12:13 cgroup.controllers
-r--r--r-- 1 root root 0 Oct 21 12:13 cgroup.events
-rw-r--r-- 1 root root 0 Oct 21 12:13 cgroup.freeze
--w------- 1 root root 0 Oct 21 12:13 cgroup.kill
-rw-r--r-- 1 root root 0 Oct 21 12:13 cgroup.max.depth
-rw-r--r-- 1 root root 0 Oct 21 12:13 cgroup.max.descendants
-rw-r--r-- 1 root root 0 Oct 21 12:13 cgroup.pressure
-rw-r--r-- 1 root root 0 Oct 21 12:13 cgroup.procs
-r--r--r-- 1 root root 0 Oct 21 12:13 cgroup.stat
-rw-r--r-- 1 root root 0 Oct 21 12:13 cgroup.subtree_control
-rw-r--r-- 1 root root 0 Oct 21 12:13 cgroup.threads
-rw-r--r-- 1 root root 0 Oct 21 12:13 cgroup.type
-rw-r--r-- 1 root root 0 Oct 21 12:13 cpu.idle
-rw-r--r-- 1 root root 0 Oct 21 12:13 cpu.max
-rw-r--r-- 1 root root 0 Oct 21 12:13 cpu.max.burst
-rw-r--r-- 1 root root 0 Oct 21 12:13 cpu.pressure
-rw-r--r-- 1 root root 0 Oct 21 12:13 cpuset.cpus
-r--r--r-- 1 root root 0 Oct 21 12:13 cpuset.cpus.effective
-rw-r--r-- 1 root root 0 Oct 21 12:13 cpuset.cpus.exclusive
-r--r--r-- 1 root root 0 Oct 21 12:13 
cpuset.cpus.exclusive.effective
-rw-r--r-- 1 root root 0 Oct 21 12:13 cpuset.cpus.partition
-rw-r--r-- 1 root root 0 Oct 21 12:13 cpuset.mems
-r--r--r-- 1 root root 0 Oct 21 12:13 cpuset.mems.effective
-r--r--r-- 1 root root 0 Oct 21 12:13 cpu.stat
-r--r--r-- 1 root root 0 Oct 21 12:13 cpu.stat.local
-rw-r--r-- 1 root root 0 Oct 21 12:13 cpu.uclamp.max
-rw-r--r-- 1 root root 0 Oct 21 12:13 cpu.uclamp.min
-rw-r--r-- 1 root root 0 Oct 21 12:13 cpu.weight
-rw-r--r-- 1 root root 0 Oct 21 12:13 cpu.weight.nice
-rw-r--r-- 1 root root 0 Oct 21 12:13 io.max
-rw-r--r-- 1 root root 0 Oct 21 12:13 io.pressure
-rw-r--r-- 1 root root 0 Oct 21 12:13 io.prio.class
-r--r--r-- 1 root root 0 Oct 21 12:13 io.stat
-rw-r--r-- 1 root root 0 Oct 21 12:13 io.weight
-r--r--r-- 1 root root 0 Oct 21 12:13 memory.current
-r--r--r-- 1 root root 0 Oct 21 12:13 memory.events
-r--r--r-- 1 root root 0 Oct 21 12:13 memory.events.local
-rw-r--r-- 1 root root 0 Oct 21 12:13 memory.high
-rw-r--r-- 1 root root 0 Oct 21 12:13 memory.low
-rw-r--r-- 1 root root 0 Oct 21 12:13 memory.max
-rw-r--r-- 1 root root 0 Oct 21 12:13 memory.min
-r--r--r-- 1 root root 0 Oct 21 12:13 memory.numa_stat
-rw-r--r-- 1 root root 0 Oct 21 12:13 memory.oom.group
-rw-r--r-- 1 root root 0 Oct 21 12:13 memory.peak
-rw-r--r-- 1 root root 0 Oct 21 12:13 memory.pressure
--w------- 1 root root 0 Oct 21 12:13 memory.reclaim
-r--r--r-- 1 root root 0 Oct 21 12:13 memory.stat
-r--r--r-- 1 root root 0 Oct 21 12:13 memory.swap.current
-r--r--r-- 1 root root 0 Oct 21 12:13 memory.swap.events
-rw-r--r-- 1 root root 0 Oct 21 12:13 memory.swap.high
-rw-r--r-- 1 root root 0 Oct 21 12:13 memory.swap.max
-rw-r--r-- 1 root root 0 Oct 21 12:13 memory.swap.peak
-r--r--r-- 1 root root 0 Oct 21 12:13 memory.zswap.current
-rw-r--r-- 1 root root 0 Oct 21 12:13 memory.zswap.max
-rw-r--r-- 1 root root 0 Oct 21 12:13 memory.zswap.writeback
-r--r--r-- 1 root root 0 Oct 21 12:13 pids.current
-r--r--r-- 1 root root 0 Oct 21 12:13 pids.events
-r--r--r-- 1 root root 0 Oct 21 12:13 pids.events.local
-rw-r--r-- 1 root root 0 Oct 21 12:13 pids.max
-r--r--r-- 1 root root 0 Oct 21 12:13 pids.peak
  1. 打开新的 shell 窗口 B 窗口,使用 stress 模拟一个任务,cpu 使用率为 100
bash 复制代码
root@maxhou-VMware-Virtual-Platform:/sys/fs/cgroup# stress -c 1
stress: info: [4781] dispatching hogs: 1 cpu, 0 io, 0 vm, 0 hdd
  1. 可以看到 cpu 的使用率
bash 复制代码
pidstat -u -C stress -p ALL 1 10000
  1. 打开新的 shell 窗口 C 窗口,我们设置 cproup 的 cpu 使用率为 30%,cpu 使用率的计算公式 cfs_quota_us/cfs_period_us
  • cfs_period_us:cfs_period_us 表示一个 cpu 带宽,单位为微秒。系统总 CPU 带宽 ,默认值 100000。

  • cfs_quota_us:cfs_quota_us 表示 Cgroup 可以使用的 cpu 的带宽,单位为微秒。cfs_quota_us 为-1,表示使用的 CPU 不受 cgroup 限制。cfs_quota_us 的最小值为1ms(1000),最大值为 1s。

所以我们将 cfs_quota_us的值设置为30000**,从理论上讲就可以限制test_cpu控制的进程的cpu利用率最多是30%****。**

bash 复制代码
cd /sys/fs/cgroup/test_cpu
echo "30000 100000" > cpu.max
  1. 我们可以看到进程的 PID 为 4782,我们将该进程放到 procs 文件进行控制
bash 复制代码
echo 4782 > cgroup.procs
  1. B 窗口中可以看到我们监控的 cpu 的使用率由 100%降低为 30%

至此我们成功的模拟了对内存和 cpu 的使用控制,而 docker 本质也是调用这些的 API 来完成对资源的管理,只不过 docker 的易用性和镜像的设计更加人性化,所以 docker才能风靡全球。

相关推荐
山东孙燕姿1 小时前
维修工单的转派与协同:两个人一起上
大数据·运维·服务器·网络·人工智能
AI你一生一世1 小时前
Cloud in a Bottle:把自托管从“运维苦役”变成“可交付的私有云”
运维·部署·状态管理·容器编排·私有云·备份恢复·自托管
BioRunYiXue2 小时前
使用docker分析高通量测序数据
java·数据库·人工智能·spring cloud·docker·tomcat·html
Madison-No72 小时前
Jenkins持续集成
运维·ci/cd·jenkins
Initialize293083 小时前
Docker 容器网络不通?五步排查法
运维
重生之高冷汉堡包3 小时前
家庭住宅IP是什么?机房住宅与普通住宅有什么区别
运维·服务器·网络·网络协议·tcp/ip·用户运营
Thneonl3 小时前
git reset --hard 之后先别哭:reflog 里存着你刚弄丢的那个分支
运维·后端
见闻小天地3 小时前
液冷直流负载:AI 算力中心带载测试的关键设备
运维·业界资讯
迪康软件zz3 小时前
从 PHP 高危漏洞看纵深防御:资产盘点、补丁管理与端点防护实践
运维·安全·自动化运维