欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 美食 > 【Docker-5】资源控制实战

【Docker-5】资源控制实战

2025/4/17 17:40:14 来源:https://blog.csdn.net/2202_75331338/article/details/146970190  浏览:    关键词:【Docker-5】资源控制实战

CGroups 资源控制实战

一、实战目的

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

二、基础知识

1.pidstat

pidstat 是一个在 Linux 系统中用于监控和分析单个进程性能的强大命令行工具。它是 sysstat 工具包的一部分,该工具包提供了多种用于系统性能监控的实用程序。pidstat 命令可以生成关于进程活动各个方面的详细统计信息,包括 CPU 使用率、内存消耗、I/O 操作、上下文切换等

主要功能

CPU 使用率:监控进程占用的 CPU 时间百分比,帮助识别高 CPU 占用的进程。

内存使用情况:显示进程的内存使用情况,包括常驻内存集(RSS)、虚拟内存大小(VSZ)以及页面错误等信息。

I/O 活动:跟踪进程的 I/O 操作,例如读写请求的数量和速率,帮助发现 I/O 密集型进程。

上下文切换:统计进程的上下文切换次数,包括自愿和非自愿切换,有助于分析调度问题。

线程统计信息:支持查看多线程应用程序中每个线程的资源使用情况。

任务切换频率:提供任务运行队列长度和任务切换频率的信息,帮助评估系统的调度负载。

语法:

pidstat [ 选项 ] [ <时间间隔> ] [ <次数> ]

一些常用的 pidstat 命令选项及其作用:

  • -u:显示 CPU 使用率统计信息,默认参数
  • -r:显示内存使用情况统计信息。
  • -d:显示 I/O 统计信息。
  • -w:显示上下文切换统计信息。
  • -t:显示线程级别的统计信息。
  • -l:显示命令名和所有参数
  • -p <PID>:指定要监控的进程 ID(PID)。如果使用 ALL,则显示所有进程的统计信息。
  • <interval>:设置统计信息的刷新间隔(单位为秒)。
  • <count>:设置统计信息的输出次数。

安装

Ubuntu 安装
#卸载
apt remove sysstat -y
#安装
apt install sysstat -yCentOS 安装
#卸载
yum remove sysstat -y
#安装
yum install sysstat -y

示例用法:

1. 查看所有进程的 CPU 使用情况 每隔 2 秒刷新一次,共输出 2 次

QQ_1741953489734

07:57:11 PM   UID       PID    %usr %system  %guest   %wait    %CPU   CPU  Command
07:57:13 PM     0       754    0.00    0.50    0.00    0.00    0.50     1  AliYunDunUpdate
时间戳07:57:13 PM统计信息的时间点,格式为 HH:MM:SS AM/PM
UID0进程的所有者用户 ID。0表示超级用户(root)。
PID754进程的唯一标识符(进程 ID)。
%usr0.00进程在用户空间中消耗的 CPU 时间百分比。0.00%表示没有显著的用户级计算任务。
%system0.50进程在内核空间中消耗的 CPU 时间百分比。0.50%表示有少量内核操作(如系统调用)。
%guest0.00进程在虚拟化环境中运行客户机操作系统所消耗的 CPU 时间百分比。0.00%表示无虚拟化任务。
%wait0.00进程等待 I/O 操作完成的时间百分比。0.00%表示没有因 I/O 阻塞的情况。
%CPU0.50进程总的 CPU 使用率。0.50%%usr%system的总和。
CPU1运行该进程的 CPU 核心编号。1表示该进程当前运行在 CPU 核心 1 上。
CommandAliYunDunUpdate启动该进程的命令名称。AliYunDunUpdate是阿里云安全服务的一个组件,用于更新安全规则等。

2.查看特定进程的内存使用情况–显示 PID 为 994 的进程的内存使用情况

QQ_1741953818479

minflt/s0.00每秒发生的次要页面错误数(minor page faults)。0.00表示没有发生内存页错误。
majflt/s0.00每秒发生的主要页面错误数(major page faults)。0.00表示没有发生需要从磁盘加载的页面错误。
VSZ1792088虚拟内存大小(Virtual Memory Size),单位为 KB。表示进程占用的虚拟内存总量。
RSS10928常驻内存集(Resident Set Size),单位为 KB。表示进程实际占用的物理内存大小。
%MEM0.64进程占用的物理内存百分比。0.64%表示该进程占用了系统总内存的 0.64%。
Commandmysqld启动该进程的命令名称。mysqld是 MySQL 数据库服务的主进程。

3.查看I/O活动–显示所有进程的 I/O 操作统计信息QQ_1741954016900

4. 查看上下文切换统计信息—显示所有进程的上下文切换信息

QQ_1741954073467

5. 查看线程级别的 CPU 使用率—查看所有进程中每个线程CPU使用率

QQ_1741954164809

2.stress

stress 是一个用于在 Linux 系统中模拟高负载的工具,常用于测试系统的稳定性和性能极限。它可以人为地施加 CPU、内存、I/O 和磁盘压力,以观察系统在高负载情况下的表现。

stress 的主要功能

CPU 压力测试

  • 通过生成繁忙的计算任务(如平方根运算)来占用 CPU 资源。
  • 可以指定使用的 CPU 核心数量。

内存压力测试

  • 分配大量内存并持续访问,模拟内存使用高峰。
  • 可以指定分配的内存大小和分配的数量。

I/O 压力测试

  • 通过频繁读写文件来模拟 I/O 密集型操作。
  • 可以指定并发的 I/O 操作数量。

磁盘压力测试

  • 创建和删除大量临时文件,模拟磁盘密集型操作。
  • 可以指定创建的文件数量和文件大小。

安装

Ubuntu
#卸载
apt remove stress -y
#安装
apt install stress -yCentOS
#卸载
yum remove stress -y
#安装
yum install stress -y

常用命令选项

-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:程序在运行的过程中不输出信息

示例用法:

1.对 CPU 施加压力–启动 4 个 CPU 工作线程,持续 30 秒。

QQ_1741954817870

QQ_1741954853304

2.对 I/O 施加压力–启动 4 个 I/O 工作线程,持续 20 秒。

QQ_1741954996680

QQ_1741955011844

3.对内存施加压力

QQ_1741955307244

QQ_1741955401197

4.对磁盘施加压力

QQ_1741955529454

QQ_1741955566036

三、实操一-cgroups信息查看

在 Linux 系统中,cgroups(Control Groups)用于限制、控制和隔离进程组的资源使用。cgroups 有两个主要版本:cgroups v1cgroups v2

1. 查看 cgroups 版本

方法 1:通过 /proc/filesystems

QQ_1741956247084

  • 如果输出中包含 cgroupcgroup2,说明系统同时支持 cgroups v1 和 vgroups v2。
  • 如果仅包含 cgroup2,说明系统仅支持 cgroups v2。
  • 如果仅包含 cgroup,说明系统仅支持 cgroups v1。

方法 2:通过 /sys/fs/cgroup

QQ_1741956505839

  • 如果目录下只有一个 cgroup.procs 文件和一些通用文件(如 cpu.max, memory.max),说明系统使用的是 cgroups v2。
  • 如果目录下有多个子目录(如 cpu, memory, blkio 等),说明系统使用的是 cgroups v1。

2. 查看 cgroups 子系统

方法 1:通过 /proc/cgroups

QQ_1741957004438

  • subsys_name: 子系统名称(如 cpu, memory 等)。
  • enabled: 是否启用(1 表示启用,0 表示禁用)。

方法 2:通过 lssubsys

安装 cgroup-tools 包后,可以使用以下命令查看子系统及其挂载点:

QQ_1741957095880

3. 查看 cgroups 挂载信息

方法 1:通过 mount 命令

QQ_1741957120310

方法 2:通过 /proc/mounts

QQ_1741957148758

4. 查看一个进程上的 cgroup 限制

每个进程都属于一个或多个 cgroups,其信息存储在 /proc/<PID>/cgroup 文件中。以下是具体操作步骤:

步骤 1:查看进程所属的 cgroup

cat /proc/<PID>/cgroup

QQ_1741957436289

字段解释

0

  • 表示 cgroup 的层级编号。
  • 在 cgroups v2 中,只有一个统一的层级(编号为 0),所有的子系统(如 CPU、内存、I/O 等)都挂载在这个层级上。

::

  • 分隔符,用于分隔层级编号和 cgroup 路径。
  • 在 cgroups v2 中,子系统名称不再显示,因为所有子系统都共享同一个层级。

/system.slice/mysql.service

  • 表示该进程所属的 cgroup 路径。
  • /system.slice/ 是 systemd 管理的服务的标准路径,表示这是一个系统服务。
  • mysql.service 是具体的服务名称,说明该进程是由 mysql.service 启动的。

进一步查看 mysql.service 的资源限制。以下是具体操作步骤:

1.查看 CPU 限制

wuxu@Nanyiroot:~$ cat /sys/fs/cgroup/system.slice/mysql.service/cpu.max
max 100000
  • 第一个值(max 或具体数字)表示 CPU 时间配额。
  • 第二个值(100000)表示 CPU 时间周期(单位为微秒)。
  • 如果第一个值是 max,表示没有限制。

2. 查看内存限制

wuxu@Nanyiroot:~$ cat /sys/fs/cgroup/system.slice/mysql.service/memory.max
max
  • 如果输出为2147483648,表示内存限制为 2 GB(单位为字节)。
  • 如果值为 max,表示没有限制。
  1. 查看当前内存使用量
wuxu@Nanyiroot:~$ cat /sys/fs/cgroup/system.slice/mysql.service/memory.current
52428800

表示当前内存使用量为 50 MB(单位为字节)

  1. 查看磁盘 I/O 限制
cat /sys/fs/cgroup/system.slice/mysql.service/io.max
8:0 rbps=1048576 wbps=524288 riops=max wiops=max
  • 8:0 表示设备号(主设备号:次设备号)。
  • rbpswbps 分别表示每秒读取和写入的最大字节数。
  • riopswiops 分别表示每秒读取和写入的最大 I/O 操作数。

总结

通过 cat /proc/994/cgroup,我们确认了进程 994mysqld)属于 cgroups v2,并且其资源管理由 /system.slice/mysql.service 控制。接下来,您可以根据需要查看具体的资源限制和使用情况,例如 CPU、内存、I/O 等。

如果您想进一步优化 MySQL 的性能,可以根据这些资源限制调整配置文件(如 my.cnf),或者通过 systemd 修改 mysql.service 的 cgroup 参数。

四、实操二(使用 cgroupsv2 对内存进行控制)

系统使用的是 cgroups v2,我们可以通过直接操作 /sys/fs/cgroup 文件系统来创建和管理 cgroups,并对内存进行控制。以下是详细的实操步骤:

目标

通过 cgroups v2 限制一个进程的内存使用量。例如,限制某个进程最多只能使用 100 MB 内存。

步骤

1. 创建一个新的 cgroup

在 cgroups v2 中,所有子系统的资源控制都集中在一个统一的挂载点下(通常是 /sys/fs/cgroup)。我们可以通过创建一个新的目录来定义一个新的 cgroup。

sudo mkdir /sys/fs/cgroup/my_memory_limit
  • my_memory_limit 是我们为这个 cgroup 定义的名称,您可以根据需要更改。

2. 设置内存限制

进入新创建的 cgroup 目录,并设置内存限制。

echo 100M | sudo tee /sys/fs/cgroup/my_memory_limit/memory.max
  • memory.max 文件用于设置内存限制。
  • 100M 表示限制为 100 MB。您也可以使用其他单位,如 50M(50 MB)、1G(1 GB)等。
  • 如果希望取消限制,可以将值设置为 max
    echo max | sudo tee /sys/fs/cgroup/my_memory_limit/memory.max
    

3. 启动一个受控进程

将一个进程加入到这个 cgroup 中,以使其受到内存限制。

方法 1:手动启动进程并添加到 cgroup

启动一个测试进程(例如 stress 工具):

stress --vm 1 --vm-bytes 200M --timeout 60s &
  • --vm 1:启动 1 个内存工作线程。
  • --vm-bytes 200M:每个线程尝试分配 200 MB 内存。
  • --timeout 60s:运行 60 秒后自动退出。

获取该进程的 PID:

pidof stress

将该进程的 PID 添加到 cgroup 的 cgroup.procs 文件中:

echo <PID> | sudo tee /sys/fs/cgroup/my_memory_limit/cgroup.procs
  • <PID> 是上一步获取的进程 ID。

方法 2:直接在 cgroup 中启动进程

您也可以直接在 cgroup 中启动进程,而不需要手动添加 PID:

sudo systemd-run --scope -p MemoryMax=100M stress --vm 1 --vm-bytes 200M --timeout 60s
  • --scope:创建一个新的 cgroup 范围。
  • -p MemoryMax=100M:设置内存限制为 100 MB。

4. 验证内存限制

观察进程是否受到内存限制的影响。

方法 1:查看 cgroup 的内存使用情况

cat /sys/fs/cgroup/my_memory_limit/memory.current
  • 输出的是当前内存使用量(单位为字节)。
  • 如果进程尝试分配超过 100 MB 的内存,它会被限制或被内核终止(OOM Killer)。

方法 2:检查系统日志

如果内存超出限制,内核可能会触发 OOM(Out of Memory)机制,终止进程。您可以通过以下命令查看系统日志:

dmesg | grep -i oom

5. 清理 cgroup

完成测试后,可以删除 cgroup 以释放资源。

sudo rmdir /sys/fs/cgroup/my_memory_limit

完整示例

以下是一个完整的示例流程:

# 1. 创建新的 cgroup
sudo mkdir /sys/fs/cgroup/my_memory_limit# 2. 设置内存限制为 100 MB
echo 100M | sudo tee /sys/fs/cgroup/my_memory_limit/memory.max# 3. 启动一个测试进程(尝试分配 200 MB 内存)
stress --vm 1 --vm-bytes 200M --timeout 60s &# 4. 获取进程 PID 并添加到 cgroup
pidof stress | sudo tee /sys/fs/cgroup/my_memory_limit/cgroup.procs# 5. 验证内存使用情况
cat /sys/fs/cgroup/my_memory_limit/memory.current# 6. 检查系统日志(可选)
dmesg | grep -i oom# 7. 清理 cgroup
sudo rmdir /sys/fs/cgroup/my_memory_limit

注意事项

OOM Killer

  • 如果进程尝试分配的内存超过限制,内核可能会触发 OOM Killer 终止进程。
  • 您可以通过以下命令禁用 OOM Killer(仅适用于测试环境):
    echo 1 | sudo tee /proc/sys/vm/overcommit_memory
    

权限问题

  • 操作 /sys/fs/cgroup 文件系统通常需要超级用户权限(sudo)。

工具安装

  • 如果需要使用 stress 工具,请确保已安装:
    sudo apt-get install stress  # Ubuntu/Debian
    sudo yum install stress      # CentOS/RHEL
    

总结

通过上述步骤,您可以使用 cgroups v2 对进程的内存使用进行限制。这种方法简单直观,适用于现代 Linux 系统。如果您有更多需求(如限制 CPU、I/O 等),可以参考类似的文件和目录结构进行配置。

五、实操三、使用 cgroups2 对 cpu 进行控制

在 Linux 系统中,cgroups v2 提供了对 CPU 资源的细粒度控制。通过 cgroups v2,您可以限制进程组的 CPU 使用时间、优先级等资源。以下是一个实操示例,展示如何使用 cgroups v2 对 CPU 进行控制。

目标

通过 cgroups v2 限制一个进程的 CPU 使用量。例如,限制某个进程最多只能使用 50% 的一个 CPU 核心。


步骤

1. 创建一个新的 cgroup

在 cgroups v2 中,所有子系统的资源控制都集中在一个统一的挂载点下(通常是 /sys/fs/cgroup)。我们可以通过创建一个新的目录来定义一个新的 cgroup。

sudo mkdir /sys/fs/cgroup/my_cpu_limit
  • my_cpu_limit 是我们为这个 cgroup 定义的名称,您可以根据需要更改。

2. 设置 CPU 限制

进入新创建的 cgroup 目录,并设置 CPU 使用限制。

方法 1:限制 CPU 时间配额

CPU 限制通过 cpu.max 文件进行配置。格式为:

<quota> <period>
  • <quota>: 表示允许的最大 CPU 时间(单位为微秒)。
  • <period>: 表示 CPU 时间周期(单位为微秒)。

例如,限制进程最多使用 50% 的一个 CPU 核心:

echo "50000 100000" | sudo tee /sys/fs/cgroup/my_cpu_limit/cpu.max
  • 50000: 在每个周期内,允许使用的最大 CPU 时间为 50,000 微秒(即 50 毫秒)。
  • 100000: 每个周期的时间长度为 100,000 微秒(即 100 毫秒)。
  • 结果是,进程最多只能使用 50% 的一个 CPU 核心。

方法 2:取消限制

如果希望取消 CPU 限制,可以将值设置为 max

echo "max 100000" | sudo tee /sys/fs/cgroup/my_cpu_limit/cpu.max

3. 启动一个受控进程

将一个进程加入到这个 cgroup 中,以使其受到 CPU 限制。

方法 1:手动启动进程并添加到 cgroup

启动一个测试进程(例如 stress 工具):

stress --cpu 2 --timeout 60s &
  • --cpu 2: 启动 2 个 CPU 工作线程。
  • --timeout 60s: 运行 60 秒后自动退出。

获取该进程的 PID:

pidof stress

将该进程的 PID 添加到 cgroup 的 cgroup.procs 文件中:

echo <PID> | sudo tee /sys/fs/cgroup/my_cpu_limit/cgroup.procs
  • <PID> 是上一步获取的进程 ID。

方法 2:直接在 cgroup 中启动进程

您也可以直接在 cgroup 中启动进程,而不需要手动添加 PID:

sudo systemd-run --scope -p CPUQuota=50% stress --cpu 2 --timeout 60s
  • --scope: 创建一个新的 cgroup 范围。
  • -p CPUQuota=50%: 设置 CPU 使用限制为 50%。

4. 验证 CPU 限制

观察进程是否受到 CPU 限制的影响。

方法 1:查看 CPU 使用情况

运行 tophtop 命令,查看 stress 进程的 CPU 使用率:

top
  • 如果限制生效,您会看到 stress 进程的 CPU 使用率接近 50%(假设系统只有一个 CPU 核心)。

方法 2:查看 cgroup 的 CPU 统计信息

cat /sys/fs/cgroup/my_cpu_limit/cpu.stat
  • 输出示例:
    usage_usec 123456789
    user_usec 67890123
    system_usec 56789012
    nr_periods 1234
    nr_throttled 12
    throttled_usec 123456
    
    • nr_periods: 调度周期的数量。
    • nr_throttled: 被限制的周期数量。
    • throttled_usec: 被限制的总时间(单位为微秒)。

5. 清理 cgroup

完成测试后,可以删除 cgroup 以释放资源。

sudo rmdir /sys/fs/cgroup/my_cpu_limit

完整示例

以下是一个完整的示例流程:

# 1. 创建新的 cgroup
sudo mkdir /sys/fs/cgroup/my_cpu_limit# 2. 设置 CPU 限制为 50%
echo "50000 100000" | sudo tee /sys/fs/cgroup/my_cpu_limit/cpu.max# 3. 启动一个测试进程(尝试占用 2 个 CPU 核心)
stress --cpu 2 --timeout 60s &# 4. 获取进程 PID 并添加到 cgroup
pidof stress | sudo tee /sys/fs/cgroup/my_cpu_limit/cgroup.procs# 5. 验证 CPU 使用情况
top# 6. 查看 cgroup 的 CPU 统计信息
cat /sys/fs/cgroup/my_cpu_limit/cpu.stat# 7. 清理 cgroup
sudo rmdir /sys/fs/cgroup/my_cpu_limit

总结

通过上述步骤,您可以使用 cgroups v2 对进程的 CPU 使用进行限制。这种方法简单直观,适用于现代 Linux 系统。如果您有更多需求(如限制内存、I/O 等),可以参考类似的文件和目录结构进行配置。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词