K8s中CPU和Memory的资源管理

news2025/7/8 22:37:20

资源类型

在 Kubernetes 中,Pod 作为最小的原子调度单位,所有跟调度和资源管理相关的属性都属于 Pod。其中最常用的资源就是 CPU 和 Memory。

CPU 资源

在 Kubernetes 中,一个 CPU 等于 1 个物理 CPU 核或者一个虚拟核,取决于节点是一台物理主机还是运行在某物理主机上的虚拟机。CPU 的请求是允许带小数的,比如 0.5 等价于 500m,表示请求 500 millicpu 或 0.5 个 cpu 的意思,这样 Pod 就会被分配 1 个 CPU 一半的计算能力。需要注意的是,Kubernetes 不允许设置精度小于 1m 的 CPU 资源。

Memory 资源

Memory 以 bytes 为单位,Kubernetes 支持使用 Ei、Pi、Ti、Gi、Mi、Ki(或者E、P、T、G、M、K)作为 bytes 的值。

其中 1Mi=1024*1024;1M=1000*1000,还要注意后缀的小写情况,400m实际上请求的是 0.4 字节。

资源的请求和限制

在 Kubernetes 中,CPU 是一种可压缩资源,当可压缩资源不足时,Pod 会处于 Pending 状态;而 Memory 是一种不可压缩资源,当不可压缩资源不足时,Pod 会因 OOM 而被杀掉。所以合理的请求和分配 CPU 和 Memory 资源,可以提高应用程序的性能。Pod 可以由多个 Container 组成,每个 Container 的资源配置通过累加,形成 Pod 整体的资源配置。

针对每个容器的资源请求和限制,可以通过以下字段设置:

  • spec.containers[].resources.limits.cpu

  • spec.containers[].resources.limits.memory

  • spec.containers[].resources.requests.cpu

  • spec.containers[].resources.requests.memory

下面是一个示例:

该 Pod 有两个容器,每个容器请求的 CPU 和 Memory 都是 0.25 CPU 和 64 MiB,每个容器的资源限制都是 0.5 CPU 和 128 MiB,所以该 Pod 的资源请求为 0.5 CPU 和 128 MiB,资源限制为 1 CPU 和 256 MiB。

apiVersion: v1
kind: Pod
metadata:
  name: frontend
spec:
  containers:
  - name: app
    image: images.my-company.example/app:v4
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "500m"
  - name: log-aggregator
    image: images.my-company.example/log-aggregator:v6
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "500m"

QoS模型

除了通过 limits 和 requests 限制和请求资源,Kubernetes 还会根据值的不同,为 Pod 设置优先级。当 Node 上的资源不足时,驱逐低优先级的 Pod,以保证更重要的 Pod 正常运行。这里就要介绍 Kubernetes 中的 QoS**(Quality of Service,服务质量)**。

QoS 类一共有三种:Guaranteed、Burstable 和 BestEffort。当一个 Node 耗尽资源时,Kubernetes 驱逐策略为:BestEffort Pod > Burstable Pod > Guaranteed Pod。

  • BestEffort:pod没有设置requests和limit
  • Burstable:pod设置request和limit,但request<limit
  • Guaranteed:pod设置request和limit,并且request=limit

Guaranteed

判断依据:

  • Pod 中的每一个 Container 都同时设置了 Memory limits 和 requests,且值相等

  • Pod 中的每一个 Container 都同时设置了 CPU limits 和 requests,且值相等

比如下面的 Pod 中,CPU 的请求和限制都为 0.7 CPU,Memory 的请求和限制都为 200 MiB。当该 Pod 创建后,它的 QoS Class 字段的值就是:Guaranteed。属于该类型的 Pod 具有最严格的资源限制,且最不可能被驱逐。只有当获取的资源超出 limits 值或没有可被驱逐的 BestEffort Pod 或 Burstable Pod,这些 Pod 才会被杀死。

apiVersion: v1
kind: Pod
metadata:
  name: qos-demo
  namespace: qos-example
spec:
  containers:
  - name: qos-demo-ctr
    image: nginx
    resources:
      limits:
        memory: "200Mi"
        cpu: "700m"
      requests:
        memory: "200Mi"
        cpu: "700m"

需要注意的是,当 Pod 仅设置了 limits 没有设置 requests 时,Kubernetes 会自动为它设置与 limits 相同的 requests 值。

Burstable

判断依据:

  • 不满足 Guaranteed 的判断条件

  • 至少有一个 Container 设置了 requests

在下面的 Pod 中,Memory 的限制为 200 MiB,请求为 100 MiB。两者不相等,所以被划分为 Burstable。

如果不指定 limits 的值,那么默认 limits 等于 Node 容量,允许 Pod 灵活地使用资源。如果 Node 资源不足,导致 Pod 被驱逐,只有在 BestEffort Pod 被驱逐后,Burstable Pod 才会被驱逐。

apiVersion: v1
kind: Pod
metadata:
  name: qos-demo-2
  namespace: qos-example
spec:
  containers:
  - name: qos-demo-2-ctr
    image: nginx
    resources:
      limits:
        memory: "200Mi"
      requests:
        memory: "100Mi"

BestEffort

判断依据:

  • 不满足 Guaranteed 或 Burstable 的判断条件

  • 既没有设置 limits,也没有设置 requests

属于 BestEffort 的 Pod,可以使用未分配给其他 QoS 类中的资源。如果 Node 有 16 核 CPU 可供使用,且已经为 Guaranteed Pod 分配了 4 核 CPU,那么 BestEffort Pod 可以随意使用剩余的 12 核 CPU。

如果 Node 的资源不足,那么将首先驱逐 BestEffort Pod。

apiVersion: v1
kind: Pod
metadata:
  name: qos-demo-3
  namespace: qos-example
spec:
  containers:
  - name: qos-demo-3-ctr
    image: nginx

限制范围和资源配额

默认情况下,Kubernetes 中的容器可以使用的资源是没有限制的。但是当多个用户使用同一个集群时,可能会出现有人占用过量的资源,导致其他人无法正常使用集群的情况。

限制范围和资源配额正是解决该问题的方法。其中限制范围通过 LimitRange 对象,在命名空间级别下限制 Pod 中容器的资源使用量,在创建 Pod 时,自动设置 CPU 和 Memory 的请求和限制。资源配额通过 ResourceQuota 对象,对每个命名空间的资源总量进行限制,避免命名空间中的程序无限制地使用资源。

在下面的例子中,定义了一个 LimitRange 对象。在该命名空间创建的 Pod 将遵循以下条件:

  • 如果未指定 CPU 的 requests 和 limits,则均为 0.5 CPU

  • 如果只指定了 requests,则 limits 的值在 0.1 CPU 和 1 CPU 之间

  • 如果只指定了 limits,则 request 的值与 limits 相同,低于 0.1 CPU 的设为 0.1 CPU,高于 1 CPU 的设为 1 CPU。

  • 如果命名空间存在多个 LimitRange 对象,应用哪个默认值是不确定的

apiVersion: v1
kind: LimitRange
metadata:
  name: cpu-resource-constraint
spec:
  limits:
  - default: # 此处定义默认限制值
      cpu: 500m
    defaultRequest: # 此处定义默认请求值
      cpu: 500m
    max: # max 和 min 定义限制范围
      cpu: "1"
    min:
      cpu: 100m
    type: Container

需要注意的是,当只指定了 requests,没有指定 limits 时,requests 的值大于 LimitRange 设置的 limits 的默认值,将导致 Pod 无法调度。

资源配额的流程如下:

  • 集群管理员为每个命名空间创建一个或多个 ResourceQuota 对象

  • 当用户在命名空间下创建对象时,Kubernetes 的配额系统会跟踪集群的资源使用情况,以确保使用的资源总量不超过 ResourceQuota 中的配额

  • 如果命名空间下的计算资源(CPU、Memory)被开启,则用户必须为 Pod 设置 limits 和 requests,否则系统将拒绝 Pod 的创建(或者使用 LimitRanger 解决)

下面的 ResourceQuota 定义了命名空间的资源限制:该命名空间中所有 Pod 的 CPU 总量不能超过 2,Pod 的 Memory 总量不能超过 2 GiB,PVC 的存储总量不能超过 5 GiB,Pod 的数量不能超过 10 个。

apiVersion: v1
kind: ResourceQuota
metadata:
  name: example-quota
spec:
  hard:
    cpu: "2"
    memory: 2Gi
    storage: 5Gi
    pods: "10"

CPU 管理器策略

默认情况下,kubelet 使用 CFS 配额 来对 Pod 的 CPU 进行约束。当 Node 上运行了很多 CPU 密集型任务时,Pod 可能会争夺可用的 CPU 资源,工作负载可能会迁移到不同的 CPU 核,对上下文切换敏感的工作负载的性能会受到影响。为此,kubelet 提供了可选的 CPU 管理器策略。

管理策略

CPU 管理器目前有两种策略:

  • None:默认策略

  • Static:允许为节点上具有整数型 CPU requests 的 Guaranteed Pod 赋予 CPU 亲和性和独占性。

此策略管理一个 CPU 共享池,该共享池最初包含节点上所有的 CPU 资源。可独占性 CPU 资源数量等于 CPU 总量减去通过 kubeReserved 或 systemReserved 参数指定的 CPU 数量。这些参数指定的 CPU 供 BestEffort Pod、Burstable Pod 和 Guaranteed 中请求了非整数值 CPU 的 Pod 使用。只有那些请求了整数型 CPU 的 Guaranteed Pod,才会被分配独占 CPU 资源。

上图显示了 CPU 管理器的结构。CPU 管理器使用contaimerRuntimeService接口的UpdateContainerResources方法来修改容器可以运行的 CPU。Manager 定期使用 cgroupfs 技术来与每个正在运行的容器的 CPU 资源的当前状态进行协调。

使用场景

如果工作负载具有以下场景,那么通过使用该策略,操作系统在CPU之间进行上下文切换的次数大大减少,容器里应用的性能会得到大幅提升。

  • 对 CPU 节流敏感

  • 对上下文切换敏感

  • 对处理器换成未命中敏感

验证策略

由于 CPU 管理器策略只能在 kubelet 生成新 Pod 时生效,所以简单地从 "None" 更改为 "Static" 将不会对现有的 Pod 起作用。 因此,为了正确更改节点上的 CPU 管理器策略,可以执行以下步骤:

  1. 腾空节点

  2. 停止 kubelet

  3. 删除旧的 CPU 管理器状态文件。该文件的路径默认为/var/lib/kubelet/cpu_manager_state。这将清除 CPUManager 维护的状态,以便新策略设置的 cpu-sets 不会与之冲突

  4. 编辑 kubelet 配置/var/lib/kubelet/config.yml,以将 CPU 管理器策略更改为所需的值

  5. 启动 kubelet

  6. 对需要更改其 CPU 管理器策略的每个节点重复此过程。

以下示例在config.yml添加了字段,如果该 Node 有 64 核,那么共享池将有 8 核,剩余的 56 核将用于指定了整数型 CPU 的 Guaranteed Pod。

systemReserved:
    cpu: "4"
    memory: "500m"
kubeReserved:
    cpu: "4"
    memory: "500m"
cpuManagerPolicy: "Static"

当重新启动 kubelet 后,就会新建cpu_manager_state,"policyName" 字段将从 “None” 变为 “Static”。

{"policyName":"Static","defaultCpuSet":"","checksum":1353318690}

创建一个 calculate.yml,用来验证 Static 策略是否真的生效。用 go 写了一个可以并发计算 200000 以内的素数的程序 calculate_primes。指定部署在启动了 Static 策略的 dc02-pff-500-5c24-cca-e881-3c40 节点上,并把 Pod 设置为 Guaranteed。

apiVersion: batch/v1
kind: Job
metadata:
  name: calculate-job
spec:
  template:
    metadata:
      name: calculate-job
    spec:
      nodeName: ***
      containers:
      - name: calculate-container
        image: ubuntu:latest
        command: ["./calculate_primes", "2000000"]
        resources:
          limits:
            cpu: "5"
            memory: "100Mi"
        volumeMounts:
        - name: mix-storage-volume
          mountPath: ***
      volumes:
      - name: mix-storage-volume
        persistentVolumeClaim:
          claimName: mix-storage-pvc
      restartPolicy: Never
  backoffLimit: 0

查看 Pod 可以确认确实为 Guaranteed。

通过 taskset -cp PID 和 cat cpu_manager_state 可以查看 calculate_primes 进程使用了序号为 8-12 的5个 CPU,表明 Static 策略生效,程序可以独占 CPU。

而使用 None 策略时,通过 taskset -cp PID 命令可以查看当前进程并不会独占 CPU,而是在 64 个 CPU 间随意切换。

CPU、Memory 限制和请求的最佳实践

Natan Yellin 通过“口渴的探险家”和“披萨派对”的例子,给出了关于 CPU 、Memory 限制和请求的最佳实践。

省略版

永远设置 Memory limits == requests

绝不设置 CPU limits

口渴的探险家

在该故事中,CPU 就是水,CPU 饥饿就是死亡。A 和 B 在沙漠中旅行,他们有一个神奇的水瓶,每天可以产生 3 升水,每人每天需要 1 升水才能存活。

情景1:without limits, without requests

A 很贪婪,在 B 之前喝光了所有的水,导致 B 渴死。因为没有限制和请求,所以 A 能喝掉所有的水,导致 CPU 饥饿。

情景2:with limits, with or without requests

A 和 B 都喝了 1 升水,但是 A 生病了,需要额外的水,B 不让 A 喝,因为 A 的限制是每天 1 升水,所以 A 渴死了。当有 CPU 限制时,就可能发生这种情况,即使有很多资源,也无法使用。

情景3:without limits, with requests

这次轮到 B 生病了,需要额外的水,但是当喝到只剩 1 升水时停下了,因为 A 每天需要 1 升水。两个人都活了下来。当没有 CPU 限制但有请求时就会出现这种情况,一切正常。

用表格概括一下 limits 和 requests 的区别

PodCPU limitsNo CPU limits
CPU requests能使用的CPU 在 requests和limits之间无法使用更多的 CPU能够使用 requests 指定的 CPU 数量多余的CPU也能用,不会造成浪费
No CPU requests能够使用 limits 指定的 CPU 数量无法使用更多的 CPU随意使用可能会耗尽节点资源

Kubernetes 给出了解释:

Pod 保证能够获得所请求的 CPU 数量,如果没有 limits,可能会使用多余的 CPU,但不会抢占其他正在运行任务的CPU。

披萨派对

想象一个披萨派对,每个人点 2 片,最多可以吃 4 片,相当于 requests = 2,limits = 4。但在订购披萨的时候,是按每人 2 片的数量订的。派对开始了,每张桌子都为坐下的人准备了 2 片披萨,谁都可以拿。但是在你准备吃的时候发现披萨没有了,此时一个保镖出来把正在吃披萨的另一个人击倒,收集剩下的披萨(准确地说是也包括这个人吃过的披萨),给桌子上的其他人吃。并把刚才的那个人安排到另一张有更多披萨的桌子上。

当 Node 上的 Memory 不足时(OOM),就会出现这种情况。Pod 访问不可用的 Memory,就会因 OOM 而被终止。如果客人只允许吃掉所订购数量的披萨,即 requests = limits,那么大家都将相安无事。

总结

在 Kubernetes 中,CPU 和 Memory 资源的管理和分配是非常重要的。通过合理地分配和管理这些资源,可以确保 Kubernetes 集群的稳定性和可用性,提高应用程序的性能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2328552.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

任务挂起和恢复

任务挂起和恢复API函数 下面用按键和震动传感器验证任务挂起和恢复API函数&#xff1a; PA7接震动传感器&#xff0c;按键引脚为PA0&#xff0c;提前初始化好GPIO引脚 key.c #include "key.h" #include "stm32f10x.h"void KeyInit() {GPIO_InitTypeDef …

【NLP 55、投机采样加速推理】

目录 一、投机采样 二、投机采样改进&#xff1a;美杜莎模型 流程 改进 三、Deepseek的投机采样 流程 Ⅰ、输入文本预处理 Ⅱ、引导模型预测 Ⅲ、候选集筛选&#xff08;可选&#xff09; Ⅳ、主模型验证 Ⅴ、生成输出与循环 骗你的&#xff0c;其实我在意透了 —— 25.4.4 一、…

如何在 Windows 上安装 Python

Python是一种高级编程语言&#xff0c;由于其简单性、多功能性和广泛的应用范围而变得越来越流行。如何在 Windows 操作系统中安装 Python 的过程相对简单&#xff0c;只需几个简单的步骤。 本文旨在指导您完成在 Windows 计算机上下载和安装 Python 的过程。 如何在 Windows…

selectdb修改表副本

如果想修改doris&#xff08;也就是selectdb数据库&#xff09;表的副本数需要首先确定是否分区表&#xff0c;当前没有数据字典得知哪个表是分区的&#xff0c;只能先show partitions看结果 首先&#xff0c;副本数不应该大于be节点数 其次&#xff0c;修改期间最好不要跑业务…

Metabase:一个免费开源的BI平台

今天给大家介绍一个开源数据可视化分析工具&#xff1a;Metabase。它可以帮助用户快速连接数据库、执行查询并创建交互式仪表盘&#xff0c;即使非技术人员也能快速上手。 Metabase 支持多种数据源&#xff0c;包括 MySQL、PostgreSQL、Oracle、SQL Server、SQLite、MongoDB、P…

第15届蓝桥杯省赛python组A,B,C集合

过几天就省赛了&#xff0c;一直以来用的是C&#xff0c;Python蓝桥杯也是刚刚开始准备&#xff08;虽然深度学习用的都是python&#xff0c;但是两者基本没有任何关系&#xff09;&#xff0c;这两天在做去年题时犯了很多低级错误&#xff0c;因此记录一下以便自己复查 PS&am…

为什么有的深度学习训练,有训练集、验证集、测试集3个划分,有的只是划分训练集和测试集?

在机器学习和深度学习中&#xff0c;数据集的划分方式取决于任务需求、数据量以及模型开发流程的严谨性。 1. 三者划分&#xff1a;训练集、验证集、测试集 目的 训练集&#xff08;Training Set&#xff09;&#xff1a;用于模型参数的直接训练。验证集&#xff08;Validati…

虚拟现实 UI 设计:打造沉浸式用户体验

VR UI 设计基础与特点 虚拟现实技术近年来发展迅猛&#xff0c;其独特的沉浸式体验吸引了众多领域的关注与应用。在 VR 环境中&#xff0c;UI 设计扮演着至关重要的角色&#xff0c;它是用户与虚拟世界交互的桥梁。与传统 UI 设计相比&#xff0c;VR UI 设计具有显著的特点。传…

前端Uniapp接入UviewPlus详细教程!!!

相信大家在引入UviewPlusUI时遇到很头疼的问题&#xff0c;那就是明明自己是按照官网教程一步一步的走&#xff0c;为什么到处都是bug呢&#xff1f;今天我一定要把这个让人头疼的问题解决了&#xff01; 1.查看插件市场 重点&#xff1a; 我们打开Dcloud插件市场搜素uviewPl…

【性能优化点滴】odygrd/quill在编译期做了哪些优化

Quill 是一个高性能的 C 日志库&#xff0c;它在编译器层面进行了大量优化以确保极低的运行时开销。以下是 Quill 在编译器优化方面的关键技术和实现细节&#xff1a; 1. 编译时字符串解析与格式校验 Quill 在编译时完成格式字符串的解析和校验&#xff0c;避免运行时开销&…

02 反射 泛型(II)

目录 一、反射 1. 反射引入 2. 创建对象 3. 反射核心用法 二、泛型 1. 泛型的重要性 &#xff08;1&#xff09;解决类型安全问题 &#xff08;2&#xff09;避免重复代码 &#xff08;3&#xff09;提高可读性和维护性 2. 泛型用法 &#xff08;1&#xff09;泛型类 …

元宇宙浪潮下,前端开发如何“乘风破浪”?

一、元宇宙对前端开发的新要求 元宇宙的兴起&#xff0c;为前端开发领域带来了全新的挑战与机遇。元宇宙作为一个高度集成、多维互动的虚拟世界&#xff0c;要求前端开发不仅具备传统网页开发的能力&#xff0c;还需要掌握虚拟现实&#xff08;VR&#xff09;、增强现实&#…

2025年3月 Scratch 图形化(二级)真题解析 中国电子学会全国青少年软件编程等级考试

2025.03Scratch图形化编程等级考试二级真题试卷 一、选择题 第 1 题 甲、乙、丙、丁、戊五人参加100米跑比赛&#xff0c;甲说:“我的前面至少有两人&#xff0c;但我比丁快。”乙说:“我的前面是戊。”丙说:“我的后面还有两个人。”请从前往后&#xff08;按照速度快慢&a…

从代码学习深度学习 - GRU PyTorch版

文章目录 前言一、GRU模型介绍1.1 GRU的核心机制1.2 GRU的优势1.3 PyTorch中的实现二、数据加载与预处理2.1 代码实现2.2 解析三、GRU模型定义3.1 代码实现3.2 实例化3.3 解析四、训练与预测4.1 代码实现(utils_for_train.py)4.2 在GRU.ipynb中的使用4.3 输出与可视化4.4 解析…

二叉树 递归

本篇基于b站灵茶山艾府的课上例题与课后作业。 104. 二叉树的最大深度 给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&…

反常积分和定积分的应用 2

世界尚有同类 前言伽马函数的推论关于数学的思考平面图形的面积笛卡尔心形线伯努利双纽线回顾参数方程求面积星型线摆线 旋转体体积一般轴线旋转被积函数有负数部分曲线的弧长最后一个部分内容-旋转曲面侧表面积直角坐标系极坐标系参数方程 总结 前言 力大出奇迹。好好加油。 …

Element-plus弹出框popover,使用自定义的图标选择组件

自定义的图标选择组件是若依的项目的 1. 若依的图标选择组件 js文件&#xff0c;引入所有的svg图片 let icons [] // 注意这里的路径&#xff0c;一定要是自己svg图片的路径 const modules import.meta.glob(./../../assets/icons/svg/*.svg); for (const path in modules)…

思维链 Chain-of-Thought(COT)

思维链 Chain-of-Thought&#xff08;COT&#xff09;&#xff1a;思维链的启蒙 3. 思维链 Chain-of-Thought&#xff08;COT&#xff09;存在问题&#xff1f;2. 思维链 Chain-of-Thought&#xff08;COT&#xff09;是思路是什么&#xff1f;1. 什么是 思维链 Chain-of-Thoug…

硬件电路(23)-输入隔离高低电平有效切换电路

一、概述 项目中为了防止信号干扰需要加一些隔离电路&#xff0c;而且有时传感器的信号是高有效有时是低有效&#xff0c;所以基于此背景&#xff0c;设计了一款方便实现高低电平有效检测切换电路。 二、应用电路

大模型学习二:DeepSeek R1+蒸馏模型组本地部署与调用

一、说明 DeepSeek R1蒸馏模型组是基于DeepSeek-R1模型体系&#xff0c;通过知识蒸馏技术优化形成的系列模型&#xff0c;旨在平衡性能与效率。 1、技术路径与核心能力 基础架构与训练方法‌ ‌DeepSeek-R1-Zero‌&#xff1a;通过强化学习&#xff08;RL&#xff09;训练&…