ulimit
ulimit实际上是一种已经快被淘汰的资源限制工具,因为仅用于一些传统业务的机器的调优,现在都上云了
机制:
- 进程级限制:
ulimit
是传统的 Unix/Linux 资源限制工具,主要针对单个进程或用户会话(如 Shell 启动的进程)设置资源上限,例如文件描述符数量、CPU 时间、内存等。 - 局限性:其限制是“继承式”的,父进程的限制会传递给子进程,但无法对一组进程进行统一管理。
- 内核接口:通过
setrlimit
系统调用实现,属于内核的RLIMIT_*
机制
局限性:
- 功能单一:
ulimit
仅支持少数资源类型(如nproc
进程数、nofile
文件描述符) - 在容器化(Docker、Kubernetes)和微服务场景中,资源隔离需精确到组级别,cgroups 是事实标准,而 ulimit 无法满足需求。
场景 | ulimit | systemd/cgroups |
---|---|---|
限制单个进程的文件描述符数 | ulimit -n 1024 |
LimitNOFILE= |
限制容器的总内存使用 | 不适用 | docker run --memory=500m |
动态调整服务的 CPU 配额 | 不适用 | systemctl set-property 等 |
全局用户进程数限制 | /etc/security/limits.conf |
结合 cgroups 和 pam 模块 |
配置ulimit
ulimit持久化配置文件/etc/security/limits.conf
或子配置文件/etc/security/limits.d/
1 | # 查看当前所有ulimit |
cgroup v1
cgroups(Control Groups)是 Linux 内核提供的一种机制,用于对进程或进程组进行资源限制、优先级分配、资源统计和任务控制。它是现代 Linux 系统资源管理的核心组件(尤其在容器化技术中广泛应用)。
核心功能
(1) 资源限制
限制进程组使用的资源总量
- CPU 时间片(cpu)
- 内存使用量(memory)
- 磁盘 I/O 带宽(blkio)
- 网络带宽(net_cls、net_prio)
- 进程数(pids)
(2) 优先级控制
- 分配不同进程组的资源使用权重(如 CPU 优先级)。
(3) 资源统计
- 监控进程组的资源使用情况(如内存占用、CPU 时间)。
(4) 任务控制
- 冻结、恢复或终止一组进程(freezer)。
核心组件
控制器
每种资源:CPU/MM/IO等对应一个控制器
层级结构-树状结构
1 | 根目录: /sys/fs/cgroup |
控制组/任务
任务即进程,是cgroup资源管理的直接对象
控制组是进程的集合,用于关联控制器并应用资源管理策略
也就是控制组是任务的集合
cgroup文件系统
/sys/fs/cgroup
核心文件包括:
配置文件
cgroup.procs
:列出cgroup中的进程PID。cgroup.controllers
:显示可用的控制器。memory.max
:设置内存使用上限。cpu.max
:配置CPU时间分配
监控文件
cpu.stat
:统计CPU使用情况memory.usage_in_bytes
:显示当前内存使用量。
操作示例
- 限制CPU使用:
echo "50000 100000" > /sys/fs/cgroup/cpu/mygroup/cpu.max
- 添加进程:
echo 1234 > /sys/fs/cgroup/memory/mygroup/cgroup.procs
工作流程
创建层级:挂载关联CPU和内存控制器的层级。
1
2
3
4bash
mount -t cgroup -o cpu,memory none /sys/fs/cgroup/wangsheng
这就是一个控制器,叫wangsheng创建控制组:在层级下创建子cgroup。
1
2
3
4
5bash
mkdir /sys/fs/cgroup/wangsheng/ws
这是一个工作组ws
隶属于wangsheng控制器的配置资源限制:设置CPU配额
1
2
3
4bash
echo "20000 100000" > /sys/fs/cgroup/myhierarchy/cgroup/wangsheng/ws
添加一个规则添加进程:将PID为1234的进程加入cgroup。
1
2
3
4
5bash
echo 1234 > /sys/fs/cgroup/cgroup/wangsheng/ws/cgroup.procs
现在1234这个进程就属于wangsheng控制器下的ws控制组了
该组下的进程,都遵循上面的资源限制
cgroupv2
v1的局限性
如果你已经看懂了cgroup的工作流程
那么就很容易知道,在多个控制器的工作组下,一定会有cgroup.procs文件中
含有相同的PID,就会增加配置的复杂性
特性 | cgroup v1 | cgroup v2 |
---|---|---|
层级结构 | 多层级树结构,每个控制器(如 CPU、Memory)独立挂载 | 单一层级树结构,所有控制器统一挂载到 /sys/fs/cgroup |
控制粒度 | 控制器可独立配置,但可能导致规则冲突 | 统一控制模型,避免策略冲突 |
进程归属 | 一个进程可属于多个不同控制器的 cgroup | 一个进程只能属于一个 cgroup(所有控制器共享同一层级) |
v2的优越性
主要是层级结构的不同
也就是,现在同一个控制组中,可以直接定义规则,而不是通过控制器进行分类
1 | # 内存和 CPU 限制(v2) |
限制容器内存
- v1:需分别配置
memory.limit_in_bytes
和memory.swappiness
。 - v2:直接设置
memory.max
和memory.swap.max
,且支持更精细的内存回收策略。
场景 2:CPU 配额分配
- v1:通过
cpu.shares
(相对权重)或cpu.cfs_quota_us
(绝对配额)分配。 - v2:统一使用
cpu.max
文件
cgroup与systemd
cgroups 和 systemd 在现代 Linux 系统中密切相关。systemd 是 cgroups 的主要管理者和使用者,它利用 cgroups 实现服务资源隔离、进程跟踪和资源限制
slice切片
相当于逻辑组group的概念
systemd 预定义了三个核心slice
1 | system.slice 所有系统服务的默认分组 |
创建自定义slice
子slice命名规则
子slices名称需要带有父slice的名称,通过连字符分隔,
system.slice 的子 slice → system-mycustom.slice
且子slice不能超过父slice的限额
创建文件
**存放目录(自定义)/etc/systemd/system/ ****
1 | # 创建slice |
定义规则
可定义多种块:
1 | [Unit]块 |
开启审计
1 | [Slice] |