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 等资源。

相关推荐
皓月盈江1 小时前
Linux Debian系统安装Google Chrome谷歌浏览器教程
linux·chrome·debian·谷歌浏览器
Vcaker1 小时前
Linux学习37-rook-ceph部署
linux·运维·学习
Mortalbreeze1 小时前
MySQL 基础篇(二):数据库和数据表的基本操作
linux·服务器·数据库·mysql
yt004yt2 小时前
VOCs 绿岛项目数字化设计要点,结合能碳管控思路
大数据·运维
Zenova EdgeOS2 小时前
工业网关心跳机制实战:Keepalive、应用层探活与健康判定
服务器·网络·数据库
阳光九叶草LXGZXJ2 小时前
Linux-学习-12-JDK安装
java·linux·运维·学习
wtblszn10 小时前
自动化包装生产线设备可视化管理方案
运维·自动化
跨境小彭11 小时前
Temu拉美站点铺货实操复盘:手动复制痛点与批量自动化解决方案
服务器·人工智能·搜索引擎·自动化·temu电商运营
心之语歌11 小时前
Tkinter 画布基本梳理
运维·服务器·python