容器资源请求与限制:Requests和Limits配置、服务质量等级、资源超卖策略
好,咱们进入第二章。这一章聊的是Kubernetes里最基础、也最容易踩坑的部分——容器的Requests和Limits。说白了,就是告诉集群:“我这个Pod最少要多少资源,最多能吃多少资源”。
我见过太多团队,要么完全不设限制,导致一个Pod把整台机器打爆;要么设得太死,集群利用率低得可怜。嗯,咱们今天就把这事彻底聊透。
一、Requests和Limits到底是什么?
先看一个最简单的配置:
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
Requests:你向集群“申请”的资源量。调度器根据这个值决定把Pod放在哪台Node上。说白了,这是你的“最低保障”。
Limits:Pod最多能用的资源上限。超过这个值,CPU会被限流,内存会被OOM Kill。
我个人习惯把Requests理解为“预订座位”,Limits理解为“最多能吃几碗饭”。你预订了2个座位,但最多能吃4碗饭——这就是典型的Burstable模式。
二、服务质量等级:Guaranteed / Burstable / BestEffort
Kubernetes根据Requests和Limits的配置方式,把Pod分成三个等级。这个等级决定了Pod被“杀掉”的优先级。
1. Guaranteed(最高优先级)
条件:每个容器都设置了Requests和Limits,并且两者相等。
resources:
requests:
memory: "512Mi"
cpu: "500m"
limits:
memory: "512Mi"
cpu: "500m"
这种Pod最“稳”。系统认为它需要固定资源,轻易不会动它。我在项目中遇到过,核心数据库、关键API网关,我都会设成Guaranteed。为什么?因为一旦内存紧张,系统优先杀BestEffort和Burstable,Guaranteed是最后一道防线。
核心原则:关键业务用Guaranteed,非关键业务用Burstable,临时任务用BestEffort。
2. Burstable(中等优先级)
条件:至少有一个容器设置了Requests,但Requests和Limits不相等。
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "1Gi"
cpu: "1"
这是最常见的配置。说白了,你给Pod一个“最低保障”,但允许它在空闲时“多吃点”。我大部分微服务都这么配。你想想看,业务高峰期需要更多CPU,平时又用不了那么多——Burstable正好满足这种弹性需求。
3. BestEffort(最低优先级)
条件:完全不设置Requests和Limits。
# 没有resources字段
这种Pod“有啥吃啥”。系统空闲时它跑得欢,一旦资源紧张,第一个被干掉的就是它。我曾经在CI/CD流水线里用BestEffort跑一些非关键的测试任务——跑成了赚了,跑死了也无所谓。
避坑指南:千万不要在生产环境的核心服务上用BestEffort。我曾经见过一个团队,把线上API网关设成了BestEffort,结果隔壁Pod一吃内存,网关直接被OOM Kill,整个业务挂了半小时。
三、资源超卖策略:如何“榨干”集群资源?
好,现在问题来了:如果所有Pod都按Guaranteed配置,集群利用率可能只有30%-40%。太浪费了。怎么办?超卖。
超卖,说白了就是“多分配、少使用”。你给Pod设了1核CPU的Requests,但它实际只用0.2核。那剩下的0.8核就可以给别的Pod用。
1. CPU超卖
CPU是可压缩资源。什么意思?就是Pod用超了,系统可以“限流”,不会杀掉它,只是让它变慢。
我常用的策略:
- 核心服务:Requests = Limits,不超卖
- 普通服务:Requests设为实际使用量的70%,Limits设为峰值的150%
- 批处理任务:Requests设得很低,Limits设得很高
举个例子:
# 普通Web服务
resources:
requests:
cpu: "200m" # 实际平时只用150m
limits:
cpu: "500m" # 高峰期能冲到400m
2. 内存超卖
内存是不可压缩资源。超了就是超了,系统只能杀掉Pod。所以内存超卖要非常谨慎。
我的经验:
- 内存Requests = 实际使用量的90%
- 内存Limits = 实际使用量的120%
- 永远不要设置Limits超过Node内存的80%
个人技巧:我习惯用Vertical Pod Autoscaler(VPA)来推荐Requests和Limits。跑个几天,VPA会告诉你“这个Pod实际用了多少,建议设多少”。然后你再手动调整。别完全相信VPA,它有时候会推荐得太保守。
四、实战配置建议
说了这么多,给出一套我常用的配置模板:
| 业务类型 | QoS等级 | CPU Requests | CPU Limits | Memory Requests | Memory Limits |
|---|---|---|---|---|---|
| 核心API | Guaranteed | 1 | 1 | 1Gi | 1Gi |
| 普通微服务 | Burstable | 250m | 500m | 512Mi | 1Gi |
| 批处理任务 | Burstable | 100m | 2 | 256Mi | 2Gi |
| 临时测试 | BestEffort | 无 | 无 | 无 | 无 |
嗯,这套配置我用了两年,集群利用率从35%提到了65%。当然,具体数值要根据你的业务调整。
五、常见坑与避坑指南
- 坑1:Limits设得太低——Pod频繁被OOM Kill。我曾经有个Java服务,Limits只给了512Mi,结果JVM一GC就挂。后来调到2Gi才稳定。
- 坑2:Requests设得太高——集群调度不进去。你想想看,每个Pod都申请2核,但实际只用0.5核,那10台Node的集群只能调度5个Pod,太浪费了。
- 坑3:所有Pod都用Guaranteed——集群利用率极低。我见过一个团队,所有服务都设成Requests=Limits,结果集群利用率不到20%。
- 坑4:完全不设Limits——某个Pod可能把整台机器打爆。特别是那些有内存泄漏的服务,不设Limits就是定时炸弹。
总结一句话:Requests保底,Limits防爆,QoS定生死,超卖提效率。把这四个点吃透了,Kubernetes资源管理你就入门了。
下一章咱们聊聊HPA和VPA,怎么让Pod自动伸缩。嗯,那才是真正的“自动驾驶”。