linux 内核资源配置--cgroups详解以及在docker中的应用

一、Cgroup 概述

1.1、cgroups 是什么

Linux cgroup (Control Groups)是 Linux 内核提供的一种机制,用于限制进程组使用的资源(如 CPU、内存、磁盘 I/O 等)。通过将进程组划分为层次结构,并将资源限制应用于不同层次的组,可以实现对系统资源的统一管理和限制。

cgroup 提供了一套 API,用于创建、管理和监控进程组。通过这些 API,可以将进程组划分为不同的层次结构,并为每个层次结构设置不同的资源限制。在实际使用中,可以使用 cgroup 来限制某些进程组的资源使用,以确保系统资源的公平分配和有效使用。

1.2、cgroup 四大功能

  • 资源限制(Resource Limiting):cgroup 可以限制进程组的资源使用,如 CPU、内存、磁盘 I/O 等,以保证系统的稳定性和可靠性。通过配置 cgroup,可以为每个进程组分配合适的资源,并防止某个进程组的资源占用过多影响其他进程组的正常运行。

  • 优先级管理(Priority Management):cgroup 可以控制进程组的运行优先级(CPU shares),以确保系统中每个进程组都有足够的 CPU 时间片,从而避免 CPU 资源的浪费和系统的不稳定性。

  • 资源统计(Accounting):cgroup 可以对进程组使用的资源进行统计,包括 CPU、内存、磁盘 I/O 等,从而帮助系统管理员了解系统资源的使用情况,并进行资源规划和优化。

  • 控制访问(Access Control):cgroup 可以对任务执行挂起,恢复等操作,从而实现对系统资源的统一管理和控制。通过配置 cgroup,可以限制某些用户或进程组的资源使用,保证系统资源的公平分配和有效使用。

1.3、cgroup 架构

在这里插入图片描述

1.3.1、css_set

css_set 是一个用于管理 cgroup 层次结构的结构体。它是一个代表 cgroup 集合的数据结构,用于存储每个 cgroup 在层次结构中的位置和控制器信息

css_set 保存了一个 cgroup 集合的状态,包括每个 cgroup 所属的父节点、子节点等信息。它将 cgroup 组织成层次结构,并按照不同的控制器对 cgroup 进行管理和限制资源使用。每个 css_set 都包含一个指向其父 css_set 的指针,这样就可以形成一个树状结构的 cgroup 层次结构。

css_set 中包含了一组指向 cgroup 控制器(如 CPU 权限、内存限制等)的指针,这些控制器用于限制进程组使用的资源。通过配置这些控制器,可以为每个 cgroup 分配不同的资源限制,从而确保系统的稳定性和可靠性。

在 cgroup 中,每个 cgroup 都关联着一个 css_set,它保存着 cgroup 的状态信息以及与其他 cgroup 之间的关系。因此,css_set 是 cgroup 中非常重要的一个数据结构,它负责管理和组织 cgroup 的层次结构,并提供了一组 API,允许用户对 cgroup 进行管理和监控,同时也管理和限制 cgroup 的资源使用。

1.3.2、subsys

在 cgroup 中,subsys(Subsystem)是指一个负责管理 cgroup 中某个资源的模块。每个 subsys 管理着 cgroup 中的一组资源,并提供了一组 API,用于配置和管理这些资源。

常见的 subsys 包括 CPU、内存、磁盘 I/O 等。每个 subsys 可以为 cgroup 分配不同的资源限制,从而限制进程组使用的资源。

在 cgroup 中,每个 cgroup 都可以使用一个或多个 subsys。每个 subsys 都具有以下功能:

  • 提供 API:subsys 提供了一组 API,用于配置和管理 cgroup 中的资源。这些 API 允许用户为每个 cgroup 分配不同的资源限制,从而限制进程组使用的资源。

  • 管理资源:subsys 管理 cgroup 中的资源,如 CPU、内存、磁盘 I/O 等。通过配置不同的 subsys,可以为每个 cgroup 分配不同的资源限制,从而确保系统的稳定性和可靠性。

  • 统计资源:subsys 可以统计 cgroup 中每个资源的使用情况,如 CPU 使用率、内存使用量等。这些统计数据可以帮助系统管理员更好地了解系统资源的使用情况,并进行资源规划和优化。

1.3.3、subsys 和css_set 的关系

subsys 是针对某个资源的管理模块,而 css_set 则是针对 cgroup 层次结构的管理结构。每个 cgroup 可以使用一个或多个 subsys。每个 css_set 中包含了一组指向 cgroup 控制器(即 subsys)的指针,这些控制器用于限制进程组使用的资源。通过配置这些控制器,可以为每个 cgroup 分配不同的资源限制,从而确保系统的稳定性和可靠性。

1.4、主要术语

  • 任务(Tasks):就是系统的一个进程。
  • 控制组(Control Group):一组按照某种标准划分的进程,比如官方文档中的Professor和Student,或是WWW和System之类的,其表示了某进程组。Cgroups中的资源控制都是以控制组为单位实现。一个进程可以加入到某个控制组。而资源的限制是定义在这个组上,就像上面示例中我用的 hello 一样。简单点说,cgroup的呈现就是一个目录带一系列的可配置文件。
  • 层级(Hierarchy):控制组可以组织成hierarchical的形式,即一棵控制组的树(目录结构)。控制组树上的子节点继承父结点的属性。简单点说,hierarchy就是在一个或多个子系统上的cgroups目录树。
  • 子系统(Subsystem):一个子系统就是一个资源控制器,比如CPU子系统就是控制CPU时间分配的一个控制器。子系统必须附加到一个层级上才能起作用,一个子系统附加到某个层级以后,这个层级上的所有控制族群都受到这个子系统的控制。Cgroup的子系统可以有很多,也在不断增加中。

二、Cgroups子系统

2.1、查看环境中的子系统

mount -t cgroup

$ mount -t cgroup
cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd)
cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event)
cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer)
cgroup on /sys/fs/cgroup/cpuset,cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset,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/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb)
cgroup on /sys/fs/cgroup/rdma type cgroup (rw,nosuid,nodev,noexec,relatime,rdma)
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/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)
其中:
/sys/fs/cgroup/systemd  # 是子系统
type cgroup  表示文件系统类型。# cgroup就是一个虚拟文件系统
rw,nosuid,nodev,noexec,relatime # 表示文件系统的挂载选项

挂载选项解释

挂载选项 解释
rw 表示文件系统可读可写
ro 表示文件系统只读
auto 表示当系统引导时自动挂载
noauto 表示不自动挂载
exec 表示允许在文件系统上执行二进制文件
noexec 表示不允许在文件系统上执行二进制文件
sync 表示文件系统数据同步写入到磁盘
async 表示文件系统数据异步写入到磁盘
atime 表示访问时间要更新
noatime 表示访问时间不更新
diratime 表示目录访问时间要更新
nodiratime 表示目录访问时间不更新
dev 表示允许在文件系统上创建设备
nodev 表示不允许在文件系统上创建设备
suid 表示允许在文件系统上执行SUID程序
nosuid 表示不允许在文件系统上执行SUID程序
user 表示允许普通用户挂载文件系统
nouser 表示不允许普通用户挂载文件系统
defaults 表示使用默认的挂载选项
relatime 相对访问时间。它与atime选项类似,但是只在文件被访问时更新访问时间,或者在文件系统被挂载时更新整个文件系统的访问时间。与atime选项相比,relatime选项能够减少对文件系统的写入操作,因此对性能影响较小
xattr 扩展属性。它允许为文件和目录添加额外的元数据,例如权限、所有者、创建时间等
release_agent release agent机制提供了一种方式,可以在文件的最后一个引用被释放时执行指定的脚本或命令。它通常用于在文件系统被卸载之前执行某些操作,例如清理缓存、备份数据等
perf_event 该选项用于启用感知性能事件(performance events)子系统,以便在文件系统中追踪和分析系统性能

lssubsys -m

# 要使用lssubsys 命令,需要安装包
$ yum install libcgroup-tools
$ lssubsys -m
cpuset,cpu,cpuacct /sys/fs/cgroup/cpuset,cpu,cpuacct
blkio /sys/fs/cgroup/blkio
memory /sys/fs/cgroup/memory
devices /sys/fs/cgroup/devices
freezer /sys/fs/cgroup/freezer
net_cls,net_prio /sys/fs/cgroup/net_cls,net_prio
perf_event /sys/fs/cgroup/perf_event
hugetlb /sys/fs/cgroup/hugetlb
pids /sys/fs/cgroup/pids
rdma /sys/fs/cgroup/rdma

cat /proc/cgroups

$ cat /proc/cgroups
#subsys_name	hierarchy	num_cgroups	enabled
cpuset	6	124	1
cpu	6	124	1
cpuacct	6	124	1
blkio	7	113	1
memory	9	185	1
devices	8	111	1
freezer	5	83	1
net_cls	4	83	1
perf_event	10	83	1
net_prio	4	83	1
hugetlb	11	83	1
pids	2	111	1
rdma	3	2	1

cat /proc/[pid]/cgroup 查看进程所属的 cgroups

$ cat /proc/1/cgroup 
11:hugetlb:/
10:perf_event:/
9:memory:/
8:devices:/
7:blkio:/
6:cpuset,cpu,cpuacct:/
5:freezer:/
4:net_cls,net_prio:/
3:rdma:/
2:pids:/
1:name=systemd:/

$ cat /proc/84083/cgroup 
11:hugetlb:/
10:perf_event:/
9:memory:/system.slice/docker.service
8:devices:/system.slice/docker.service
7:blkio:/system.slice/docker.service
6:cpuset,cpu,cpuacct:/
5:freezer:/
4:net_cls,net_prio:/
3:rdma:/
2:pids:/system.slice/docker.service
1:name=systemd:/system.slice/docker.service

2.2、子系统名称及其作用

名称 作用
blkio 限制进程组对块设备的访问,确保磁盘 I/O 的公平使用和稳定性
cpu 使用调度程序控制任务对CPU的使用
cpuacct 自动生成cgroups中任务对cpu资源使用情况报告
cpuset 为 cgroup 中的任务分配独立 CPU(在多核系统)和内存节点
devices 允许或者拒绝 cgroup 中的任务访问设备
freezer 挂起或者恢复 cgroup 中的任务
memory 设定 cgroup 中任务使用的内存限制,并自动生成由那些任务使用的内存资源报告
net_cls 使用等级识别符(classid)标记网络数据包,可允许 Linux 流量控制程序(tc)识别从具体 cgroup 中生成的数据包,配合 tc(traffic controller)限制网络带宽
net_prio 设置进程的网络流量优先级
hugetlb 限制 HugeTLB 的使用
perf_event 允许 Perf 工具基于 Cgroup 分组做性能检测
rdma 将 RDMA 资源(如 HCA、QPs、CQs 等)分配给 cgroup,并限制 cgroup 使用这些资源的数量,RDMA 设备通常包括网卡、主机适配器和交换机等
pids 限制 cgroup 中能够运行的进程数量
ns 允许用户将不同的命名空间分配给 cgroup,并限制 cgroup 中的进程仅能访问特定的命名空间

2.3、各个子系统主要配置

2.3.1、blkio配置

blkio 子系统是 cgroup 提供的一种用于控制块设备(如硬盘、SSD 等)输入/输出(I/O)带宽的子系统。通过 blkio 子系统,用户可以为每个 cgroup 分配不同的磁盘 I/O 带宽限制,并确保不同进程组之间的磁盘 I/O 不会互相干扰和冲突。

下面是 blkio 子系统的一些常用配置(如下mygroup为示例,具体根据环境中确定):

blkio.weight:用于设置 cgroup 的 I/O 权重,它是一个相对值,默认值为 500。较高的权重值表示更高的 I/O 优先级。

# 设置 cgroup 的 I/O 权重为 1000
echo 1000 > /sys/fs/cgroup/blkio/mygroup/blkio.weight

blkio.weight_device:用于设置某个块设备的 I/O 权重,例如:

# 为设备 /dev/sda 设置 I/O 权重为 1000
echo "1000:253:*" > /sys/fs/cgroup/blkio/mygroup/blkio.weight_device

blkio.throttle.read_bps_deviceblkio.throttle.write_bps_device:用于限制读和写操作的 I/O 带宽,例如:

# 限制设备 /dev/sda 的读操作带宽为 10 MB/s
echo "10:253:rw" > /sys/fs/cgroup/blkio/mygroup/blkio.throttle.read_bps_device

# 限制设备 /dev/sda 的写操作带宽为 5 MB/s
echo "5:253:rw" > /sys/fs/cgroup/blkio/mygroup/blkio.throttle.write_bps_device

blkio.throttle.read_iops_deviceblkio.throttle.write_iops_device:用于限制读和写操作的 I/O 操作数,例如:

# 限制设备 /dev/sda 的读操作 IOPS 为 1000
echo "1000:253:rw" > /sys/fs/cgroup/blkio/mygroup/blkio.throttle.read_iops_device

# 限制设备 /dev/sda 的写操作 IOPS 为 500
echo "500:253:rw" > /sys/fs/cgroup/blkio/mygroup/blkio.throttle.write_iops_device

2.3.2、cpu配置

cpu 子系统是 cgroup 提供的一种用于控制 CPU 使用率的子系统。通过 cpu 子系统,用户可以限制 cgroup 中进程的 CPU 使用率,并确保不同进程组之间的 CPU 使用率不会互相干扰和冲突。

以下是 cpu 子系统的一些常用配置:

cpu.cfs_quota_uscpu.cfs_period_us:用于限制 cgroup 中的进程使用 CPU 时间的比例。其中 cpu.cfs_quota_us 表示时间配额,单位为微秒,cpu.cfs_period_us 表示时间周期,单位为微秒。例如:

# 限制 cgroup 中的进程使用 50% 的 CPU 时间
echo 50000 > /sys/fs/cgroup/cpu/mygroup/cpu.cfs_quota_us
echo 100000 > /sys/fs/cgroup/cpu/mygroup/cpu.cfs_period_us

这个配置将 cgroup 中的进程 CPU 使用率限制为 50%。如果希望取消限制,可以将 cpu.cfs_quota_us 的值设置为 -1。

cpu.shares:用于设置 cgroup 中进程的 CPU 使用权重,它是一个相对值,默认值为 1024。较高的权重值表示更高的 CPU 使用优先级。例如:

# 设置 cgroup 的 CPU 使用权重为 2048
echo 2048 > /sys/fs/cgroup/cpu/mygroup/cpu.shares

cpu.rt_period_uscpu.rt_runtime_us:用于限制实时进程在 cgroup 中的 CPU 使用时间。其中 cpu.rt_period_us 表示时间周期,单位为微秒,cpu.rt_runtime_us 表示时间配额,单位为微秒。例如:

# 限制实时进程在 cgroup 中使用 10ms 的 CPU 时间
echo 10000 > /sys/fs/cgroup/cpu/mygroup/cpu.rt_period_us
echo 1000 > /sys/fs/cgroup/cpu/mygroup/cpu.rt_runtime_us

2.3.3、cpuacct 配置

cpuacct 子系统是 cgroup 提供的一种用于统计 cgroup 中进程 CPU 使用情况的子系统。以下是 cpuacct 子系统的一些常用参数:

cpuacct.usage:用于获取 cgroup 中所有进程的 CPU 使用时间,以纳秒为单位。

# 获取 cgroup 中所有进程的 CPU 使用时间
cat /sys/fs/cgroup/cpuacct/mygroup/cpuacct.usage

cpuacct.usage_percpu:用于获取 cgroup 中每个 CPU 核心的 CPU 使用时间,以纳秒为单位。

# 获取 cgroup 中每个 CPU 核心的 CPU 使用时间
cat /sys/fs/cgroup/cpuacct/mygroup/cpuacct.usage_percpu

cpuacct.stat:用于获取 cgroup 中进程的 CPU 使用时间和资源消耗情况的统计信息,包括用户态时间、内核态时间、等待时间等。

# 获取 cgroup 中进程的 CPU 使用时间和资源消耗情况的统计信息
cat /sys/fs/cgroup/cpuacct/mygroup/cpuacct.stat

这些参数可以根据实际需求进行调整和修改。需要注意的是,cpuacct 子系统只用于统计进程的 CPU 使用情况,不限制进程的 CPU 使用率。如果需要限制进程的 CPU 使用率,应该使用 cpu 子系统

2.3.4、cpuset 配置

cpuset 子系统是 cgroup 提供的一种用于控制进程 CPU 核心和内存使用的子系统。通过 cpuset 子系统,用户可以将进程限制在特定的 CPU 核心或者 NUMA 节点上,以及限制进程的内存使用。

以下是 cpuset 子系统的一些常用配置:

cpuset.cpus:用于设置 cgroup 中允许使用的 CPU 核心。该参数可以使用类似 0-3,6,8-10 的格式,表示允许使用编号为 0-3、6、8-10 的 CPU 核心。例如:

# 设置 cgroup 中允许使用的 CPU 核心为 0-3 和 6
echo "0-3,6" > /sys/fs/cgroup/cpuset/mygroup/cpuset.cpus

cpuset.mems:用于设置 cgroup 中允许使用的 NUMA 节点。该参数可以使用类似 0,1 的格式,表示允许使用编号为 0 和 1 的 NUMA 节点。例如:

# 设置 cgroup 中允许使用的 NUMA 节点为 0 和 1
echo "0,1" > /sys/fs/cgroup/cpuset/mygroup/cpuset.mems

cpuset.memory_migrate:用于设置是否允许 cgroup 中的进程迁移内存。可以将该参数设置为 1,表示允许内存迁移,或者将其设置为 0,表示禁止内存迁移。例如:

# 允许 cgroup 中的进程迁移内存
echo 1 > /sys/fs/cgroup/cpuset/mygroup/cpuset.memory_migrate

2.3.5、devices 配置

devices 子系统是 cgroup 提供的一种用于控制进程对系统设备访问权限的子系统。通过 devices 子系统,用户可以限制 cgroup 中进程对指定设备的访问权限,防止恶意程序或者误操作对系统设备造成损害。

devices 子系统的配置涉及以下三个参数:

devices.allow:用于设置允许访问的设备列表。该参数可以使用类似 “c 1:3 rwm” 的格式,其中 “c” 表示字符设备,“1:3” 表示设备的主次编号,“rwm” 表示允许的访问权限(读、写、执行)。例如:

# 允许 cgroup 中的进程访问 /dev/null 和 /dev/zero 设备
echo "c 1:3 rwm, c 1:5 rwm" > /sys/fs/cgroup/devices/mygroup/devices.allow

上面的示例中,设置了允许 cgroup 中的进程访问 /dev/null/dev/zero 设备,并且设置了读、写、执行权限。

devices.deny:用于设置禁止访问的设备列表。该参数可以使用类似 “c 1:3 rwm” 的格式,其中 “c” 表示字符设备,“1:3” 表示设备的主次编号,“rwm” 表示禁止的访问权限(读、写、执行)。例如:

# 禁止 cgroup 中的进程访问 /dev/pts 和 /dev/tty 设备
echo "c 5:2 rwm, c 4:0 rwm" > /sys/fs/cgroup/devices/mygroup/devices.deny

上面的示例中,设置了禁止 cgroup 中的进程访问 /dev/pts/dev/tty 设备,并且设置了读、写、执行权限。

devices.list:用于获取当前 cgroup 中允许访问的设备列表。例如:

# 获取当前 cgroup 中允许访问的设备列表
cat /sys/fs/cgroup/devices/mygroup/devices.list

2.3.6、freezer 配置

freezer 子系统是 cgroup 提供的一种用于暂停和恢复进程的子系统。通过 freezer 子系统,用户可以暂停 cgroup 中的所有进程或者某个进程,以便进行调试、备份或者迁移等操作。

以下是 freezer 子系统的一些常用配置:

freezer.state:用于设置或获取 cgroup 的状态。该参数可以设置为以下几个值:

FROZEN:冻结 cgroup 中的所有进程,包括子 cgroup 中的进程。
THAWED:解冻 cgroup 中的所有进程,包括子 cgroup 中的进程。
FREEZING:正在冻结 cgroup 中的进程。
FROZEN:正在解冻 cgroup 中的进程。
UNKNOWN:cgroup 的状态未知。

例如:

# 冻结 cgroup 中的所有进程
echo "FROZEN" > /sys/fs/cgroup/freezer/mygroup/freezer.state

freezer.parent_freezing:用于设置子 cgroup 是否继承父 cgroup 的冻结状态。该参数可以设置为 0 或 1,分别表示不继承和继承。例如:

# 子 cgroup 不继承父 cgroup 的冻结状态
echo 0 > /sys/fs/cgroup/freezer/mygroup/freezer.parent_freezing

freezer.self_freezing:用于设置进程退出时是否将自己冻结。该参数可以设置为 0 或 1,分别表示不冻结和冻结。例如:

# 进程退出时将自己冻结
echo 1 > /sys/fs/cgroup/freezer/mygroup/freezer.self_freezing

2.3.7、memory 配置

memory 子系统是 cgroup 提供的一种用于控制进程内存使用的子系统。通过 memory 子系统,用户可以限制 cgroup 中进程的内存使用,防止进程耗尽系统内存,导致系统崩溃或变得不可用。

以下是 memory 子系统的一些常用配置:

memory.limit_in_bytes:用于设置 cgroup 中进程的内存限制。该参数可以设置一个整数值,表示允许使用的最大内存量(以字节为单位)。例如:

# 设置 cgroup 中进程的内存限制为 1 GB
echo "1073741824" > /sys/fs/cgroup/memory/mygroup/memory.limit_in_bytes

memory.soft_limit_in_bytes:用于设置 cgroup 中进程的软内存限制。软限制是当系统内存不足时,内核会尝试回收该 cgroup 中进程的内存。该参数可以设置一个整数值,表示软限制的最大内存量(以字节为单位)。例如:

# 设置 cgroup 中进程的软内存限制为 800 MB
echo "838860800" > /sys/fs/cgroup/memory/mygroup/memory.soft_limit_in_bytes

memory.swappiness:用于设置 cgroup 中进程的交换空间使用比例。该参数可以设置一个整数值,表示在物理内存不足时,内核将会将多少进程内存移动到交换空间中。例如:

# 设置 cgroup 中进程的交换空间使用比例为 50%
echo "50" > /sys/fs/cgroup/memory/mygroup/memory.swappiness

memory.kmem.limit_in_bytes:用于设置 cgroup 中进程使用内核内存的限制。该参数可以设置一个整数值,表示 cgroup 中进程允许使用的内核内存的最大量(以字节为单位)。例如:

# 设置 cgroup 中进程使用内核内存的限制为 100 MB
echo "104857600" > /sys/fs/cgroup/memory/mygroup/memory.kmem.limit_in_bytes

2.3.8、net_cls 配置

net_cls 子系统是 cgroup 提供的一种用于控制网络流量的子系统。通过 net_cls 子系统,用户可以将 cgroup 中的网络流量标记为特定的类别,以便网络设备或者 QoS(Quality of Service)系统根据标记来进行流量控制。

以下是 net_cls 子系统的一些常用配置:

net_cls.classid:用于设置 cgroup 中网络流量的分类标识符。该参数可以设置一个整数值,表示网络流量的分类标识符。例如:

# 设置 cgroup 中网络流量的分类标识符为 0x10001
echo "0x10001" > /sys/fs/cgroup/net_cls/mygroup/net_cls.classid

/sys/class/net/<interface>/queues/tx-<queue>/xps_cpus:用于设置网络接口队列中流量的处理器亲和性。该参数可以设置一个 CPU 核心的位图,表示哪些 CPU 核心可以处理该队列中的网络流量。例如:

# 设置 eth0 接口队列 0 中网络流量的处理器亲和性为 CPU 0 和 CPU 1
echo "3" > /sys/class/net/eth0/queues/tx-0/xps_cpus

2.3.9、net_prio 配置

net_prio 子系统是 cgroup 提供的一种用于控制网络流量优先级的子系统。通过 net_prio 子系统,用户可以将 cgroup 中的网络流量设置为不同的优先级,以便优化网络性能和资源利用。

以下是 net_prio 子系统的一些常用配置:

net_prio.ifpriomap:用于设置网络接口的优先级映射。该参数可以设置一个字符串,表示网络接口和优先级之间的映射关系。例如:

# 设置 eth0 接口的优先级为 1,eth1 接口的优先级为 2
echo "eth0 1, eth1 2" > /sys/fs/cgroup/net_prio/mygroup/net_prio.ifpriomap

net_prio.prioidx:用于设置优先级索引。该参数可以设置一个整数值,表示 cgroup 中网络流量的优先级。例如:

# 设置 cgroup 中网络流量的优先级为 1
echo "1" > /sys/fs/cgroup/net_prio/mygroup/net_prio.prioidx

net_prio.default:用于设置默认的网络流量优先级。该参数可以设置一个整数值,表示当流量没有被映射到具体接口时的默认优先级。例如:

# 设置默认的网络流量优先级为 2
echo "2" > /sys/fs/cgroup/net_prio/mygroup/net_prio.default

2.3.10、hugetlb 配置

hugetlb 子系统是 cgroup 提供的一种用于控制大页面内存(Huge Page)使用的子系统。大页面内存是一种更大的内存页,可以提高内存访问效率和性能。通过 hugetlb 子系统,用户可以限制 cgroup 中进程使用的大页面内存的数量和大小。

以下是 hugetlb 子系统的一些常用配置:

hugetlb.<pagesize>.limit_in_bytes:用于设置 cgroup 中进程使用指定大小的大页面内存的限制。该参数可以设置一个整数值,表示 cgroup 中进程允许使用的指定大小的大页面内存的最大量(以字节为单位)。其中 <pagesize> 表示大页面的大小,例如 hugetlb.2MB.limit_in_bytes 表示 2MB 大页面内存的限制。例如:

# 设置 cgroup 中进程使用 2MB 大页面内存的限制为 1 GB
echo "1073741824" > /sys/fs/cgroup/hugetlb/mygroup/hugetlb.2MB.limit_in_bytes

hugetlb.<pagesize>.max_usage_in_bytes:用于设置 cgroup 中进程使用指定大小的大页面内存的最大使用量。该参数可以设置一个整数值,表示 cgroup 中进程使用指定大小的大页面内存的最大使用量(以字节为单位)。例如:

# 设置 cgroup 中进程使用 2MB 大页面内存的最大使用量为 512 MB
echo "536870912" > /sys/fs/cgroup/hugetlb/mygroup/hugetlb.2MB.max_usage_in_bytes

hugetlb.<pagesize>.current_usage_in_bytes:用于获取 cgroup 中进程使用指定大小的大页面内存的当前使用量。该参数可以查询 cgroup 中进程使用指定大小的大页面内存的当前使用量(以字节为单位)。例如:

# 查询 cgroup 中进程使用 2MB 大页面内存的当前使用量
cat /sys/fs/cgroup/hugetlb/mygroup/hugetlb.2MB.current_usage_in_bytes

2.3.11、perf_event 配置

perf_event 子系统是 cgroup 提供的一种用于控制进程性能计数器(Performance Counter)的子系统。通过 perf_event 子系统,用户可以对 cgroup 中的进程进行性能分析和调优。

以下是 perf_event 子系统的一些常用配置:

perf_event.<event_name>.enable:用于启用或禁用指定的性能计数器事件。该参数可以设置一个整数值,表示是否启用指定的性能计数器事件(1 表示启用,0 表示禁用)。其中 <event_name> 表示性能计数器事件的名称,例如 cycles 表示 CPU 周期计数器事件。例如:

# 启用 cgroup 中进程的 CPU 周期计数器事件
echo "1" > /sys/fs/cgroup/perf_event/mygroup/perf_event.cycles.enable

perf_event.<event_name>.config:用于设置指定的性能计数器事件的配置参数。该参数可以设置一个整数值,表示性能计数器事件的配置参数。例如:

# 设置 cgroup 中进程的 CPU 周期计数器事件的配置参数为 0x412e
echo "0x412e" > /sys/fs/cgroup/perf_event/mygroup/perf_event.cycles.config

perf_event.<event_name>.count:用于获取 cgroup 中进程指定性能计数器事件的计数值。该参数可以查询 cgroup 中进程指定性能计数器事件的计数值。例如:

# 查询 cgroup 中进程 CPU 周期计数器事件的计数值
cat /sys/fs/cgroup/perf_event/mygroup/perf_event.cycles.count

2.3.12、rdma配置

rdma 子系统是 cgroup 提供的一种用于控制 RDMA(Remote Direct Memory Access)资源使用的子系统。RDMA 是一种高性能网络传输技术,可以实现低延迟、高吞吐量的数据传输。通过 rdma 子系统,用户可以限制 cgroup 中进程使用 RDMA 资源的数量和大小。

以下是 rdma 子系统的一些常用配置:

rdma.max_qp:用于设置 cgroup 中进程在每个 RDMA 设备上可以创建的最大 QP(Queue Pair)数。该参数可以设置一个整数值,表示 cgroup 中进程在每个 RDMA 设备上可以创建的最大 QP 数。例如:

# 设置 cgroup 中进程在每个 RDMA 设备上可以创建的最大 QP 数为 128
echo "128" > /sys/fs/cgroup/rdma/mygroup/rdma.max_qp

rdma.max_mr:用于设置 cgroup 中进程在每个 RDMA 设备上可以注册的最大 MR(Memory Region)数。该参数可以设置一个整数值,表示 cgroup 中进程在每个 RDMA 设备上可以注册的最大 MR 数。例如:

# 设置 cgroup 中进程在每个 RDMA 设备上可以注册的最大 MR 数为 256
echo "256" > /sys/fs/cgroup/rdma/mygroup/rdma.max_mr

rdma.max_pd:用于设置 cgroup 中进程在每个 RDMA 设备上可以创建的最大 PD(Protection Domain)数。该参数可以设置一个整数值,表示 cgroup 中进程在每个 RDMA 设备上可以创建的最大 PD 数。例如:

# 设置 cgroup 中进程在每个 RDMA 设备上可以创建的最大 PD 数为 16
echo "16" > /sys/fs/cgroup/rdma/mygroup/rdma.max_pd

rdma.max_cq:用于设置 cgroup 中进程在每个 RDMA 设备上可以创建的最大 CQ(Completion Queue)数。该参数可以设置一个整数值,表示 cgroup 中进程在每个 RDMA 设备上可以创建的最大 CQ 数。例如:

# 设置 cgroup 中进程在每个 RDMA 设备上可以创建的最大 CQ 数为 64
echo "64" > /sys/fs/cgroup/rdma/mygroup/rdma.max_cq

2.3.13、pids 配置

pids 子系统是 cgroup 提供的一种用于控制进程数量的子系统。通过 pids 子系统,用户可以控制 cgroup 中运行的进程数量,以避免系统过载或进程耗尽系统资源。

以下是 pids 子系统的一些常用配置:

pids.max:用于限制 cgroup 中进程的最大数量。该参数可以设置一个整数值,表示 cgroup 中允许运行的最大进程数量。例如:

# 设置 cgroup 中允许运行的最大进程数量为 1000
echo "1000" > /sys/fs/cgroup/pids/mygroup/pids.max

pids.current:用于查询 cgroup 中当前运行的进程数量。该参数可以查询 cgroup 中当前运行的进程数量。例如:

# 查询 cgroup 中当前运行的进程数量
cat /sys/fs/cgroup/pids/mygroup/pids.current

pids.max_depth:用于限制 cgroup 的层级深度。该参数可以设置一个整数值,表示 cgroup 可以创建的最大层级深度。例如:

# 设置 cgroup 可以创建的最大层级深度为 3
echo "3" > /sys/fs/cgroup/pids/mygroup/pids.max_depth

2.3.14、ns 配置

ns 子系统是 cgroup 提供的一种用于控制 Linux 命名空间(Namespace)的子系统。通过 ns 子系统,用户可以限制 cgroup 中进程使用特定命名空间的数量和类型。

以下是 ns 子系统的一些常用配置:

ns.<namespace_type>.max:用于限制 cgroup 中进程使用特定类型命名空间的数量。该参数可以设置一个整数值,表示 cgroup 中允许运行的最大特定类型命名空间的数量。其中 <namespace_type> 表示命名空间的类型,例如 pid 表示进程 ID 命名空间。例如:

# 设置 cgroup 中允许运行的最大 PID 命名空间数量为 5
echo "5" > /sys/fs/cgroup/ns/mygroup/ns.pid.max

ns.<namespace_type>.current:用于查询 cgroup 中当前运行特定类型命名空间的进程数量。该参数可以查询 cgroup 中当前运行特定类型命名空间的进程数量。例如:

# 查询 cgroup 中当前运行的 PID 命名空间的进程数量
cat /sys/fs/cgroup/ns/mygroup/ns.pid.current

ns.current:用于查询 cgroup 中进程使用的所有命名空间的数量。该参数可以查询 cgroup 中进程使用的所有命名空间的数量。例如:

# 查询 cgroup 中进程使用的所有命名空间的数量
cat /sys/fs/cgroup/ns/mygroup/ns.current

2.4、创建子系统

在 Linux 中,可以使用 cgroupfs 文件系统来创建和管理 Cgroups 子系统。cgroupfs 文件系统通常挂载在 /sys/fs/cgroup 目录下,您可以在该目录下创建子目录,来创建 Cgroups 子系统。

2.4.1、创建子目录

/sys/fs/cgroup 目录下创建一个子目录,用于存放控制组。例如,要创建一个 CPU 控制组,可以执行以下命令:

 mkdir /sys/fs/cgroup/cpu/mygroup

该命令会在 /sys/fs/cgroup/cpu 目录下创建一个名为 mygroup 的子目录,用于存放 CPU 控制组。

创建后目录中自动生成以下文件:

cgroup.clone_children         cpuacct.usage              cpu.cfs_init_buffer_us  cpuset.group_balancer            cpuset.soft_cpus
cgroup.procs                  cpuacct.usage_all          cpu.cfs_period_us       cpuset.mem_exclusive             cpu.shares
cgroup.rich_container_source  cpuacct.usage_percpu       cpu.cfs_quota_us        cpuset.mem_hardwall              cpu.stat
cpuacct.block_latency         cpuacct.usage_percpu_sys   cpu.identity            cpuset.memory_migrate            notify_on_release
cpuacct.cgroup_wait_latency   cpuacct.usage_percpu_user  cpu.rt_period_us        cpuset.memory_pressure           pool_size
cpuacct.enable_sli            cpuacct.usage_sys          cpu.rt_runtime_us       cpuset.memory_spread_page        tasks
cpuacct.ioblock_latency       cpuacct.usage_user         cpuset.cpu_exclusive    cpuset.memory_spread_slab
cpuacct.proc_stat             cpuacct.wait_latency       cpuset.cpus             cpuset.mems
cpuacct.sched_cfs_statistics  cpu.bvt_warp_ns            cpuset.effective_cpus   cpuset.sched_load_balance
cpuacct.stat                  cpu.cfs_burst_us           cpuset.effective_mems   cpuset.sched_relax_domain_level

除了每个cgroup独特的资源控制文件,还有一些通用的文件。

  • tasks:当前 cgroup 包含的任务(task)pid 列表,把某个进程的 pid 添加到这个文件中就等于把进程交由到该cgroup控制。
  • cgroup.procs:使用逻辑和tasks相同。
  • notify_on_release:0或者1,该文件的内容为1时,当cgroup退出时(不再包含任何进程和子cgroup),将调用release_agent里面配置的命令。
  • release_agent:需要执行的命令。

另外在docker中无法创建,报错:

$ mkdir /sys/fs/cgroup/cpu/mygroup
mkdir: cannot create directory ‘/sys/fs/cgroup/cpu/mygroup’: Read-only file system

2.4.2、指定控制组参数

在创建控制组的子目录下,可以创建一些文件来指定控制组的参数,例如 CPU 使用率、内存限制等。例如,要限制 mygroup 控制组中的进程使用 50% 的 CPU,可以执行以下命令:

echo 50000 > /sys/fs/cgroup/cpu/mygroup/cpu.cfs_quota_us
echo 100000 > /sys/fs/cgroup/cpu/mygroup/cpu.cfs_period_us

该命令会将 mygroup 控制组中的进程限制为最多占用 50% 的 CPU 使用率。

2.4.3、将进程加入控制组

将需要受到控制的进程加入到相应的控制组中。例如,要将进程 PID 为 12345 的进程加入到 mygroup 控制组中,可以执行以下命令:

sudo echo 12345 > /sys/fs/cgroup/cpu/mygroup/tasks

一次只能添加一个任务进程ID。如果有多个任务ID,需分多次添加。

cgroup各个子系统初始化时,默认把系统中所有进程都纳管了,将一个进程的pid添加到新建的cgroup tasks文件的操作,实际是从一个cgroup移入到另一个cgroup的操作。所以要将进程从某个cgroup中删除,只能通过将其移出到另一个cgroup来实现,或者将进程终止

2.4.4、删除cgroup 子系统

删除子资源,就是删除对应的目录:

# 删除失败
$ rm -rf /sys/fs/cgroup/cpu/mygroup/
rm: cannot remove ‘mygroup/cpu.cfs_burst_us’: Operation not permitted
rm: cannot remove ‘mygroup/cgroup.procs’: Operation not permitted
rm: cannot remove ‘mygroup/cpu.cfs_period_us’: Operation not permitted
rm: cannot remove ‘mygroup/cpuset.memory_pressure’: Operation not permitted
rm: cannot remove ‘mygroup/cpu.identity’: Operation not permitted
rm: cannot remove ‘mygroup/cpu.stat’: Operation not permitted
rm: cannot remove ‘mygroup/cpuset.memory_migrate’: Operation not permitted
rm: cannot remove ‘mygroup/cpuacct.cgroup_wait_latency’: Operation not permitted
rm: cannot remove ‘mygroup/cpuacct.usage_percpu_sys’: Operation not permitted
...

# 删除成功
$ rmdir /sys/fs/cgroup/cpu/mygroup/

# 验证删除干净
$ find /sys/fs/cgroup  -name mygroup

三、层级(Hierarchy

Hierarchy 是指 Cgroups 控制组的层级结构,是一种树形结构,由多个 Cgroups 控制组组成。每个层级都有一个根控制组,可以包含多个子控制组,每个子控制组又可以包含多个子子控制组,以此类推,形成了一棵树形结构。

由于 Cgroups 控制组可以包含其他子控制组,因此 Cgroups 控制组的层级结构可以表现为进程间的层级关系。例如,一个父进程可以创建多个子进程,每个子进程可以绑定到不同的 Cgroups 控制组中,形成一个层级结构。

每个 Cgroups 控制组都有自己的资源限制和控制参数,例如 CPU 使用率、内存限制、IO 限制等。这些资源限制和控制参数可以在 Cgroups 控制组层级中进行继承和覆盖。当一个进程被绑定到一个 Cgroups 控制组中时,它会受到该控制组及其父控制组的所有资源限制和控制参数的影响。如果一个子控制组需要覆盖父控制组的某个参数,可以在子控制组中重新指定该参数。

每个Hierarchy都对应一个cgroup虚拟文件系统,每个Hierarchy都有系统上的所有task,此外低level的Hierarchy不能超过高level设定的资源上限

架构图如下:
在这里插入图片描述

结合cgroup层级(Hierarchy)可以理解为一颗树,树的每个节点就是一个进程组,每棵树都会与一到多个子系统关联。在一棵树里,会包含Linux系统中的所有进程,但每个进程只能属于一个节点(进程组)。系统中可以有很多颗cgroup树,每棵树都和不同的subsystem关联,一个进程可以属于多棵树,即一个进程可以属于多个进程组,只是这些进程组和不同的子系统关联。目前Linux最多可以建十二颗cgroup树,每棵树关联一个子系统,当然也可以只建一棵树,然后让这棵树关联到所有的子系统。当一颗cgroup树不和任何子系统关联的时候,意味着这棵树只是将进程进行分组,至于要在分组的基础上做些什么,将由应用程序自己决定,systemd就是这样一个例子。

层级的组成规则有四个:

3.1、规则一

单个层次结构可以具有一个或多个子系统。如图所示,/cpu_memory_cg这个层级对cgroup1,cgroup2设置了cpu和memory两个子系统。

在这里插入图片描述

3.2、规则二

如果任何一个子系统已经附加到了一个层次,则不能将他们附加到另一个层次的结构中。如图所示,层级A的cpu_cg首先管理cpu子系统,那么层级B的cpu_mem_cg就无法管理cpu子系统。
在这里插入图片描述

3.3、规则三

每次在系统上创建新的层次结构时,系统上的所有任务最初都是该层次结构的默认cgroup(称为根cgroup)成员。对于创建的任何单个层次结构,系统上的每个任务都可以是该层次结构中的一个cgroup成员。一个任务可以位于多个cgroup中,只要这些cgroup中的每个处于不同的子系统层次结构中即可。任务一旦成为同一层次结构中的第二个cgroup成员,就会将其从该层次结构中的第一个cgroup中删除,即在同一层次结构中的两个不同cgroup,绝不会有同一任务,也即是对某进程某类cgroup子系统的限制方式只能有一种。创建第一个层次结构时,系统上的每个任务都是至少一个cgroup(根cgroup)的成员,因此,在使用cgroup时,每个系统任务始终至少位于一个cgroup中,如图所示
在这里插入图片描述

3.3、规则四

系统上派生的任何进程都会创建一个子进程(或线程)。子进程自动继承其父级的cgroup成员资格,但可以根据需要移动到其他cgroup中,移动后父子进程完全独立,如图所示

在这里插入图片描述

四、cgroups 在Docker 中的应用

4.1、对cpu 使用率控制

在启动容器时使用docker run --cpu等参数可以控制容器CPU 使用率和分配比例,避免因为某个容器过度使用 CPU 资源而影响其他服务的正常运行。常见参数及其作用如下:

--cpus

限制容器使用的 CPU 核心数量。例如,--cpus=2 表示限制容器最多只能使用 2 个 CPU 核心。

--cpu-period 和 --cpu-quota

用于限制容器可以使用的 CPU 时间。--cpu-period 参数用于指定时间周期,单位为微秒,默认为 100,000 微秒。--cpu-quota 参数用于指定每个时间周期容器可以使用的 CPU 时间,单位为微秒,默认为 -1,表示不限制。

--cpu-shares

指定容器的 CPU 分配比例。例如,--cpu-shares=512 表示容器分配到的 CPU 资源权重是 512。

--cpu-rt-period

docker run --cpu-rt-period是 Docker 的一个 CPU 实时调度相关的参数。它用于指定在实时控制组中运行的容器的 CPU 时间周期,单位为微秒,默认值为 1000000 微秒(即 1 秒)。

实时控制组(RT Cgroups) 是一种针对实时任务的 Cgroups 控制组。当一个容器属于实时控制组时,容器可以有更高的 CPU 优先级,并且可以使用更多的 CPU 资源。

通过在 docker run 命令中使用 --cpu-rt-period 参数,可以为容器指定自己的 CPU 时间周期。例如,使用以下命令创建一个实时控制组的容器:

docker run --cpu-rt-period=50000 --cpu-rt-runtime=10000 myimage

该命令会创建一个名为 myimage 的容器,将容器绑定到一个实时控制组中,并指定容器的 CPU 时间周期为 50000 微秒,CPU 运行时间为 10000 微秒。这样,容器可以使用更多的 CPU 资源,并提高容器内部应用程序的性能。

需要注意的是,实时控制组的使用需要谨慎。不当使用实时控制组可能会影响其他服务的正常运行。建议在使用实时控制组时仅为真正需要实时性的服务使用,并根据系统实际情况进行适当的调优和管理。

--cpu-rt-runtime

docker run --cpu-rt-runtime 是 Docker 的一个 CPU 实时调度相关的参数。它用于指定在实时控制组中运行的容器的 CPU 运行时间,单位为微秒,默认值为 -1,表示不限制。

--cpuset-cpus

docker run --cpuset-cpus 是 Docker 的一个 CPU 调度相关的参数。它用于指定容器可使用的 CPU 核心编号,可以用逗号分隔多个 CPU 核心编号。例如,--cpuset-cpus=0,2,4 表示容器只能使用编号为 0、2、4 的 CPU 核心。

通过在 docker run 命令中使用 --cpuset-cpus 参数,可以限制容器只能使用指定的 CPU 核心,避免容器过度使用 CPU 资源而影响系统性能。例如,使用以下命令创建一个限制容器使用 CPU 核心的容器:

docker run --cpuset-cpus=0,2,4 myimage

该命令会创建一个名为 myimage 的容器,将容器限制为只能使用编号为 0、2、4 的 CPU 核心。

--cpuset-mems

docker run --cpuset-mems 是 Docker 的一个 CPU 调度相关的参数。它用于指定容器可使用的内存节点,可以用逗号分隔多个内存节点编号。例如,--cpuset-mems=0,1 表示容器只能使用节点 0 和节点 1 上的内存资源。

通过在 docker run 命令中使用 --cpuset-mems 参数,可以限制容器只能使用指定的内存节点,避免容器过度使用内存资源而影响系统性能。例如,使用以下命令创建一个限制容器使用内存节点的容器:

docker run --cpuset-mems=0,1 myimage

该命令会创建一个名为 myimage 的容器,将容器限制为只能使用节点 0 和节点 1 上的内存资源。

4.2、对内存限额

与操作系统类似,容器可使用的内存包括两部分:物理内存和 Swap,默认情况下,容器可以使用主机上的所有空闲内存,docker可以使用一些参数来限制容器使用的内存资源,避免因为某个容器过度使用内存资源而影响其他服务的正常运行。常见参数如下:

--memory 和 --memory-swap

限制容器可以使用的内存和交换空间的大小。
--memory 参数用于指定内存限制,
--memory-swap 参数用于指定交换空间限制。
默认情况下,--memory-swap 的值等于 --memory 的值加上主机上可用的交换空间大小。例如,--memory=1g --memory-swap=2g 表示限制容器最多只能使用 1GB 的内存和 2GB 的交换空间。

--memory-reservation

指定容器的内存保证,即为容器预留一定的内存空间。例如, --memory-reservation=500m 表示为容器预留至少 500MB 的内存空间。

--memory-swappiness

指定容器对交换空间的使用倾向性。该参数的值范围为 0 到 100,表示对内存的使用倾向性。值越大,容器越倾向于使用交换空间。

4.3、对-Block IO的限制

对于容器使用的块 IO 资源,可以使用以下参数进行限制

--blkio-cost-weight-device

docker run --blkio-cost-weight-device 是 Docker 的一个 IO 调度相关的参数。它用于指定容器在指定块设备上使用 IO 资源的权重。该参数在使用 IO 资源时会影响容器的 IO 资源使用情况,从而保证容器磁盘 IO 的质量。

使用 --blkio-cost-weight-device 参数可以为容器指定在指定块设备上使用 IO 资源的权重。例如,使用以下命令创建一个限制容器在 /dev/sda 上的磁盘 IO 资源使用权重为 400 的容器:

docker run --blkio-cost-weight-device=/dev/sda:400 myimage

该命令会创建一个名为 myimage 的容器,并为容器指定在 /dev/sda 块设备上使用 IO 资源的权重为 400。

--blkio-weight

docker run --blkio-weight 是 Docker 的一个 IO 调度相关的参数。它用于为容器指定 IO 资源的权重,从而影响容器在 IO 调度时的优先级。该参数在使用 IO 资源时会影响容器的 IO 资源使用情况,从而保证容器磁盘 IO 的质量。

使用 --blkio-weight 参数可以为容器指定在 IO 调度时的权重。默认情况下,容器没有 IO 限制。使用 --blkio-weight 可以设置容器的 IO 权重,值越大,容器的 IO 资源使用优先级越高。例如,使用以下命令创建一个 IO 权重为 500 的容器:

docker run --blkio-weight=500 myimage

该命令会创建一个名为 myimage 的容器,并为容器指定 IO 权重为 500。

--blkio-cost-weight-device--blkio-weight 区别

作用不同:--blkio-cost-weight-device 参数是针对指定的块设备设置容器在该设备上的 IO 资源使用权重,而 --blkio-weight 参数是为容器指定 IO 调度时的总权重。
适用范围不同:--blkio-cost-weight-device 参数只能限制容器在指定的块设备上使用的 IO 资源,而 --blkio-weight 参数可以影响容器在所有块设备上的 IO 调度。
举个例子,如果一个容器使用多个块设备,那么使用 --blkio-cost-weight-device 参数只能针对某个指定的设备设置 IO 资源的使用限制,而使用 --blkio-weight 参数可以为整个容器设置 IO 调度的权重,从而影响容器在多个块设备上的 IO 资源使用情况。

--blkio-weight-device

docker run --blkio-weight-device 是 Docker 的一个 IO 调度相关的参数。它用于为容器在指定块设备上使用 IO 资源的权重,从而影响容器在 IO 调度时的优先级。该参数在使用 IO 资源时会影响容器的 IO 资源使用情况,从而保证容器磁盘 IO 的质量。

使用 --blkio-weight-device 参数可以为容器在指定块设备上使用 IO 资源的权重。例如,使用以下命令创建一个限制容器在 /dev/sda 块设备上的 IO 资源使用权重为 400 的容器:

docker run --blkio-weight-device=/dev/sda:400 myimage

该命令会创建一个名为 myimage 的容器,并为容器在 /dev/sda 块设备上使用 IO 资源的权重为 400。

--blkio-cost-weight-device--blkio-weight-device 区别

作用不同:--blkio-cost-weight-device 参数是针对指定的块设备设置容器在该设备上的 IO 资源使用权重,而 --blkio-weight-device 参数是为容器指定在所有块设备上使用 IO 资源的权重。
适用范围不同:--blkio-cost-weight-device 参数只能限制容器在指定的块设备上使用的 IO 资源,而 --blkio-weight-device 参数可以影响容器在所有块设备上的 IO 调度。
举个例子,如果一个容器使用多个块设备,那么使用 --blkio-cost-weight-device 参数只能针对某个指定的设备设置 IO 资源的使用限制,而使用 --blkio-weight-device 参数可以为整个容器设置在所有块设备上的 IO 调度的权重,从而影响容器在多个块设备上的 IO 资源使用情况。

--blkio-weight--blkio-weight-device 区别

作用不同:--blkio-weight 参数是为容器指定 IO 调度时的总权重,而 --blkio-weight-device 参数是为容器在指定块设备上使用 IO 资源的权重。
适用范围不同:--blkio-weight 参数可以影响容器在所有块设备上的 IO 调度,而 --blkio-weight-device 参数只能限制容器在指定的块设备上使用的 IO 资源。
举个例子,如果一个容器使用多个块设备,那么使用 --blkio-weight 参数可以为整个容器设置 IO 调度时的权重,从而影响容器在多个块设备上的 IO 资源使用情况,而使用 --blkio-weight-device 参数只能针对某个指定的设备设置容器在该设备上的 IO 资源的使用限制。

4.4、devices 的限制

bps 是byte per second,每秒读写的数据量。iops是io per second,每秒IO的次数。常见参数如下:

--device

docker run --device选项用于将主机上的特定设备映射到容器中,以便容器内的进程可以访问这些设备。这是Docker中的一个高级选项,通常用于需要访问主机上的硬件设备的应用程序,例如音频设备、摄像头、串口等。

例如,如果您想在Docker容器中运行一个使用USB设备连接的应用程序,那么您可以使用以下命令运行容器:

docker run --device=/dev/ttyUSB0 myapp

其中,/dev/ttyUSB0是USB设备的路径,myapp是您要运行的应用程序的名称。这个命令将会将主机上的/dev/ttyUSB0设备映射到容器中,以便您的应用程序可以使用它。这样,在容器中运行的应用程序就可以像在主机上一样访问USB设备了。

此外,还可以指定多个设备,例如:

docker run --device=/dev/ttyUSB0 --device=/dev/video0 myapp

这个命令将会将主机上的/dev/ttyUSB0设备和/dev/video0设备映射到容器中,以便myapp应用程序可以使用这些设备。

--device-cgroup-rule

docker run --device-cgroup-rule选项用于在容器内设置控制组规则,以限制容器中进程对指定硬件设备的访问。通常,这个选项与docker run --device选项一起使用,以控制容器中进程对硬件设备的访问。

例如,以下命令限制了容器中所有进程对/dev/snd设备的访问:

docker run --device=/dev/snd --device-cgroup-rule='c 116:* rwm' myapp

其中,--device=/dev/snd将主机上的/dev/snd设备映射到容器中,--device-cgroup-rule='c 116:* rwm'设置了控制组规则,以允许容器中进程对设备/dev/snd的读、写和映射操作。

--device-read-bps

docker run --device-read-bps选项用于限制容器内的进程从指定设备读取数据的速度。它限制了设备的读取速度,以保护设备不会被过度使用。这个选项仅在使用–device选项映射设备时生效。

例如,以下命令将限制容器中的进程从/dev/sda设备每秒读取不超过1MB的数据:

docker run --device=/dev/sda --device-read-bps=/dev/sda:1mb myapp

其中,--device=/dev/sda将主机上的/dev/sda设备映射到容器中,--device-read-bps=/dev/sda:1mb设置了限制,以限制容器中的进程每秒最多从/dev/sda设备读取1MB的数据。

--device-read-iops

docker run --device-read-iops选项用于限制容器内的进程从指定设备读取数据的IOPS(每秒输入/输出操作数)。它限制了设备的读取速度,以保护设备不会被过度使用。这个选项仅在使用–device选项映射设备时生效。

例如,以下命令将限制容器中的进程从/dev/sda设备每秒执行不超过100个读取操作:

docker run --device=/dev/sda --device-read-iops=/dev/sda:100 myapp

其中,--device=/dev/sda将主机上的/dev/sda设备映射到容器中, --device-read-iops=/dev/sda:100设置了限制,以限制容器中的进程每秒最多从/dev/sda设备执行100个读取操作。

--device-write-bps

docker run --device-write-bps选项用于限制容器内的进程向指定设备写入数据的速度。它限制了设备的写入速度,以保护设备不会被过度使用。这个选项仅在使用–device选项映射设备时生效。

例如,以下命令将限制容器中的进程向/dev/sda设备每秒写入不超过1MB的数据:

docker run --device=/dev/sda --device-write-bps=/dev/sda:1mb myapp

其中,--device=/dev/sda将主机上的/dev/sda设备映射到容器中,--device-write-bps=/dev/sda:1mb设置了限制,以限制容器中的进程每秒最多向/dev/sda设备写入1MB的数据。

--device-write-iops

docker run --device-write-iops选项用于限制容器内的进程向指定设备写入数据的IOPS(每秒输入/输出操作数)。它限制了设备的写入速度,以保护设备不会被过度使用。这个选项仅在使用–device选项映射设备时生效。

例如,以下命令将限制容器中的进程向/dev/sda设备每秒执行不超过100个写入操作:

docker run --device=/dev/sda --device-write-iops=/dev/sda:100 myapp

其中,--device=/dev/sda将主机上的/dev/sda设备映射到容器中,--device-write-iops=/dev/sda:100设置了限制,以限制容器中的进程每秒最多向/dev/sda设备执行100个写入操作。

参考文档

1、https://blog.csdn.net/weixin_41402069/article/details/125886286

2、https://www.cnblogs.com/rdchenxi/p/10464386.html

3、https://www.cnblogs.com/lioa/p/12664912.html

4、https://www.modb.pro/db/233701

5、https://blog.frognew.com/2021/05/relearning-container-06.html

6、https://www.modb.pro/db/233701

7、https://ggaaooppeenngg.github.io/zh-CN/2017/05/07/cgroups-%E5%88%86%E6%9E%90%E4%B9%8B%E5%86%85%E5%AD%98%E5%92%8CCPU/

8、https://www.php.cn/faq/556561.html

9、https://blog.csdn.net/m0_71931851/article/details/128132467

猜你喜欢

转载自blog.csdn.net/yuelai_217/article/details/131332809