四、Linux 内核容器技术深度解析系列-6-linux-kernel-container-cgroups-part1
·
Linux 内核容器技术:CGroups 资源限制核心技术(第一部分)
文档信息
- 系列: Linux 内核容器技术深度解析
- 第二篇: CGroups 资源限制
- 版本: V1.0
- 创建日期: 2026 年 3 月 10 日
- 预计阅读时间: 4-5 小时
- 技术难度: ⭐⭐⭐⭐⭐ (专家级)
- 前置知识: Linux 进程管理、内存管理、调度器基础
目录
- [CGroups 技术概述](#cgroups 技术概述)
- CGroups v1 核心子系统详解
- CGroups v2 统一架构
- [Docker 与 Kubernetes 中的 CGroups 应用](#docker 与 kubernetes 中的 cgroups 应用)
- 资源限制实战与性能调优
- 故障排查与最佳实践
CGroups 技术概述
什么是 CGroups?
CGroups 定义:
Control Groups (控制组) 是 Linux 内核功能,用于:
├─ 限制进程组的资源使用
├─ 监控资源消耗
├─ 控制资源分配
└─ 实现 QoS 保障
核心价值:
├─ 防止资源耗尽:单个进程不影响系统
├─ 资源隔离:多租户环境下的公平分配
├─ 性能保障:关键业务优先
└─ 成本优化:提升资源利用率
与 Namespace 对比:
Namespace (隔离):
├─ 解决"看不见"问题
├─ 系统视图隔离
├─ 进程、网络、文件隔离
└─ 各看各的
CGroups (限制):
├─ 解决"用多少"问题
├─ 资源使用限制
├─ CPU、内存、I/O 控制
└─ 定量分配
CGroups 发展历史
CGroups v1 (2008):
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Linux 2.6.24 引入
特点:
├─ 18 个子系统 (资源控制器)
├─ 树状层级结构
├─ 每个子系统独立层级
└─ 配置复杂
问题:
├─ 层级嵌套复杂
├─ 线程问题
├─ 内存回收不可控
└─ 配置繁琐
CGroups v2 (2016):
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Linux 4.5 引入
改进:
├─ 统一层级结构
├─ 单个树管理所有资源
├─ 线程安全
├─ 内存压力事件
├─ IO 控制增强
└─ 配置简化
优势对比:
特性 CGroups v1 CGroups v2
层级结构 多树 (每子系统) 单树 (统一)
线程支持 部分支持 完全支持
内存回收 不可控 可控
IO 控制 较弱 增强
配置复杂度 高 低
内核版本 2.6.24+ 4.5+
CGroups 核心概念
层级结构 (Hierarchy):
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
root/
├── system/
│ ├── user.slice/ # 用户会话
│ ├── system.slice/ # 系统服务
│ └── machine.slice/ # 虚拟机
├── docker/ # Docker 容器
│ ├── container1/
│ └── container2/
└── kubernetes/ # K8s Pod
├── pod1/
└── pod2/
控制组 (Control Group):
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
定义: 层级树中的节点
特点:
├─ 包含一组进程
├─ 继承父组配置
├─ 可设置资源限制
└─ 可监控资源使用
子系统 (Subsystem):
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
CGroups v1 的子系统:
├─ cpu: CPU 调度
├─ cpuacct: CPU 记账
├─ cpuset: CPU 亲和性
├─ memory: 内存控制
├─ blkio: 块设备 I/O
├─ devices: 设备访问
├─ net_cls: 网络分类
├─ net_prio: 网络优先级
├─ hugetlb: 大页内存
├─ pids: 进程数限制
├─ freezer: 进程冻结
├─ perf_event: 性能监控
├─ debug: 调试
└─ ... (共 18 个)
CGroups v2 的资源控制器:
├─ cpu: CPU 权重和带宽
├─ memory: 内存限制
├─ io: I/O 带宽和 IOPS
├─ pids: 进程数
├─ hugetlb: 大页内存
├─ rdma: RDMA 资源
└─ misc: 其他资源
CGroups 文件系统接口
CGroups v1 文件系统:
挂载点:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
$ mount | grep cgroup
cgroup on /sys/fs/cgroup/cpu type cgroup (rw,cpu)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,memory)
cgroup on /sys/fs/cgroup/blkio type cgroup (rw,blkio)
目录结构:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
/sys/fs/cgroup/memory/
├── cgroup.procs # 进程列表
├── tasks # 线程列表
├── memory.limit_in_bytes # 内存限制
├── memory.usage_in_bytes # 内存使用
├── memory.stat # 详细统计
├── memory.soft_limit_in_bytes # 软限制
├── memory.oom_control # OOM 控制
└── docker/ # 子控制组
├── cgroup.procs
└── memory.limit_in_bytes
CGroups v2 文件系统:
挂载点:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
$ mount | grep cgroup2
cgroup2 on /sys/fs/cgroup type cgroup2 (rw,nosuid,nodev,noexec,relatime)
目录结构:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
/sys/fs/cgroup/
├── cgroup.controllers # 可用控制器
├── cgroup.subtree_control # 子树控制
├── cgroup.procs # 进程列表
├── cgroup.threads # 线程列表
├── cpu.max # CPU 限制
├── cpu.weight # CPU 权重
├── memory.max # 内存限制
├── memory.current # 当前使用
├── io.max # I/O 限制
└── pids.max # 进程数限制
配置示例:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# 创建控制组
$ sudo mkdir /sys/fs/cgroup/mygroup
# 启用控制器
$ echo "+memory +cpu" > /sys/fs/cgroup/cgroup.subtree_control
# 设置内存限制 (512MB)
$ echo "536870912" > /sys/fs/cgroup/mygroup/memory.max
# 设置 CPU 限制 (50% = 50000ms/100000ms)
$ echo "50000 100000" > /sys/fs/cgroup/mygroup/cpu.max
# 添加进程到控制组
$ echo "12345" > /sys/fs/cgroup/mygroup/cgroup.procs
CGroups v1 核心子系统详解
1. CPU 子系统
功能:控制 CPU 时间分配
核心参数:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
cpu.cfs_quota_us: CPU 配额 (微秒)
cpu.cfs_period_us: CPU 周期 (微秒,默认 100000)
cpu.shares: CPU 权重 (默认 1024)
cpu.rt_runtime_us: 实时运行时间
cpu.rt_period_us: 实时周期
配置示例:
场景 1: 限制容器使用 50% CPU
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# 创建控制组
$ sudo cgcreate -g cpu:/docker/container1
# 设置 50% CPU (50000us / 100000us)
$ echo 50000 > /sys/fs/cgroup/cpu/docker/container1/cpu.cfs_quota_us
$ echo 100000 > /sys/fs/cgroup/cpu/docker/container1/cpu.cfs_period_us
# 添加进程
$ echo 12345 > /sys/fs/cgroup/cpu/docker/container1/cgroup.procs
# 验证
$ cgget -g cpu:docker/container1
cpu.cfs_quota_us = 50000
cpu.cfs_period_us = 100000
场景 2: CPU 权重分配
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# 容器 A: 权重 2048 (2 倍)
$ echo 2048 > /sys/fs/cgroup/cpu/docker/containerA/cpu.shares
# 容器 B: 权重 1024 (1 倍)
$ echo 1024 > /sys/fs/cgroup/cpu/docker/containerB/cpu.shares
# 容器 C: 权重 512 (0.5 倍)
$ echo 512 > /sys/fs/cgroup/cpu/docker/containerC/cpu.shares
# CPU 竞争时分配比例: A:B:C = 2:1:0.5
场景 3: 绑定到特定 CPU 核心
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# 使用 cpuset 子系统
$ sudo cgcreate -g cpuset:/docker/container1
# 设置 CPU 核心 (0-3)
$ echo "0-3" > /sys/fs/cgroup/cpuset/docker/container1/cpuset.cpus
# 设置内存节点
$ echo "0" > /sys/fs/cgroup/cpuset/docker/container1/cpuset.mems
# 添加进程
$ echo 12345 > /sys/fs/cgroup/cpuset/docker/container1/cgroup.procs
性能监控:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# 查看 CPU 使用统计
$ cat /sys/fs/cgroup/cpu/docker/container1/cpuacct.usage
1234567890 # 纳秒
# 查看每个 CPU 核心的使用
$ cat /sys/fs/cgroup/cpu/docker/container1/cpuacct.usage_percpu
123456 234567 345678 456789
# 使用 cgtop 查看实时 CPU 使用
$ cgtop -g cpu
2. Memory 子系统
功能:控制内存使用,防止 OOM
核心参数:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
memory.limit_in_bytes: 硬限制
memory.soft_limit_in_bytes: 软限制 (回收阈值)
memory.memsw.limit_in_bytes: 内存 +Swap 限制
memory.oom_control: OOM 控制
memory.oom_kill_disable: 禁用 OOM Kill
memory.use_hierarchy: 层级统计
memory.stat: 详细统计
配置示例:
场景 1: 设置内存硬限制
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# 创建控制组
$ sudo cgcreate -g memory:/docker/container1
# 设置 512MB 限制
$ echo "536870912" > /sys/fs/cgroup/memory/docker/container1/memory.limit_in_bytes
# 添加进程
$ echo 12345 > /sys/fs/cgroup/memory/docker/container1/cgroup.procs
# 查看使用情况
$ cat /sys/fs/cgroup/memory/docker/container1/memory.usage_in_bytes
268435456 # 256MB
场景 2: 配置软限制
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# 硬限制:1GB
$ echo "1073741824" > /sys/fs/cgroup/memory/docker/container1/memory.limit_in_bytes
# 软限制:512MB (内存紧张时优先回收)
$ echo "536870912" > /sys/fs/cgroup/memory/docker/container1/memory.soft_limit_in_bytes
# 效果:
# - 正常使用:可以使用到 1GB
# - 内存紧张:回收超过 512MB 的部分
场景 3: 禁用 OOM Killer
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# 禁用 OOM Kill (进程会睡眠而不是被杀死)
$ echo "1" > /sys/fs/cgroup/memory/docker/container1/memory.oom_kill_disable
# 查看 OOM 状态
$ cat /sys/fs/cgroup/memory/docker/container1/memory.oom_control
oom_kill_disable 1
under_oom 0
oom_kill 0
场景 4: 内存+Swap 限制
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# 内存限制:512MB
$ echo "536870912" > /sys/fs/cgroup/memory/docker/container1/memory.limit_in_bytes
# 内存+Swap 限制:1GB
$ echo "1073741824" > /sys/fs/cgroup/memory/docker/container1/memory.memsw.limit_in_bytes
# 效果:
# - 最多使用 512MB 物理内存
# - 超出部分使用 Swap
# - 总计不超过 1GB
详细统计信息:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
$ cat /sys/fs/cgroup/memory/docker/container1/memory.stat
cache 104857600 # 页面缓存
rss 209715200 # 匿名内存
mapped_file 52428800 # 映射文件
pgpgin 123456 # 读入页数
pgpgout 65432 # 写出页数
pgfault 78901 # 缺页中断
pgmajfault 234 # 主缺页中断
inactive_anon 104857600
active_anon 104857600
inactive_file 52428800
active_file 52428800
unevictable 0
hierarchical_memory_limit 536870912
hierarchical_memsw_limit 1073741824
total_cache 104857600
total_rss 209715200
OOM 事件监控:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# 查看 OOM 杀死次数
$ cat /sys/fs/cgroup/memory/docker/container1/memory.oom_kill
0
# 查看是否处于 OOM 状态
$ cat /sys/fs/cgroup/memory/docker/container1/memory.oom_control | grep under_oom
under_oom 0
3. Block I/O 子系统
功能:控制块设备 I/O 带宽和 IOPS
核心参数:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
blkio.weight: 权重 (10-1000, 默认 500)
blkio.weight_device: 按设备设置权重
blkio.throttle.read_bps_device: 读带宽限制 (B/s)
blkio.throttle.write_bps_device: 写带宽限制 (B/s)
blkio.throttle.read_iops_device: 读 IOPS 限制
blkio.throttle.write_iops_device: 写 IOPS 限制
配置示例:
场景 1: I/O 权重分配
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# 容器 A: 高优先级 (权重 800)
$ echo 800 > /sys/fs/cgroup/blkio/docker/containerA/blkio.weight
# 容器 B: 低优先级 (权重 200)
$ echo 200 > /sys/fs/cgroup/blkio/docker/containerB/blkio.weight
# I/O 竞争时分配比例:A:B = 4:1
场景 2: 限制读带宽
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# 限制从 /dev/sda 读取速度为 10MB/s
$ echo "8:0 10485760" > /sys/fs/cgroup/blkio/docker/container1/blkio.throttle.read_bps_device
# 设备号查询
$ ls -l /dev/sda
brw-rw---- 1 root disk 8, 0 Mar 10 10:00 /dev/sda
# 主设备号 8, 次设备号 0
场景 3: 限制写 IOPS
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# 限制向 /dev/sdb 写入 IOPS 为 100
$ echo "8:16 100" > /sys/fs/cgroup/blkio/docker/container1/blkio.throttle.write_iops_device
场景 4: 多设备限制
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# 限制 /dev/sda 读 10MB/s
$ echo "8:0 10485760" > /sys/fs/cgroup/blkio/docker/container1/blkio.throttle.read_bps_device
# 限制 /dev/sda 写 5MB/s
$ echo "8:0 5242880" > /sys/fs/cgroup/blkio/docker/container1/blkio.throttle.write_bps_device
# 限制 /dev/sdb 读 20MB/s
$ echo "8:16 20971520" > /sys/fs/cgroup/blkio/docker/container1/blkio.throttle.read_bps_device
# 限制 /dev/sdb 写 10MB/s
$ echo "8:16 10485760" > /sys/fs/cgroup/blkio/docker/container1/blkio.throttle.write_bps_device
I/O 统计监控:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# 查看 I/O 统计
$ cat /sys/fs/cgroup/blkio/docker/container1/blkio.io_service_bytes
8:0 Read 104857600
8:0 Write 52428800
8:0 Sync 157286400
8:0 Async 0
8:0 Total 157286400
8:16 Read 209715200
8:16 Write 104857600
8:16 Sync 314572800
8:16 Async 0
8:16 Total 314572800
# 查看 IOPS 统计
$ cat /sys/fs/cgroup/blkio/docker/container1/blkio.io_serviced
8:0 Read 1000
8:0 Write 500
8:0 Sync 1500
8:0 Async 0
8:0 Total 1500
4. PIDs 子系统
功能:限制进程数量,防止 fork 炸弹
核心参数:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
pids.max: 最大进程数
pids.current: 当前进程数
pids.events: 事件统计
配置示例:
场景 1: 限制进程数
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# 创建控制组
$ sudo cgcreate -g pids:/docker/container1
# 限制最多 100 个进程
$ echo "100" > /sys/fs/cgroup/pids/docker/container1/pids.max
# 添加进程
$ echo 12345 > /sys/fs/cgroup/pids/docker/container1/cgroup.procs
# 查看当前进程数
$ cat /sys/fs/cgroup/pids/docker/container1/pids.current
23
# 尝试 fork 超过限制
$ while :; do fork() & done
-bash: fork: retry: Resource temporarily unavailable
场景 2: 无限制
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# 设置为 max (无限制)
$ echo "max" > /sys/fs/cgroup/pids/docker/container1/pids.max
场景 3: 监控 fork 失败事件
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# 查看事件统计
$ cat /sys/fs/cgroup/pids/docker/container1/pids.events
max 0 # fork 失败次数
实时监控:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# 查看当前进程数
$ cat /sys/fs/cgroup/pids/docker/container1/pids.current
# 查看最大限制
$ cat /sys/fs/cgroup/pids/docker/container1/pids.max
# 列出所有进程
$ cat /sys/fs/cgroup/pids/docker/container1/cgroup.procs
12345
12346
12347
...
5. Devices 子系统
功能:控制设备访问权限
设备类型:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
b: 块设备 (block device)
c: 字符设备 (character device)
u: 任意设备
权限:
r: 读 (read)
w: 写 (write)
m: 创建设备节点 (mknod)
配置示例:
场景 1: 禁止访问所有设备 (默认)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# 默认情况下,CGroups 禁止访问所有设备
# 需要显式允许
场景 2: 允许访问 /dev/null
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# 允许读写 /dev/null (主设备号 1, 次设备号 3)
$ echo "c 1:3 rw" > /sys/fs/cgroup/devices/docker/container1/devices.allow
场景 3: 允许访问 /dev/zero
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# 允许读写 /dev/zero (主设备号 1, 次设备号 5)
$ echo "c 1:5 rw" > /sys/fs/cgroup/devices/docker/container1/devices.allow
场景 4: 允许访问所有终端设备
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# 允许访问 /dev/tty (主设备号 5, 次设备号 0)
$ echo "c 5:0 rw" > /sys/fs/cgroup/devices/docker/container1/devices.allow
场景 5: 允许访问 GPU 设备
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# NVIDIA GPU (主设备号 195)
$ echo "c 195:* rw" > /sys/fs/cgroup/devices/docker/container1/devices.allow
Docker 默认配置:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Docker 容器默认允许的设备:
├─ /dev/null (1:3)
├─ /dev/zero (1:5)
├─ /dev/full (1:7)
├─ /dev/random (1:8)
├─ /dev/urandom (1:9)
├─ /dev/tty (5:0)
├─ /dev/ptmx (5:2)
└─ /dev/fuse (10:229)
6. Net_cls 和 Net_prio 子系统
Net_cls: 为网络包添加 classid 标记
功能:配合 tc (traffic control) 进行流量控制
配置示例:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# 创建控制组
$ sudo cgcreate -g net_cls:/docker/container1
# 设置 classid (0x10001)
$ echo "0x10001" > /sys/fs/cgroup/net_cls/docker/container1/net_cls.classid
# 配置 tc 规则
$ sudo tc qdisc add dev eth0 root handle 1: htb
$ sudo tc class add dev eth0 parent 1: classid 1:1 htb rate 10mbit
$ sudo tc filter add dev eth0 parent 1:0 handle 1: cgroup
# 效果:容器所有网络包都标记为 0x10001,应用 tc 规则
Net_prio: 设置网络优先级
配置示例:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# 创建控制组
$ sudo cgcreate -g net_prio:/docker/container1
# 设置 eth0 接口优先级为 10
$ echo "eth0 10" > /sys/fs/cgroup/net_prio/docker/container1/net_prio.ifpriomap
# 设置多个接口
$ echo "eth0 10" > /sys/fs/cgroup/net_prio/docker/container1/net_prio.ifpriomap
$ echo "eth1 5" > /sys/fs/cgroup/net_prio/docker/container1/net_prio.ifpriomap
CGroups v2 统一架构
CGroups v2 核心改进
统一层级结构:
CGroups v1:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
/sys/fs/cgroup/
├── cpu/ # CPU 层级
│ └── docker/
├── memory/ # 内存层级
│ └── docker/
├── blkio/ # I/O 层级
│ └── docker/
└── ... # 每个子系统独立层级
问题:
├─ 配置复杂:需要在多个层级操作
├─ 线程问题:线程不能跨层级
└─ 资源冲突:不同子系统配置不一致
CGroups v2:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
/sys/fs/cgroup/
└── docker/
├── container1/ # 统一控制组
│ ├── cpu.max
│ ├── memory.max
│ ├── io.max
│ └── pids.max
└── container2/
优势:
├─ 单一层级:所有资源在一个树中
├─ 配置简单:一次设置所有资源
├─ 线程安全:支持线程粒度控制
└─ 资源协调:统一 QoS 策略
CGroups v2 资源控制器详解
1. CPU 控制器
核心文件:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
cpu.max: CPU 带宽限制
cpu.weight: CPU 权重
cpu.pressure: CPU 压力统计
配置示例:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# 创建控制组
$ sudo mkdir /sys/fs/cgroup/docker/container1
# 启用 CPU 控制器
$ echo "+cpu" > /sys/fs/cgroup/cgroup.subtree_control
# 设置 CPU 限制 (50% = 50000/100000)
$ echo "50000 100000" > /sys/fs/cgroup/docker/container1/cpu.max
# 设置 CPU 权重 (默认 100)
$ echo "200" > /sys/fs/cgroup/docker/container1/cpu.weight
# 查看 CPU 压力
$ cat /sys/fs/cgroup/docker/container1/cpu.pressure
some avg10=0.00 avg60=0.00 avg300=0.00 total=0
full avg10=0.00 avg60=0.00 avg300=0.00 total=0
2. Memory 控制器
核心文件:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
memory.max: 硬限制
memory.high: 软限制 (回收阈值)
memory.current: 当前使用
memory.stat: 详细统计
memory.oom.group: OOM 组标志
memory.pressure: 内存压力
配置示例:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# 启用内存控制器
$ echo "+memory" > /sys/fs/cgroup/cgroup.subtree_control
# 设置硬限制 (512MB)
$ echo "536870912" > /sys/fs/cgroup/docker/container1/memory.max
# 设置软限制 (256MB)
$ echo "268435456" > /sys/fs/cgroup/docker/container1/memory.high
# 查看当前使用
$ cat /sys/fs/cgroup/docker/container1/memory.current
134217728 # 128MB
# 查看统计
$ cat /sys/fs/cgroup/docker/container1/memory.stat
anon 104857600
file 20971520
kernel_stack 524288
slab 262144
sock 131072
shmem 65536
file_mapped 10485760
file_dirty 0
file_writeback 0
inactive_anon 52428800
active_anon 52428800
inactive_file 10485760
active_file 10485760
unevictable 0
slab_reclaimable 131072
slab_unreclaimable 131072
pgfault 12345
pgmajfault 234
pgrefill 567
pgscan 890
pgsteal 123
pgactivate 456
pgdeactivate 789
# OOM 组设置 (进程组一起被 OOM kill)
$ echo "1" > /sys/fs/cgroup/docker/container1/memory.oom.group
# 查看内存压力
$ cat /sys/fs/cgroup/docker/container1/memory.pressure
some avg10=0.00 avg60=0.00 avg300=0.00 total=0
full avg10=0.00 avg60=0.00 avg300=0.00 total=0
3. I/O 控制器
核心文件:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
io.max: I/O 限制
io.weight: I/O 权重
io.pressure: I/O 压力
配置示例:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# 启用 I/O 控制器
$ echo "+io" > /sys/fs/cgroup/cgroup.subtree_control
# 限制读带宽 (10MB/s)
$ echo "8:0 rbps=10485760" > /sys/fs/cgroup/docker/container1/io.max
# 限制写带宽 (5MB/s)
$ echo "8:0 wbps=5242880" > /sys/fs/cgroup/docker/container1/io.max
# 限制读 IOPS (100)
$ echo "8:0 riops=100" > /sys/fs/cgroup/docker/container1/io.max
# 限制写 IOPS (50)
$ echo "8:0 wiops=50" > /sys/fs/cgroup/docker/container1/io.max
# 设置 I/O 权重 (默认 100)
$ echo "200" > /sys/fs/cgroup/docker/container1/io.weight
# 查看 I/O 压力
$ cat /sys/fs/cgroup/docker/container1/io.pressure
some avg10=0.00 avg60=0.00 avg300=0.00 total=0
full avg10=0.00 avg60=0.00 avg300=0.00 total=0
4. PID 控制器
核心文件:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
pids.max: 最大进程数
pids.current: 当前进程数
pids.events: 事件统计
配置示例:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# 启用 PID 控制器
$ echo "+pids" > /sys/fs/cgroup/cgroup.subtree_control
# 限制 100 个进程
$ echo "100" > /sys/fs/cgroup/docker/container1/pids.max
# 查看当前进程数
$ cat /sys/fs/cgroup/docker/container1/pids.current
23
# 查看事件
$ cat /sys/fs/cgroup/docker/container1/pids.events
max 0
5. Hugetlb 控制器
核心文件:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
hugetlb.<size>.max: 大页内存限制
hugetlb.<size>.current: 当前使用
配置示例:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# 限制 2MB 大页内存为 64MB
$ echo "67108864" > /sys/fs/cgroup/docker/container1/hugetlb.2MB.max
# 限制 1GB 大页内存为 1GB
$ echo "1073741824" > /sys/fs/cgroup/docker/container1/hugetlb.1GB.max
# 查看使用
$ cat /sys/fs/cgroup/docker/container1/hugetlb.2MB.current
33554432 # 32MB
CGroups v2 PSI (Pressure Stall Information)
PSI 压力停滞信息:
功能:监控资源压力导致的性能停滞
三种资源压力:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
CPU: 等待 CPU 调度的时间
Memory: 等待内存回收的时间
I/O: 等待 I/O 完成的时间
两种模式:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
some: 部分任务停滞的时间占比
full: 所有任务都停滞的时间占比
配置示例:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# 查看 CPU 压力
$ cat /sys/fs/cgroup/docker/container1/cpu.pressure
some avg10=5.00 avg60=3.50 avg300=2.00 total=123456
full avg10=0.00 avg60=0.00 avg300=0.00 total=0
解读:
├─ some avg10=5.00: 过去 10 秒,5% 的时间有任务等待 CPU
├─ full avg10=0.00: 过去 10 秒,0% 的时间所有任务都在等待
└─ total=123456: 累积停滞时间 (微秒)
# 查看内存压力
$ cat /sys/fs/cgroup/docker/container1/memory.pressure
some avg10=10.00 avg60=8.50 avg300=5.00 total=234567
full avg10=2.00 avg60=1.50 avg300=0.50 total=12345
解读:
├─ some avg10=10.00: 10% 时间有任务等待内存
├─ full avg10=2.00: 2% 时间所有任务都在等待内存
└─ full > 0 表示内存严重不足
# 查看 I/O 压力
$ cat /sys/fs/cgroup/docker/container1/io.pressure
some avg10=15.00 avg60=12.00 avg300=8.00 total=345678
full avg10=5.00 avg60=3.00 avg300=1.00 total=23456
告警阈值:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# 设置 PSI 告警 (需要内核支持)
$ echo "some 60000 500000" > /sys/fs/cgroup/docker/container1/memory.pressure_threshold
# 当 some 压力超过 50% 持续 60 秒时触发
# 可用于自动扩缩容或告警
由于篇幅限制,让我继续创建文档的第二部分,包含 Docker/K8s 应用、实战调优和最佳实践:
更多推荐



所有评论(0)