容器 的 cpu request limit 与 linux cgroups 的关系

Kubernetes 通过对 Cgroups 的精细控制来实现其 requestslimits 机制。

简单来说:

  • requests -> 主要对应 cpu.shares
  • limits -> 主要对应 cpu.cfs_quota_uscpu.cfs_period_us

下面我们进行详细的分解和解释。


核心概念对应关系

Kubernetes 概念 Cgroup 文件 作用机制 性质
spec.containers[].resources.requests.cpu cpu.shares 相对权重(Shares) 软限制、弹性
spec.containers[].resources.limits.cpu cpu.cfs_quota_us cpu.cfs_period_us 绝对上限(Quota) 硬限制、严格

1. CPU Request (requests.cpu) -> cpu.shares

  • 作用requests.cpu 在 Kubernetes 中表示容器请求的、保证的最小 CPU 资源量。它主要影响 Pod 的调度------调度器会确保节点上有足够的可用资源(CPU 和内存)才会将 Pod 分配上去。
  • Cgroups 实现 :Kubernetes 通过设置 Cgroup v1 的 cpu.shares 属性来实现这一点。
  • 工作原理
    • cpu.shaes 是一个相对权重,而不是一个绝对的 CPU 核心数。
    • 它的默认值是 1024。
    • Kubernetes 的计算公式大致为:容器申请的 cpu.shares = 1024 * requests.cpu
    • 例如 :如果一个容器设置了 requests.cpu: 1.5,那么它的 cpu.shares 将被设置为 1024 * 1.5 = 1536
  • 行为
    • 当节点上的 CPU 资源充足 时,一个设置了 requests.cpu 的容器可以使用的 CPU 可以超过其请求值,它几乎可以使用任何空闲的 CPU。
    • 当节点上的 CPU 资源紧张 (多个容器竞争 CPU)时,CFS(完全公平调度器)会根据每个容器的 cpu.shares 比例来分配 CPU 时间。
    • 再例如 :假设一个节点上只有两个 Pod:
      • Pod A: requests.cpu: 1 -> cpu.shares = 1024
      • Pod B: requests.cpu: 2 -> cpu.shares = 2048
      • 当两者都全力使用 CPU 时,它们将按照 1024:2048(即 1:2)的比例分配 CPU 时间。Pod A 大约获得 33% 的 CPU,Pod B 大约获得 66% 的 CPU。

总结:requests.cpu 通过 cpu.shares 确保在资源竞争时获得最低保证份额,是一种"软"限制。


2. CPU Limit (limits.cpu) -> cpu.cfs_quota_us & cpu.cfs_period_us

  • 作用limits.cpu 在 Kubernetes 中表示容器能使用的 CPU 资源的绝对硬性上限,无论节点上的 CPU 是否空闲,它都不能超过这个限制。
  • Cgroups 实现 :Kubernetes 通过设置 Cgroup v1 的 CPU 带宽控制 (CPU bandwidth control)子系统来实现,即 cpu.cfs_quota_uscpu.cfs_period_us 这两个文件。
    • cpu.cfs_period_us:定义了一个时间周期(单位:微秒),通常固定设置为 100,000 μs(即 100毫秒)。
    • cpu.cfs_quota_us:定义了在以上一个周期内,该容器最多可以使用的 CPU 时间(单位:微秒)。
  • 工作原理
    • 计算公式为:cpu.cfs_quota_us = limits.cpu * cpu.cfs_period_us
    • 例如 :如果一个容器设置了 limits.cpu: 1,那么:
      • cpu.cfs_period_us = 100000
      • cpu.cfs_quota_us = 1 * 100000 = 100000
      • 这意味着在每 100ms 的时间内,该容器最多可以使用 100ms 的 CPU 时间,即相当于独占 1 个 CPU 核心
    • 再例如 :如果一个容器设置了 limits.cpu: 1.5,那么:
      • cpu.cfs_quota_us = 1.5 * 100000 = 150000
      • 这意味着在每 100ms 的时间内,该容器最多可以使用 150ms 的 CPU 时间,即相当于独占 1.5 个 CPU 核心
    • 如果容器在周期内耗尽了它的配额(cpu.cfs_quota_us),它就会被节流(Throttled),必须等待下一个周期才能继续运行。

总结:limits.cpu 通过 cpu.cfs_quota_uscpu.cfs_period_us 设置一个严格的"天花板",是一个"硬"限制。


综合示例与实践意义

一个 Pod 的配置可以同时包含 requestslimits

apiVersion: v1

kind: Pod

metadata:

name: example-pod

spec:

containers:

  • name: example-container
    image: nginx
    resources:
    requests:
    memory: "64Mi"
    cpu: "0.5" # 请求 0.5 核
    limits:
    memory: "128Mi"
    cpu: "1" # 限制最多使用 1 核

在这个例子中:

  1. 调度:调度器会寻找至少有 0.5 核空闲 CPU 和 64MiB 空闲内存的节点。
  2. Cgroups 设置
    • CPU :
      • cpu.shares = 1024 * 0.5 = 512
      • cpu.cfs_quota_us = 1 * 100000 = 100000
      • cpu.cfs_period_us = 100000
    • 内存 :也会设置对应的 memory.limit_in_bytes 为 128MiB。

实践意义:

  • 设置 requests 而不设置 limits:容器可以弹性使用尽可能多的空闲 CPU,但在竞争时享有保证的最低份额。适用于可以充分利用空闲资源但不需要严格限制的应用。
  • 设置 limits 而不设置 requestsrequests 会默认等于 limits。这保证了 Pod 的资源,但缺乏弹性。通常不建议,除非你明确希望如此。
  • 同时设置 requestslimits:这是最常见和推荐的做法。它既保证了 Pod 的调度和最小资源,又防止 bug 或异常导致单个 Pod 耗尽整个节点的资源( noisy neighbor 问题)。

因此,Kubernetes 通过将高级别的 requestslimits 概念映射到 Cgroups 底层的不同控制机制,实现了既灵活又严格的混合资源管理策略。

相关推荐
拾贰_C29 分钟前
【OpenClaw | openai | QQ】 配置QQ qot机器人
运维·人工智能·ubuntu·面试·prompt
桌面运维家33 分钟前
服务器进程异常监控:快速定位与排障实战指南
运维·服务器
@CLoudbays_Martin1143 分钟前
UniApp是否能够接入SDK游戏盾呢?
服务器·网络·网络协议·tcp/ip·安全
念恒123061 小时前
进程控制---自定义Shell
linux·c语言
Java后端的Ai之路1 小时前
Kubernetes是什么?(小白入门版)
云原生·容器·kubernetes·教程
风曦Kisaki1 小时前
# Linux Shell 编程入门 Day02:条件测试、if 判断、循环与随机数
linux·运维·chrome
木雷坞1 小时前
视觉算法环境 Docker 镜像拉取失败排查
运维·人工智能·docker·容器
郝亚军1 小时前
ubuntu 22.04如何安装libmodbus
运维·服务器·ubuntu
李日灐1 小时前
< 6 > Linux 自动化构建工具:makefile 详解 + 进度条实战小项目
linux·运维·服务器·后端·自动化·进度条·makefile
JZC_xiaozhong2 小时前
跨系统审批自动化怎么做?从采购到销售合同的完整方案
大数据·运维·自动化·流程自动化·数据集成与应用集成·业务流程管理·异构数据集成