以下是 Kubernetes 中 cgroups(Control Groups) 的详细解析,涵盖其核心原理、在 Kubernetes 中的具体应用及实践操作:
一、cgroups 基础概念
1. 是什么?
cgroups 是 Linux 内核提供的 资源隔离与控制机制,用于限制、统计和监控进程组(如容器)的资源使用。
可管理的资源类型:
CPU:分配核心数、时间片权重
内存:限制最大使用量、Swap 控制
I/O:磁盘和网络带宽限制
进程数:防止 fork bomb
设备访问:限制特定设备使用
2. 核心组件
组件 | 功能 |
---|---|
Hierarchy | 树状层级结构,每个层级绑定一个或多个子系统(如 CPU、Memory) |
Subsystem | 资源控制器(如 cpu 、memory 、blkio ),负责具体资源管理 |
Cgroup | 层级中的节点,包含一组进程及其资源限制规则 |
Task | 进程(线程),属于某个 cgroup,资源受其规则约束 |
3. cgroup v1 vs v2
特性 | cgroup v1 | cgroup v2 |
---|---|---|
层级结构 | 多层级,每个子系统独立 | 单一层级,统一管理所有子系统 |
资源分配模型 | 分散控制 | 统一权重分配(如 cpu.weight ) |
内存控制 | memory.limit_in_bytes |
memory.max |
兼容性 | 广泛支持 | 需较新内核(≥4.15) |
二、Kubernetes 中的 cgroups 实现
1. 资源模型
Kubernetes 通过 Resource Requests/Limits 定义容器的资源需求,底层由容器运行时(如 containerd、Docker)转换为 cgroup 配置。
resources:
requests:
cpu: "500m" # 0.5 CPU 核心
memory: "1Gi" # 1 GB 内存
limits:
cpu: "1" # 1 CPU 核心
memory: "2Gi" # 内存硬限制
2. 核心子系统映射
Kubernetes 参数 | cgroup 子系统 | 关键文件/参数 |
---|---|---|
CPU Requests | cpu |
cpu.shares (权重) |
CPU Limits | cpu |
cpu.cfs_period_us + cpu.cfs_quota_us |
Memory Limits | memory |
memory.limit_in_bytes (v1)或 memory.max (v2) |
HugePages | hugetlb |
hugetlb.<size>.limit_in_bytes |
Ephemeral Storage | blkio (部分) |
通过 XFS 配额或 blkio.throttle 控制 |
3. cgroup 路径结构
容器 cgroup 路径示例(v1):
# 查看容器进程的 cgroup
$ cat /proc/<PID>/cgroup
# 示例输出:
12:memory:/kubepods/burstable/pod<UID>/<容器ID>
3:cpu,cpuacct:/kubepods/burstable/pod<UID>/<容器ID>
Kubernetes 层级命名规则:
/kubepods/[QoS-Class]/pod<Pod-UID>/<Container-ID>
QoS Class:
burstable
(弹性)、besteffort
(尽力而为)、guaranteed
(保证)
三、实战操作:验证 cgroup 配置
1. 查看容器的 cgroup 限制
进入容器所在节点的 cgroup 目录(以内存为例):
# 查找容器对应的 cgroup 路径
$ CONTAINER_ID=$(docker ps | grep <容器名> | awk '{print $1}')
$ CGROUP_PATH=$(docker inspect $CONTAINER_ID | grep -i cgroup | grep memory | head -1 | cut -d'"' -f4)
# 查看内存限制
$ cat /sys/fs/cgroup/memory/$CGROUP_PATH/memory.limit_in_bytes
2147483648 # 2Gi
2. 动态调整 cgroup 参数(调试用)
# 临时修改 CPU 配额(慎用!)
echo 50000 > /sys/fs/cgroup/cpu/$CGROUP_PATH/cpu.cfs_quota_us # 限制为 50ms/100ms 周期
四、Kubernetes 资源 QoS 与 cgroup
1. QoS 等级
QoS 级别 | 条件 | cgroup 表现 |
---|---|---|
Guaranteed | 所有容器设置 limits=requests |
高优先级,cpu.shares 根据 requests 分配,内存不足时最后被 OOMKill |
Burstable | 至少一个容器设置 requests<limits 或未设置 limits |
中等优先级,资源超用时可能被限制或终止 |
BestEffort | 所有容器未设置 requests 和 limits |
最低优先级,资源紧张时优先被终止 |
2. OOM 处理机制
当节点内存不足时,OOM Killer 按优先级终止容器:
BestEffort
→ 2.Burstable
→ 3.Guaranteed
查看 OOM 事件:
dmesg | grep -i "oom" journalctl -k | grep -i "oom"
五、高级配置
1. 自定义 cgroup 驱动
Kubernetes 支持两种 cgroup 驱动:
cgroupfs:直接写入 cgroup 文件系统(默认)。
systemd:通过 systemd 管理 cgroup(需节点使用 systemd)。
配置 kubelet 使用 systemd 驱动:
--cgroup-driver=systemd
2. 设置 cgroup 根目录
调整 kubelet 参数:
--cgroup-root=/custom-cgroup
3. Reserved Resources
为系统进程预留资源,避免容器占用全部资源:
# kubelet 配置
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
systemReserved:
cpu: "500m"
memory: "1Gi"
六、常见问题排查
1. 容器被 OOMKilled
检查点:
kubectl describe pod <pod-name> | grep -i "OOM" kubectl get events --field-selector=reason=OOMKilled
解决:调整
spec.containers[].resources.limits.memory
2. CPU 节流(Throttling)
检查点:
kubectl top pod --containers cat /sys/fs/cgroup/cpu/$CGROUP_PATH/cpu.stat | grep nr_throttled
解决:优化应用 CPU 使用或增加
limits.cpu
总结
核心作用:Kubernetes 通过 cgroups 实现容器资源隔离,保障多租户环境稳定性。
配置关键:合理设置
requests/limits
,结合 QoS 策略优化资源分配。调试工具:
docker stats
、kubectl top
、直接查看 cgroup 文件系统。