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 文件系统。

相关推荐
水淹萌龙3 小时前
k8s 中使用 Service 访问时NetworkPolicy不生效问题排查
云原生·容器·kubernetes
旧故新长6 小时前
访问 Docker 官方镜像源(包括代理)全部被“重置连接”或超时
运维·docker·容器
matrixlzp7 小时前
K8S Gateway AB测试、蓝绿发布、金丝雀(灰度)发布
kubernetes·gateway·ab测试
云攀登者-望正茂11 小时前
最大化效率和性能:AKS 中节点池的强大功能
云原生·容器·kubernetes
haven-85212 小时前
win11安装Joplin Server私有化部署(docker)
运维·docker·容器
QX_hao12 小时前
【docker】--数据卷挂载
docker·容器·eureka
文静小土豆12 小时前
在K8S集群中部署EFK日志收集
docker·容器·kubernetes
一个向上的运维者13 小时前
k8s的flannel生产实战与常见问题排查
云原生·容器·kubernetes
不之道13 小时前
通过 wsl 安装 docker
运维·docker·容器