CGroups 资源控制组

通过命名空间可以实现进程间在文件系统、网络以及宿主进程之间的相互隔离,但是对于宿主机的物理资源比如 CPU、内存、块设备等,如果同一机器上运行了多个相互独立的容器,这些容器在执行高负载任务时必定会因此产生严重的资源争用问题。比如,当其中的某个容器正在执行 CPU 密集型的任务,此时如果没有某种限制,这个容器必定会影响在同一主机上运行的其他容器中任务,进而导致这些容器的性能受到极大的影响,这在生产上是必须要避免的。

解决进程间虚拟资源隔离问题的办法就是 CGroups(Control Groups),它是 Linux 内核的一种机制,用于对系统资源(如 CPU、内存、磁盘 I/O、网络等)进行分组管理和限制。CGroups 允许系统管理员将进程分组,并为每个组分配特定的资源限制,从而实现资源的隔离、控制和监控。

CGroups 的核心功能包括:

  1. 限制组内进程的资源使用量(如 CPU 使用率、内存使用量等)。防止某个进程或组占用过多资源,影响其他进程或系统的稳定性。
  2. 为不同的组分配不同的资源优先级。为高优先级任务分配更多的 CPU 时间。
  3. 监控和记录组内进程的资源使用情况(如 CPU 时间、内存使用量等)。
  4. 对组内进程进行挂起、恢复、终止等操作。
  5. CGroups 支持层次化结构,可以将组嵌套在其他组中,形成树状结构。

CGroups 通过子系统(subsystem)来管理不同类型的资源。常见的子系统包括:

bash 复制代码
root@docker-host:~# ls /sys/fs/cgroup/
blkio      cpu,cpuacct  freezer  net_cls        perf_event  systemd
cpu        cpuset       hugetlb  net_cls,net_prio  pids        unified
cpuacct    devices      memory   net_prio       rdma
root@docker-host:~# 

其中,cpu:限制 CPU 使用率,支持按比例分配 CPU 时间。memory:限制内存使用量,支持设置内存和交换空间的上限。blkio:限制块设备如磁盘的 I/O 操作。devices:控制组内进程对设备的访问权限。freezer:挂起或恢复组内的进程。net_cls:标记网络数据包,用于流量控制。pids:限制组内进程的数量。cpuacct:统计组内进程的 CPU 使用情况。

我们将在两个 shell 会话中同时运行这个程序,不出意外的话,主机内存很快就会耗尽。为防止这种情况的出现,可以创建一个 CGroups 来限制这两个 shell 进程的内存使用,当内存达到限制上限时终止程序,从而保证主机内存资源的安全使用。

创建 CGroups 很简单,只需在控制组文件系统创建一个目录即可。在本例中,我们将创建一个名为 demo 的内存组,之后内核会自动将可用的子系统配置文件填充到这个目录:

bash 复制代码
root@docker-host:~# mkdir /sys/fs/cgroup/memory/demo
root@docker-host:~# ls /sys/fs/cgroup/memory/demo/
cgroup.clone_children			memory.limit_in_bytes
cgroup.event_control			memory.max_usage_in_bytes
cgroup.procs				memory.move_charge_at_immigrate
memory.failcnt				memory.numa_stat
memory.force_empty			memory.oom_control
memory.kmem.failcnt			memory.pressure_level
memory.kmem.limit_in_bytes		memory.soft_limit_in_bytes
memory.kmem.max_usage_in_bytes		memory.stat
memory.kmem.slabinfo			memory.swappiness
memory.kmem.tcp.failcnt			memory.usage_in_bytes
memory.kmem.tcp.limit_in_bytes		memory.use_hierarchy
memory.kmem.tcp.max_usage_in_bytes	notify_on_release
memory.kmem.tcp.usage_in_bytes		tasks
root@docker-host:~# 

将 demo 内存控制组的最大内存使用量限制在 100M,为演示效果考虑,禁止使用交换分区:

bash 复制代码
root@docker-host:~# echo "100000000" > /sys/fs/cgroup/memory/demo/memory.limit_in_bytes
root@docker-host:~# echo "0" > /sys/fs/cgroup/memory/demo/memory.swappiness
root@docker-host:~# 

启动的两个 bash 进程 id 显示如下:

bash 复制代码
root@docker-host:~# ps -ef | grep bash
root      1585  1378 0 12:55 pts/0    00:00:00 -bash
root      1695  1371 0 12:55 pts/1    00:00:00 -bash
root      1770  1695 0 12:56 pts/1    00:00:00 grep --color=auto bash
root@docker-host:~# 

将这两个进程加入到 demo 内存控制组的 tasks 文件中:

bash 复制代码
root@docker-host:~# ps
  PID TTY          TIME CMD
 1585 pts/0    00:00:00 bash
 1850 pts/0    00:00:00 ps
root@docker-host:~# echo $$ >> /sys/fs/cgroup/memory/demo/tasks
root@docker-host:~# 

root@docker-host:~# ps
  PID TTY          TIME CMD
 1695 pts/1    00:00:00 bash
 1845 pts/1    00:00:00 ps

可以看到,当两个应用的内存使用达到 100M 时,demo 内存控制组会终止程序的运行,如果要取消控制组的限制,只要删除控制目录即可.

注意:只有 tasks 文件中的所有进程都已退出或已重新分配给另一个组才能删除。

CGroup 的前身是出自于 2006 年 Google 工程师 Paul Menage 和 Rohit Seth 启动的一个名字叫做 process containers 的项目,后来因为与 container 在内核中的名字有冲突,因此在 2007 年改名为 control groups,合并到 2008 年发布的 2.6.24 内核版本中。

最初 CGroups 的版本被称为 v1,后续的开发工作由 Tejun Heo 接管,他重新设计并重写了 CGroups,新版本被称为 v2,并在 kernel 4.5 版本中引入。随着 v2 版本的普及,容器资源的管理变得更加高效和灵活。

在容器环境中,CGroup 扮演着至关重要的角色,它是容器资源管理和隔离的核心技术之一。在 Docker 和 Kubernetes 中,CGroup 被广泛用于限制容器的 CPU、内存、磁盘 I/O 等资源。

相关推荐
2601_967987373 分钟前
安装 Redis 或 Redis Stack
linux·windows·redis·macos·安装
feng_you_ying_li4 分钟前
linux之数据链路层
linux·网络·智能路由器
修己xj20 分钟前
服务器无法解析域名?一次 DNS 配置缺失的排查与修复
运维
GeW1 小时前
高端化走到深处,是数据库和Linux的事
linux
程序员初一3 小时前
Linux 远程桌面有四种做法
linux·ssh
爱吃奥利奥_wen3 小时前
SQL Server 基础语法详解:从建库建表到约束与增删改查
服务器·数据库·oracle
程序开发阿元3 小时前
1C1G 能跑什么:把留常驻服务和不留摆进一张内存表
linux·ssh
xbzb5 小时前
自定义 yum 软件源:Linux 上 createrepo,Windows 上纯 Python 也能造
linux·运维·windows·python·yum·createrepo
Android系统攻城狮5 小时前
Linux FFmpeg深度解析之avio_open调用流程与实战(三十八)
linux·运维·服务器·ffmpeg·音视频进阶·ffmpeg音视频
独隅6 小时前
WebStorm Linux 版安装实战与核心效能展示
linux·ide·webstorm