K8S cgroups详解

以下是 Kubernetes 中 cgroups(Control Groups) 的详细解析,涵盖其核心原理、在 Kubernetes 中的具体应用及实践操作:

一、cgroups 基础概念

1. 是什么?
  • cgroups 是 Linux 内核提供的 资源隔离与控制机制,用于限制、统计和监控进程组(如容器)的资源使用。

  • 可管理的资源类型:

    • CPU:分配核心数、时间片权重

    • 内存:限制最大使用量、Swap 控制

    • I/O:磁盘和网络带宽限制

    • 进程数:防止 fork bomb

    • 设备访问:限制特定设备使用

2. 核心组件
组件 功能
Hierarchy 树状层级结构,每个层级绑定一个或多个子系统(如 CPU、Memory)
Subsystem 资源控制器(如 cpumemoryblkio),负责具体资源管理
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 Classburstable(弹性)、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 所有容器未设置 requestslimits 最低优先级,资源紧张时优先被终止
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 statskubectl top、直接查看 cgroup 文件系统。

相关推荐
CAFEBABE 3438 分钟前
安装完docker之后怎么使用
运维·docker·容器
测试人社区—小叶子1 小时前
测试开发面试高频“灵魂八问”深度解析与应答策略
网络·人工智能·测试工具·云原生·容器·面试·职场和发展
VermiliEiz3 小时前
使用二进制文件方式部署kubernetes(1)
kubernetes·云计算
kevin_水滴石穿3 小时前
centos7 离线安装docker-compose(纯绿色安装)
运维·docker·容器
java_logo5 小时前
CALIBRE-WEB Docker 容器化部署指南
前端·docker·容器·电子书·calibre·calibre-web·docker部署calibre
云计算小黄同学5 小时前
k8s中的服务通过secret访问数据库的实际案例
数据库·阿里云·kubernetes
Watermelo6176 小时前
【简单快速】windows中docker数据如何从C盘迁移到其他盘
java·运维·docker·容器·运维开发·devops·空间计算
炸裂狸花猫6 小时前
开源日志收集体系ELK
elk·elasticsearch·云原生·kubernetes·metricbeat
周杰伦_Jay7 小时前
【Docker】容器化核心与实践
运维·docker·容器