特性起源
Linux cgroups(控制组)最初由Google工程师Paul Menage在2006年提出,并在Linux内核的2.6.24版本中首次引入。自那时以来,cgroups一直是Linux内核的一部分,并在容器化技术等领域中发挥着至关重要的作用。随着时间的推移,cgroups功能不断得到改进和扩展,以满足对资源管理和隔离性能的不断增长的需求。
特性功能
Linux cgroups(控制组)是一种内核功能,用于限制、控制和监视一个或多个进程的资源,如CPU、内存、磁盘I/O等。Cgroups允许系统管理员将一组进程放入一个或多个cgroups中,并为每个cgroup分配资源限制。这样可以更好地管理系统资源,确保不同进程之间的资源隔离和分配。
Cgroups可以在Linux系统中用于多种用途,例如容器技术(比如Docker、Kubernetes)中就广泛应用了cgroups来对容器的资源进行限制和管理。Cgroups也可以用于其他需要对系统资源进行精细控制的场景。
资源子系统
Cgroups通过sys文件系统提供接口,即它是以文件和目录的方式组织在操作系统的/sys/fs/cgroup
路径下。在Ubuntu 18.04.6 LTS机器里,使用mount -t cgroup
展示:
$ mount -t cgroup
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpu,cpuacct)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)
cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids)
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/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)
...
输出结果就是文件系统目录,如果没有看到就需要你自己去挂载Cgroups,可以参考sudo apt install cgroupfs-mount
或者找寻其他方式。
在 /sys/fs/cgroup 下面有很多如 cpu、 memory、pids 这样的子目录,也叫子系统。
Cgroup通过配置文件限制进程可占用资源,通过查看 /sys/fs/cgroup目录,可以查看所支持的配置。
子系统资源限制/配置
在子系统对应的资源配置路径下,你可以看到该类资源具体可以被限制的方法。比如,对 CPU 子系统来说,我们可以看到如下几个配置文件,这个指令是:
$ ls /sys/fs/cgroup/cpu
cgroup.clone_children cpuacct.stat cpuacct.usage_all cpuacct.usage_percpu_sys cpuacct.usage_sys cpu.cfs_period_us cpu.shares notify_on_release
cgroup.procs cpuacct.usage cpuacct.usage_percpu cpuacct.usage_percpu_user cpuacct.usage_user cpu.cfs_quota_us cpu.stat tasks
如果之前有了解CPU资源限制,可以注意到在它的输出里有 cfs_period 和 cfs_quota 这两个熟悉的关键词。这两个参数需要组合使用,可以用来限制进程在长度为 cfs_period 的一段时间内,只能被分配到总量为 cfs_quota 的 CPU 时间。
怎么使用配置文件?
在对应的子系统下面创建一个目录,进入cd /sys/fs/cgroup/cpu
目录下:
$ mkdir ./container
$ ls container/
cgroup.clone_children cpuacct.stat cpuacct.usage_all cpuacct.usage_percpu_sys cpuacct.usage_sys cpu.cfs_period_us cpu.shares notify_on_release
cgroup.procs cpuacct.usage cpuacct.usage_percpu cpuacct.usage_percpu_user cpuacct.usage_user cpu.cfs_quota_us cpu.stat tasks
这个目录就称为一个“控制组”。你会发现,操作系统会在你新创建的 container 目录下,自动生成该子系统对应的资源限制文件。
现在,在后台执行如下脚本full_cpu.sh
或者直接执行,这段代码会启动一个进程,并跑满剩余的CPU到100%
$ cat full_cpu.sh | bash
#! /bin/bash
while : ;do : ; done &
$ top -p 29194
%Cpu(s):100.0 us, 0.0 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
29194 root 20 0 12892 232 0 R 93.4 0.0 0:16.26 bash full_cpu.sh
输出里可以看到目前%Cpu(s):100.0 us,已经被跑满了
此时,我们可以通过查看 container 目录下的文件,看到 container 控制组里的 CPU quota 还没有任何限制(即:-1),CPU period 则是默认的 100 ms(100000 us)
$ cat /sys/fs/cgroup/cpu/container/cpu.cfs_quota_us
-1
$ cat /sys/fs/cgroup/cpu/container/cpu.cfs_period_us
100000
接下来,我们可以通过修改这些文件的内容来设置限制。比如,向 container 组里的 cfs_quota 文件写入 20 ms(20000 us):
$ echo 20000 > /sys/fs/cgroup/cpu/container/cpu.cfs_quota_us
结合前面的介绍,这意味着在每 100 ms 的时间里,被该控制组限制的进程只能使用 20 ms 的 CPU 时间,也就是说这个进程只能使用到 20% 的 CPU 带宽。
接下来,我们把被限制的进程的 PID 写入 container 组里的 tasks 文件,上面的设置就会对该进程生效了:
$ echo 29194 > /sys/fs/cgroup/cpu/container/tasks
$ top -p 29194
%Cpu(s): 25.9 us, 5.8 sy, 0.0 ni, 67.6 id, 0.3 wa, 0.0 hi, 0.3 si, 0.0 st
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
29194 root 20 0 12892 232 0 R 19.9 0.0 13:30.51 bash full_cpu.sh
可以看到,该进程的 CPU 使用率立刻降/限制到了 20% 左右。
(提示:测试完毕,记得kill “29194”,tasks文件中进程也会随即清空)
除 CPU 子系统外,Cgroups 的每一个子系统都有其独有的资源限制能力,比如:
blkio,为块设备设定I/O 限制,一般用于磁盘等设备;
cpuset,为进程分配单独的 CPU 核和对应的内存节点;
memory,为进程设定内存使用的限制;
cpu:用于限制进程使用CPU的资源,如可用的CPU时间片和CPU份额;
cpuacct:用于追踪进程使用的CPU资源,可以记录CPU的使用情况;
devices:可以限制进程对设备的访问;
freezer:可以暂停和恢复cgroup中的进程;
net_cls:可以标记网络数据包,允许数据包根据cgroup进行分类处理。
这些Cgroups子系统都提供不同的资源控制和限制机制,使得管理员可以更加灵活地管理系统中进程的资源使用。
Docker控制组资源限制
Linux Cgroups 的设计还是比较易用的。简单粗暴地理解它就是一个子系统目录加上一组资源限制文件的组合。而对于 Docker 等 Linux 容器项目来说,它们只需要在每个子系统下面,为每个容器创建一个控制组(即创建一个新目录),然后在启动容器进程之后,把这个进程的 PID 填写到对应控制组的 tasks 文件中就可以了。
(现在,操作系统上有跑docker项目的可以看下对应子系统下是否有一个docker的控制组)
而至于在这些控制组下面的资源文件里填上什么值,就靠用户执行 docker run 时的参数指定了,比如这样一条命令:
$ docker run -it --cpu-period=100000 --cpu-quota=20000 centos:7 /bin/bash
在启动这个容器后,我们可以通过docker inspect <容器ID>
查看完整ID,在 Cgroups 文件系统 的 CPU 子系统中,“docker”这个控制组里的资源限制文件的内容来确认:文章来源:https://www.toymoban.com/news/detail-833150.html
$ cat /sys/fs/cgroup/cpu/docker/da3b6f68*/cpu.cfs_period_us
100000
$ cat /sys/fs/cgroup/cpu/docker/da3b6f68*/cpu.cfs_quota_us
20000
这就意味着这个 Docker 容器,只能使用到 20% 的 CPU 带宽。
(提示:停止run容器即关闭,rm容器则销毁,同时清理Cgroup子系统的控制组)文章来源地址https://www.toymoban.com/news/detail-833150.html
到了这里,关于Linux Cgroups进程资源限制管理 之 资源子系统限制/控制、Docker资源隔离与限制原理解读的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!