管理容器的资源:深入理解 Cgroup 机制

🧩 管理容器的资源:深入理解 Cgroup 机制

Docker 能够高效地运行多个容器、并精确地控制它们的 CPU、内存、I/O 等资源,
这背后的“魔法”来自 Linux 的 Cgroup(Control Groups)

本文将带你深入理解 Cgroup 的原理、类别、Docker 如何使用它,以及如何亲手限制容器资源。


🧠 一、Cgroup 是什么?

Cgroup(Control Groups) 是 Linux 内核提供的一种机制,用于:

  • 限制(Limit)
  • 统计(Account)
  • 隔离(Isolate)

一组进程对系统资源(如 CPU、内存、I/O、进程数等)的使用情况。

换句话说,Cgroup 是 Linux 系统的“资源管理底层”
Docker、Kubernetes、systemd 都是通过它来实现容器化资源控制的。


⚙️ 二、为什么容器需要 Cgroup?

如果没有 Cgroup,所有容器运行在宿主机上时:

  • 容易出现某个容器独占 CPU;
  • 内存泄漏会导致宿主机 OOM;
  • I/O 密集型容器可能拖慢整个系统。

通过 Cgroup,Docker 能为每个容器设定“上限”,例如:

  • CPU 只能用 20%
  • 内存最多 512MB
  • 最多允许 100 个进程
  • 限制磁盘写入速率 10MB/s

🧩 这样,每个容器都像被分配了独立的资源配额,互不干扰。


🔍 三、Cgroup 的结构与版本

🪜 1. 树状层级结构

Cgroup 将系统中的进程组织成一个树状结构。
每个节点是一个 控制组(control group),每个组可绑定若干控制器。

示意图:

cgroup
 ├── docker
 │    ├── container_1
 │    └── container_2
 └── system.slice

每个控制组可以定义自己的资源限制文件,例如:

/sys/fs/cgroup/docker/container_1/memory.max
/sys/fs/cgroup/docker/container_1/cpu.max

🧩 2. 控制器类型(常用)

控制器说明
cpu限制进程使用 CPU 的时间
cpuacct统计 CPU 使用量
memory限制内存使用
pids限制进程数
blkio限制磁盘 I/O 速率
devices控制设备访问权限
cpuset控制进程可运行的 CPU 核心

🧬 3. Cgroup v1 与 v2 区别

对比项v1v2
控制器结构各自独立统一管理
层级模型控制器可挂载多次单一树结构
文件接口分散复杂简洁一致
Docker 默认旧版使用 v1新版全面支持 v2

📌 新系统(如 Ubuntu 22+、RHEL 9+)默认使用 Cgroup v2


🧱 四、Docker 如何使用 Cgroup?

Docker 通过 libcontainer 与内核交互,为每个容器创建独立的控制组:

示意图:

/sys/fs/cgroup/
 ├── system.slice
 ├── user.slice
 └── docker/
      ├── 2b8f2a1b.../
      │    ├── cpu.max
      │    ├── memory.max
      │    └── pids.max
      └── ...

这些文件中保存的就是资源配额数据。
当容器进程启动时,Docker 会把它加入对应的 cgroup 中。


⚡ 五、Docker 中的资源限制实战

Docker 的资源限制其实就是对 Cgroup 文件的封装。
例如:

💾 限制内存使用

docker run -d --name mem_test --memory=200m ubuntu sleep 1000

效果:容器最大只能用 200MB 内存。
超过时,系统会触发 OOM(Out Of Memory) 杀死容器进程。


🧮 限制 CPU 使用

docker run -d --name cpu_test --cpus=0.5 ubuntu sleep 1000

效果:容器最多使用 50% CPU 时间。


🧩 限制进程数量

docker run -d --name pids_test --pids-limit=50 ubuntu sleep 1000

效果:容器最多可创建 50 个进程,防止 fork 炸弹。


🧱 限制磁盘 I/O

docker run -d --name io_test --device-write-bps /dev/sda:10mb ubuntu dd if=/dev/zero of=/tmp/test bs=1M count=100

效果:磁盘写入速度被限制为 10MB/s。


🔬 六、手动使用 Cgroup 限制资源(原生命令演示)

下面我们动手体验下 原生 cgroup 操作,理解 Docker 背后做了什么。

1️⃣ 创建控制组

sudo mkdir /sys/fs/cgroup/testgroup

2️⃣ 限制内存

echo $((100*1024*1024)) | sudo tee /sys/fs/cgroup/testgroup/memory.max

3️⃣ 启动测试进程

stress --vm 1 --vm-bytes 200M --timeout 30s &
echo $! | sudo tee /sys/fs/cgroup/testgroup/cgroup.procs

效果:该进程被限制为 100MB 内存,超过时会被系统 OOM 杀死。


📊 七、资源监控与调优

查看 cgroup 使用状态:

cat /sys/fs/cgroup/testgroup/memory.current
cat /sys/fs/cgroup/testgroup/cpu.stat

在 Docker 中查看容器资源使用:

docker stats

示例输出:

CONTAINER ID   NAME         CPU %   MEM USAGE / LIMIT   MEM %   NET I/O
c72bdf13e     mem_test     49.7%   180.4MiB / 200MiB   90.2%   1.5kB / 0B

💡 八、Cgroup 与 Namespace 的关系

功能机制说明
隔离Namespace控制容器“能看到什么”
限制Cgroup控制容器“能用多少”

🧠 一句话理解:

Namespace 提供“边界”,Cgroup 提供“配额”。


🧭 九、总结

功能Cgroup 控制项Docker 参数
CPUcpu.max--cpus
内存memory.max--memory
进程数pids.max--pids-limit
I/Oio.max--device-read-bps / --device-write-bps

Cgroup 是容器资源管理的核心基础
✅ Docker、Kubernetes 都是基于它构建的高层封装
✅ 理解 Cgroup = 理解容器资源管理的本质


📚 延伸阅读


🧩 一句话记忆:
Cgroup 是容器的“资源警察”,
负责限制、统计、调度一切可被度量的系统资源。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

君九@DBA

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值