Day5 :防止容器占满服务器,内存限制完整实验

在Docker中Namespace负责资源隔离,让容器互相看不见彼此;而CGroup负责资源限制。二者搭配才构成容器两大底层核心技术。如果只有隔离没有限制,某个容器疯狂占用CPU、内存,会直接把宿主机资源耗尽引发宕机。

问答题

1、请说明 CGroups 对于容器运行有什么重要作用。
资源隔离与限制的核心
1、限制组内进程的资源使用量(如CPU使用率、内存使用量)。防止每个进程或组占用过多资源,影响其他进程或系统的稳定性
2、为不同组分配不同的资源优先级。为高优先级任务分配更多的CPU时间
3、监控和记录组内进程的资源使用情况(如CPU时间、内存使用量)
4、可对组内进程挂起、恢复、终止
5、CGroups支持层次化结构,可将组嵌套在其他组中,形成树形结构

2、CGroups 是如何控制容器资源使用的,请举例说明。
创建控制组、配置资源规则、将进程加入控制组
当程序申请的内存超过 100MB 时,内核会立刻终止进程,不会让它把宿主机内存占满。
没有 CGroups,容器就做不到真正的资源隔离和限制,宿主机上的容器很容易互相干扰甚至拖垮宿主机。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

一、什么是CGroup

CGroup全称Control Groups(控制组),是Linux内核提供的机制。作用:对一组进程做资源配额限制、统计、监控。简单理解:Namespace划分“独立房间”,CGroup给每个房间安装电表、水表,限制最多能用多少资源。

二、CGroup五大核心功能

  1. 资源限制(Limit)
    限制进程组最大可占用资源,例如最大内存、最大CPU算力。
  2. 优先级分配(Priority)
    分配CPU调度权重,重要容器优先使用CPU。
  3. 资源统计(Accounting)
    统计进程消耗CPU、内存、磁盘IO,对应docker stats底层数据来源。
  4. 进程冻结(Suspend)
    暂停/恢复一组进程。
  5. 进程控制(Control)
    对组内进程执行信号、销毁等操作。

三、常用CGroup子系统(Subsystem)

子系统就是内核中针对某一类资源的管控模块:

  • cpu:限制CPU时间、调度权重
  • memory:限制进程最大内存,内存超限触发OOM
  • blkio:块设备磁盘IO读写限速
  • pids:限制组内最多能创建多少进程,防御fork炸弹
  • cpuset:绑定进程到指定CPU核心、内存节点(多核服务器常用)

补充:容器 = Namespace(隔离视图) + CGroup(资源配额) + rootfs文件系统

四、内存溢出Demo + 手动CGroup内存限制实操

我们手动创建CGroup,限制进程最多使用100M内存,运行一段无限申请内存的C语言程序,观察内核如何杀掉超限进程。

4.1 内存溢出C Demo代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(){
    while(1){
        // 每次申请10MB内存
        char *p = malloc(10*1024*1024);
        memset(p, 1, 10*1024*1024);
        sleep(1);
    }
    return 0;
}

编译命令:gcc mem_leak.c -o mem_leak

4.2 手动创建CGroup限制内存流程

  1. 挂载cgroup文件系统(cgroup v1)
  2. 在memory子系统下新建控制组目录
  3. 设置最大可用内存 memory.limit_in_bytes=104857600(100MB)
  4. 将程序PID写入 tasks 文件,把进程加入该控制组
  5. 运行内存溢出程序,内存达到阈值后触发OOM Kill,进程被系统终止

实验现象:程序持续占用内存,到达100MB上限不再分配新内存,内核触发OOM机制杀死进程,防止耗尽宿主机内存。

五、CGroup v1 与 CGroup v2 简单区分

CGroup v1:各类资源子系统独立目录,cpu、memory分开挂载,Docker长期默认使用v1,配置简单但是结构零散。

CGroup v2:统一层级架构,所有资源放在同一套目录树,内核新版本支持,设计更简洁;新版容器运行时(containerd、crun)逐步向v2迁移。

六、Docker资源参数底层对应CGroup

日常使用`docker run`资源限制参数,底层Docker会自动创建CGroup并写入对应配置,无需手动操作文件。

- `--memory 100m`:底层写入memory子系统内存上限 - `--cpus 0.5`:限制最多使用0.5颗CPU核心,映射cpu子系统配额

示例启动命令:

docker run -it --memory 100m --cpus 0.5 nginx

当容器内进程持续占用超过设定内存,同样会触发OOM;CPU占用超过配额会被内核限流,无法抢占宿主机全部算力。

七、Namespace vs CGroup 核心区别

Namespace:改变进程“能看到什么资源”,实现隔离;CGroup:限制进程“最多能用多少资源”,实现管控。二者互相配合,缺一不可。


Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐