一、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)
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_device
和 blkio.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_device
和 blkio.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_us
和 cpu.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_us
和 cpu.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 中进程允许使用的指定大小的大页面内存的最大量(以字节为单位)。其中 表示大页面的大小,例如 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