发布时间:2026/8/11 18:12:06
【Kubernetes从入门到精通】第30篇:QoS——K8s的“三六九等“资源优先级 上一篇【第29篇】污点和容忍——K8s的“拒之门外“机制下一篇【第31篇】LimitRange——给你的Namespace画个圈摘要上篇咱们聊了资源请求requests和限制limits怎么配但你有没有想过一个问题K8s集群资源紧张的时候杀谁不杀谁不是随机砍的——K8s有一套严格的等级制度叫QoSQuality of Service把Pod分成三等Guaranteed皇亲国戚requestslimits全设且相等、Burstable中产阶级设了requests但对不上limits、BestEffort底层打工人啥都没设。等级不同待遇天差地别——OOM Score从最低的-998Guaranteed基本不死到最高的1000BestEffort首选开刀驱逐顺序也是从BestEffort开始一层层清退。本文就把这三六九等的规则掰碎告诉你QoS等级怎么判定、OOM Score怎么打分、生产环境怎么用Guaranteed保护核心服务——让你的金牌Pod永远不会被误杀。一、三种QoS等级怎么判定——“你是不是亲生的”1.1 判定规则——一张流程图搞定【QoS 等级判定流程——你是哪一级】 开始 │ ▼ ┌─────────────────────────────┐ │ 每个容器都设置了 │ │ requests 和 limits │──No──┐ └─────────────┬───────────────┘ │ │ Yes │ ▼ ▼ ┌─────────────────────────────┐ ┌─────────────────────────────┐ │ 每个容器都 │ │ 至少有一个容器没设 │ │ requests.cpu limits.cpu │ │ requests 或 limits │ │ AND │ │ │ │ requests.mem limits.mem│ │ → BestEffort底层打工人 │ │ │ │ 谁都可以压缩、最先被驱逐 │ └─────────────┬───────────────┘ └─────────────────────────────┘ │ ┌────────┴────────┐ │ Yes │ No ▼ ▼ ┌───────────┐ ┌───────────┐ │Guaranteed│ │ Burstable │ │皇亲国戚│ │中产阶级│ │requests │ │设了requests│ │limits │ │但不等limits│ └───────────┘ └───────────┘1.2 三个等级的YAML实例# # 等级1GuaranteedVIP# # 条件所有容器的 requests limitsCPU和内存都要相等apiVersion:v1kind:Podmetadata:name:guaranteed-podspec:containers:-name:appimage:nginxresources:requests:cpu:500m# ← 相等memory:512Mi# ← 相等limits:cpu:500m# ← 相等memory:512Mi# ← 相等# ✓ 单容器requestslimits → Guaranteed---# # 等级2Burstable中产阶级——最常见# # 条件至少一个容器设了requests或limits但不满足GuaranteedapiVersion:v1kind:Podmetadata:name:burstable-podspec:containers:-name:appimage:nginxresources:requests:cpu:200m# 设了requestsmemory:256Milimits:cpu:1000m# limits和requests不相等memory:512Mi# limits和requests不相等# ✓ 设了requests但不等limits → Burstable# 这也是最常见的配置——大部分生产Pod都是Burstable---# # 等级3BestEffort底层打工人# # 条件没有任何容器设置requests或limitsapiVersion:v1kind:Podmetadata:name:besteffort-podspec:containers:-name:appimage:nginx# 没有 resources 字段# ✗ 没设任何资源 → BestEffort# 这个Pod在资源紧张时是第一个被驱逐的1.3 容易搞错的判定细节【QoS判定中的陷阱】 场景1多容器Pod——一个容器满足Guaranteed不算数 ┌─────────────────────────────────────────────────┐ │ containers: │ │ - name: app │ │ resources: │ │ requests: {cpu:500m, mem:512Mi} │ │ limits: {cpu:500m, mem:512Mi} ← Guaranteed条件 │ │ - name: sidecar │ │ resources: │ │ requests: {cpu:100m, mem:128Mi} │ │ limits: {cpu:200m, mem:256Mi} ← 不等 │ │ │ │ 判定Burstable不是Guaranteed │ │ 原因sidecar的requests≠limits拖了后腿 │ └─────────────────────────────────────────────────┘ 场景2只设了limits没设requests ┌─────────────────────────────────────────────────┐ │ containers: │ │ - name: app │ │ resources: │ │ limits: │ │ cpu: 500m │ │ memory: 512Mi │ │ # 没设requests │ │ │ │ 判定Burstable │ │ 原因K8s自动把requestslimits至少有一个 │ │ 容器设了requests或limits就算Burstable │ │ 注意自动补的requests和limits是相等的 │ │ 但QoS判定只看你显式设的 │ └─────────────────────────────────────────────────┘ 场景3只设requests不设limits ┌─────────────────────────────────────────────────┐ │ containers: │ │ - name: app │ │ resources: │ │ requests: │ │ cpu: 200m │ │ memory: 256Mi │ │ # 没设limits │ │ │ │ 判定Burstable │ │ 原因至少一个资源requests设了 │ │ 效果可以用到Node上所有剩余资源 │ │ 但OOM时不会像Guaranteed那样被保护 │ └─────────────────────────────────────────────────┘配置情况QoS等级特征所有容器 requestslimitsCPU和内存都等Guaranteed最高保护级别至少一个容器设了requests或limits但不满足GuaranteedBurstable最常见的等级所有容器都没设requests和limitsBestEffort最低保护级别要点QoS是Pod级别的——哪怕你有一个容器配得完美满足Guaranteed只要另一个容器拉了后腿整个Pod就降级。这也是为什么Istio/Envoy这类Sidecar注入要特别小心——它给你的Pod加了个没设资源的Sidecar容器直接把你的Guaranteed拉成了BestEffort二、OOM Score——“你的生存分是多少”2.1 三级QoS的OOM Score差异【OOM Score 计分——Linux内核的生死簿】 OOM Score 计算公式简化 ┌─────────────────────────────────────────────────────────┐ │ │ │ oom_score (进程内存占用 / 系统总内存) × 1000 │ │ oom_score_adj │ │ │ │ K8s设置的 oom_score_adj │ │ │ │ Guaranteed Pod │ │ ┌──────────────────────────────────────────────────┐ │ │ │ oom_score_adj -998 │ │ │ │ (即使node OOM基本也不会被杀除非整个内存炸了) │ │ │ │ oom_score 范围-998 ~ -900 │ │ │ │ 生存概率★★★★★ 接近100% │ │ │ └──────────────────────────────────────────────────┘ │ │ │ │ Burstable Pod │ │ ┌──────────────────────────────────────────────────┐ │ │ │ oom_score_adj min(max(2, │ │ │ │ 1000 - 1000 × (request/limit) ), 999) │ │ │ │ │ │ │ │ 例mem request256Mi, limit512Mi │ │ │ │ score_adj 1000 - 1000×0.5 500 │ │ │ │ oom_score 范围500 ~ 1500 │ │ │ │ 生存概率★★★☆☆ 中等 │ │ │ └──────────────────────────────────────────────────┘ │ │ │ │ BestEffort Pod │ │ ┌──────────────────────────────────────────────────┐ │ │ │ oom_score_adj 1000 │ │ │ │ oom_score 范围1000 ~ 2000 │ │ │ │ 生存概率★☆☆☆☆ 随时可能被砍 │ │ │ └──────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────┘# 查看Pod的OOM Score# 方法1进入Node查看进程的oom_score_adjkubectl get pod guaranteed-pod-owide# NODE: worker-1sshworker-1# 找到容器进程PIDcat/proc/$(dockerinspect-f{{.State.Pid}}container_id)/oom_score_adj# -998 ← Guaranteed Pod# 500 ← Burstable Pod# 1000 ← BestEffort Pod# 方法2用kubectl describe查看QoS等级kubectl describe pod guaranteed-pod|grepQoS Class# QoS Class: Guaranteedkubectl describe pod burstable-pod|grepQoS Class# QoS Class: Burstablekubectl describe pod besteffort-pod|grepQoS Class# QoS Class: BestEffort2.2 为什么BestEffort第一个被杀【驱逐链路——资源紧张时的选择性牺牲】 时刻1Node内存开始紧张 ┌─────────────────────────────────────────────────────────┐ │ Node-1: 8Gi 内存 │ │ ┌────────────────────────────────────────────────┐ │ │ │ ████████████████████████████░░░░░░░░░░░░░░░░░░│ │ │ │ 已用 6.5Gi 剩余 1.5Gi │ │ │ └────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────┘ 时刻2内存持续增长触发Eviction阈值 ┌─────────────────────────────────────────────────────────┐ │ Node-1: 已用 7.2Gi (90%)超过 eviction-hard 阈值 │ │ │ │ kubelet 驱逐决策 │ │ ┌────────────────────────────────────────────┐ │ │ │ 第1波驱逐所有 BestEffort Pod → 直接杀掉 │ │ │ │ 第2波驱逐Burstable中超出request最多的Pod │ │ │ │ 第3波驱逐剩余Burstable Pod │ │ │ │ 第4波驱逐理论上Guaranteed Pod │ │ │ │ 实际上系统和kubelet会死保它们 │ │ │ └────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────┘ 时刻3内存恢复安全水位 ┌─────────────────────────────────────────────────────────┐ │ Node-1: 已用 5.8Gi (72%) │ │ Scheduler 在别的Node上重建被驱逐的Pod │ └─────────────────────────────────────────────────────────┘要点驱逐是排队枪毙式的——BestEffort打头阵Burstable按超出request的比例排第二梯队Guaranteed在最后面。注意kubelet驱逐的是整个Pod不是单个容器按Pod级别的资源使用量排序。即使你的BackEffort Pod只用了10Mi内存只要Node内存紧张它也会被优先驱逐。三、驱逐机制详解——“kubelet的水位线”3.1 kubelet的驱逐阈值【Eviction 阈值——kubelet 的警戒水位线】 ┌─────────────────────────────────────────────────────────┐ │ Node 内存状态 │ │ │ │ 100% ████████████████████████████████████████████████ │ │ │ │ │ 95% ├── eviction-hard 阈值内存 100Mi → 开始驱逐 │ │ │ ┌───────────────────────────────────────┐ │ │ │ │ 触发条件默认 │ │ │ │ │ • memory.available 100Mi │ │ │ │ │ • nodefs.available 10% │ │ │ │ │ • imagefs.available 15% │ │ │ │ └───────────────────────────────────────┘ │ │ 85% ├── eviction-soft 阈值默认不启用 │ │ │ │ │ 70% ├── 安全水位——正常运行 │ │ │ │ │ 50% │ │ │ │ │ │ 0% └─────────────────────────────────────────────────│ └─────────────────────────────────────────────────────────┘# 查看kubelet的驱逐配置kubectl describenodeworker-1|grep-A10Conditions:# 或者直接看kubelet配置cat/var/lib/kubelet/config.yaml|grep-A10eviction# evictionHard:# memory.available: 100Mi# nodefs.available: 10%# nodefs.inodesFree: 5%# imagefs.available: 15%# 自定义kubelet驱逐配置kubelet配置文件apiVersion:kubelet.config.k8s.io/v1beta1kind:KubeletConfigurationevictionHard:memory.available:200Mi# 提高到200Mi——更保守nodefs.available:10%imagefs.available:15%evictionSoft:memory.available:500Mi# 软阈值到达500Mi时evictionSoftGracePeriod:memory.available:60s# 持续60秒后才触发驱逐evictionMaxPodGracePeriod:120# 驱逐时最长优雅关闭时间3.2 驱逐优先级排序——“先杀谁”【Eviction 排序算法——排好队一个个来】 排序因子 ┌─────────────────────────────────────────────────────────┐ │ 1. QoS等级权重最大 │ │ BestEffort Burstable Guaranteed │ │ │ │ 2. 同一QoS内按超出部分占比排序 │ │ (Pod实际使用量 - Pod request) / Pod实际使用量 │ │ 这个比例越大的Pod越先被驱逐 │ │ 说明它多占了更多 │ │ │ │ 3. Priority优先级 │ │ 低优先级的Pod先驱逐 │ └─────────────────────────────────────────────────────────┘ 举例——3个Burstable Pod的驱逐顺序 ┌──────────┬──────────┬──────────┬──────────┬──────────┐ │ Pod │ Request │ Usage │ 超出量 │ 超出比例 │ 驱逐顺序 │ ├──────────┼──────────┼──────────┼──────────┼──────────┤ │ Burst-A │ 256Mi │ 800Mi │ 544Mi │ 68% │ 第1个 │ │ Burst-B │ 512Mi │ 900Mi │ 388Mi │ 43% │ 第2个 │ │ Burst-C │ 512Mi │ 600Mi │ 88Mi │ 15% │ 第3个 │ └──────────┴──────────┴──────────┴──────────┴──────────┘3.3 驱逐过程——Pod是怎么被请走的# 查看Pod被驱逐的原因kubectl describe pod evicted-pod# Status: Failed# Reason: Evicted# Message: The node was low on resource: memory.# Threshold quantity: 100Mi, available: 80Mi# 被驱逐的Pod的状态kubectl get pod evicted-pod# NAME READY STATUS RESTARTS AGE# evicted-pod 0/1 Evicted 0 5m# 被驱逐的Pod会在其他Node上重建如果由Deployment管理kubectl get pod-lappmy-app# NAME READY STATUS NODE# my-app-new-001 1/1 Running worker-2 ← 被驱逐了但在别的Node重建了要点驱逐不是杀掉再原地重启——是被驱逐的Pod从当前Node强行移除由Scheduler在别的Node上重新调度一个新的Pod。这就是为什么驱逐期间会有短暂的请求中断——旧Pod被驱了新Pod还没Ready。如果你的业务对可用性要求极高保证至少3个副本 用Guaranteed QoS 配好PodDisruptionBudget。四、生产环境QoS最佳实践4.1 QoS等级选择策略【按服务重要性选择QoS等级】 Tier 1核心业务支付、订单、用户登录 ┌─────────────────────────────────────────────────┐ │ QoS: Guaranteed │ │ requests limits相等 │ │ 原因绝不能因为资源紧张被杀宁可少部署几个 │ │ 代价资源预留较多弹性空间小 │ │ 适合对稳定性要求极高的核心服务 │ └─────────────────────────────────────────────────┘ Tier 2普通业务API服务、后台任务、前端页面 ┌─────────────────────────────────────────────────┐ │ QoS: Burstable │ │ requests limits不等 │ │ 原因平时用很少高峰可以多申请有一定保护 │ │ 代价可能被驱逐但概率较低 │ │ 适合大部分Web服务 │ └─────────────────────────────────────────────────┘ Tier 3可牺牲任务批处理、调试Pod、临时测试 ┌─────────────────────────────────────────────────┐ │ QoS: BestEffort │ │ 不设requests和limits │ │ 原因用完就扔的任务被杀也不心疼 │ │ 适合CI/CD任务、临时调试、一次性脚本 │ └─────────────────────────────────────────────────┘4.2 实战给核心服务套上Guaranteed金钟罩# 核心支付服务——Guaranteed QoSapiVersion:apps/v1kind:Deploymentmetadata:name:payment-servicespec:replicas:3selector:matchLabels:app:paymenttemplate:metadata:labels:app:paymentspec:# 高优先级——配合QoS保护priorityClassName:high-priority# Pod反亲和性——分散到不同Nodeaffinity:podAntiAffinity:requiredDuringSchedulingIgnoredDuringExecution:-labelSelector:matchExpressions:-key:appoperator:Invalues:-paymenttopologyKey:kubernetes.io/hostnamecontainers:-name:paymentimage:payment:v3.2resources:requests:cpu:2000m# ← 相等 → Guaranteedmemory:4Gi# ← 相等 → Guaranteedlimits:cpu:2000m# ← 相等memory:4Gi# ← 相等# 结果QoS Guaranteed, OOM Score -998# → 除非整个Node的内存都被吃光了否则这个Pod不会死# 普通Web服务——Burstable QoS最常见的配置apiVersion:apps/v1kind:Deploymentmetadata:name:web-frontendspec:replicas:5selector:matchLabels:app:webtemplate:metadata:labels:app:webspec:containers:-name:nginximage:nginx:1.25resources:requests:cpu:200m# 保证200mmemory:256Mi# 保证256Milimits:cpu:1000m# 最多1000m不等于memory:512Mi# 最多512Mi不等于# 结果QoS Burstable# 好处平时用很少省资源高峰可以爆发到limit4.3 关于Sidecar容器的QoS陷阱——“队友拖后腿”# 场景你给应用配了完美的Guaranteed# 但Istio自动注入了一个Sidecar——QoS被拖累apiVersion:v1kind:Podmetadata:name:app-with-sidecarannotations:sidecar.istio.io/inject:true# Istio自动注入spec:containers:-name:appimage:my-app:v1resources:requests:cpu:500mmemory:512Milimits:cpu:500m# ← 完美Guaranteedmemory:512Mi# Istio自动注入的Sidecar容器——拖后腿-name:istio-proxy# ← 这个容器是自动加的image:istio/proxyv2# 注意这个Sidecar可能没设resources或requests≠limits# → 整个Pod的QoS从Guaranteed降级为Burstable# 解决方案给Sidecar也配好resources---apiVersion:v1kind:Podmetadata:name:app-with-sidecar-fixedannotations:# Istio配置——给Sidecar设资源sidecar.istio.io/proxyCPU:100msidecar.istio.io/proxyCPULimit:100m# ← 相等sidecar.istio.io/proxyMemory:128Misidecar.istio.io/proxyMemoryLimit:128Mi# ← 相等spec:containers:-name:appimage:my-app:v1resources:requests:{cpu:500m,memory:512Mi}limits:{cpu:500m,memory:512Mi}# 现在app和istio-proxy都是requestslimits → Global QoS Guaranteed要点Service MeshIstio/Linkerd的Sidecar注入是Guaranteed QoS的隐形杀手——你辛辛苦苦配好Guaranteed结果Sidecar一来全给你拉成Burstable。解决方案(1) 给Sidecar也配requestslimits(2) 或者接受Burstable但至少保证Sidecar有足够的requests。本篇小结QoS是K8s资源管理的等级制度决定了资源紧张时谁先被牺牲三种等级判断Guaranteed所有容器requestslimits、Burstable有requests但不等于limits、BestEffort啥都没设OOM Score是天差地别Guaranteed是-998接近免死Burstable在0-999之间BestEffort是1000首选开刀驱逐是排队枪毙BestEffort先死→Burstable按超量比例排→Guaranteed最后基本不死核心服务用Guaranteed——虽然多占点资源但换来的是OOM保护很值Sidecar是QoS杀手——Istio/Envoy注入后如果没配resources会把你的Guaranteed拖成Burstable甚至BestEffortQoS是Pod级别的保护但如果你管理着一个多团队共享的集群光靠QoS不够——还得用LimitRange给每个Namespace画个圈强制约束Pod的资源声明。下一篇咱们聊LimitRange——给你的Namespace立规矩。上一篇【第29篇】污点和容忍——K8s的“拒之门外“机制下一篇【第31篇】LimitRange——给你的Namespace画个圈

相关新闻

2026/8/11 18:12:06

ROM/FLASH/RAM

ROM(只读存储器)、RAM(随机存取存储器)和FLASH(闪存)是计算机和电子设备中常见的三种存储技术,它们在功能、特性和应用场景上存在显著差异1. ROM(只读存储器,Read-Only M…

2026/8/11 18:12:06

3步掌握专业激光雕刻:免费开源工具LaserGRBL终极指南

3步掌握专业激光雕刻:免费开源工具LaserGRBL终极指南 【免费下载链接】LaserGRBL Laser optimized GUI for GRBL 项目地址: https://gitcode.com/gh_mirrors/la/LaserGRBL 你是否曾梦想用激光雕刻创造精美作品,却被昂贵的专业软件吓退&#xff1f…

2026/8/11 18:12:06

数据结构:双向链表

1.代码&#xff1a;​#include <stdio.h> #include <malloc.h>typedef struct DoubleLinkedNode {char data;struct DoubleLinkedNode *previous;struct DoubleLinkedNode *next; }DLNode,*DLNodePtr;DLNodePtr initLinkList() {DLNodePtr tempHeader (DLNodePtr)…

2026/8/11 18:47:24

农业机械装配完整性检查:支架、附件和管路如何避免漏装?

农机整机装配完成后&#xff0c;如果已经具备3D CAD模型&#xff0c;可以通过“CAD标准模型 现场AR叠加 逐项检查计划”的方式检查零件是否齐全。安宝特拓影 Twyn 农业机械AR视觉质检方案可将CAD设计数据与现场实物实时对齐&#xff0c;辅助质检人员检查支架、附件、结构件等…

2026/8/11 18:47:23

安宝特M400用户评价:企业实测中的使用体验与效果如何?

从现有企业应用和公开案例看&#xff0c;M400获得较多正向反馈的核心并不在“AR显示有多炫”&#xff0c;而在第一视角、解放双手、远程专家协作和数字化作业指导能够进入真实工作流程。尤其是在设备维修、生产换型、现场巡检、售后服务和人员培训等场景&#xff0c;现场人员需…

2026/8/11 18:37:07

Blender模拟结构光3D Scanner(三)获取相机观测点云的真值

模拟结构光3D Scanner时&#xff0c;常见的一个问题是如何获取重建点云的真值&#xff1f;在Blender中&#xff0c;可以使用光线求交的方法&#xff0c;从相机光心沿各像素发出射线&#xff0c;与场景物体求交&#xff0c;并将交点导出为点云文件。 本文介绍了一个Blender插件&…

2026/8/11 3:03:40

如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片&#xff1a;Python开源工具完整指南 【免费下载链接】chinese_license_plate_generator 中国车牌生成器 项目地址: https://gitcode.com/gh_mirrors/ch/chinese_license_plate_generator 中国车牌生成器是一个基于Python的开源项目&#xff0c…

2026/8/11 5:34:14

当 LLM 遇见大文档:主流开源项目如何处理上下文超限

从 Agentic Loop 到 Repo Map&#xff0c;七种策略与六类陷阱引言&#xff1a;128K vs 10MB 的硬冲突 2026 年的 LLM 上下文窗口已达到 128K ~ 1M token&#xff08;≈ 0.5MB ~ 4MB 文本&#xff09;&#xff0c;但 LLM 想要处理的真实数据规模远远超过这个量级&#xff1a;真实…

2026/8/11 0:00:39

前后端分离项目中控制台与接口工具数据差异排查指南

1. 问题现象解析&#xff1a;控制台与Apifox的数据差异 最近在调试一个前后端分离项目时&#xff0c;遇到了一个典型问题&#xff1a;后端服务在本地开发环境控制台能正常输出查询数据&#xff0c;但通过Apifox测试时却返回空结果。这种"控制台有数据&#xff0c;接口工具…

2026/8/11 0:00:39

AI编程实战:从Claude Code踩坑到游戏开发入门

1. 从“AI能帮我做游戏”到“AI让我重新学编程”最近身边不少朋友&#xff0c;尤其是一些非技术背景、但对游戏开发有浓厚兴趣的朋友&#xff0c;都在问我同一个问题&#xff1a;“听说现在用Claude Code这种AI编程工具&#xff0c;小白也能做游戏了&#xff0c;是真的吗&#…

2026/8/10 11:20:30

实测才敢推 AI论文网站 2026最新测评与推荐

2026年真正好用的AI论文网站&#xff0c;核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测&#xff0c;千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队&#xff0c;覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。一、综…

2026/8/11 17:06:59

2026必备!AI论文网站测评:最新推荐与深度对比

2026年真正好用的AI论文网站&#xff0c;核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测&#xff0c;千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队&#xff0c;覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。 一、…

2026/8/11 3:05:11

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

一天写完毕业论文在2026年已不再是天方夜谭。2026年最炸裂、实测能大幅提速的AI论文写作工具&#xff0c;覆盖选题构思、文献整理、内容生成、格式排版等核心场景&#xff0c;真正帮你高效搞定论文难题。 一、全流程王者&#xff1a;一站式搞定论文全链路&#xff08;一天定稿首…