一、Kubernetes服务质量QoS是什么
在Kubernetes集群里跑应用的时候,你有没有遇到过这种情况:某个Pod突然把CPU吃满了,导致其他Pod饿得嗷嗷叫?或者某个Pod内存泄漏,把整个节点拖垮了?这时候就需要QoS(Quality of Service)机制来救场了。
简单来说,QoS就是Kubernetes给Pod划分的三六九等。就像飞机有头等舱、商务舱和经济舱一样,Kubernetes把Pod也分为三个等级:
- Guaranteed(保证型):VIP级别,资源管够
- Burstable(突发型):普通会员,饿不死但也吃不饱
- BestEffort(尽力型):站票选手,自求多福
二、QoS的三种等级详解
2.1 Guaranteed级别
这种Pod是亲儿子待遇,资源有绝对保障。要达成这个级别需要满足两个条件:
- 必须同时设置CPU和内存的limits
- requests必须等于limits(不能少也不能多)
来看个YAML示例(技术栈:Kubernetes v1.22):
apiVersion: v1
kind: Pod
metadata:
name: guaranteed-pod
spec:
containers:
- name: nginx
image: nginx
resources:
limits:
cpu: "1"
memory: "1Gi"
requests:
cpu: "1"
memory: "1Gi"
这个配置里,CPU和内存的requests和limits完全一致,所以这个Pod会被标记为Guaranteed级别。当资源紧张时,系统会优先保证这类Pod的资源供给。
2.2 Burstable级别
这类Pod就像普通打工人,基本工资(requests)有保障,但奖金(超出requests的部分)要看公司效益。满足以下任一条件就是Burstable:
- 只设置了requests没设置limits
- requests和limits不相等
- 只设置了部分资源的requests/limits
示例配置:
apiVersion: v1
kind: Pod
metadata:
name: burstable-pod
spec:
containers:
- name: nginx
image: nginx
resources:
limits:
memory: "2Gi"
requests:
cpu: "0.5"
memory: "1Gi"
这个例子里,内存有requests和limits但不相等,CPU只设置了requests,所以是典型的Burstable Pod。
2.3 BestEffort级别
这类Pod就像临时工,啥保障都没有。判断标准很简单:啥资源限制都没设置。
示例配置:
apiVersion: v1
kind: Pod
metadata:
name: best-effort-pod
spec:
containers:
- name: nginx
image: nginx
这种Pod在资源紧张时最先被干掉,适合那些无关紧要的后台任务。
三、资源限制的实战技巧
3.1 CPU限制的坑
CPU限制和其他资源不太一样,它是个软限制。比如下面这个配置:
resources:
limits:
cpu: "1"
requests:
cpu: "0.5"
这里的"1"表示1个CPU核心,实际使用时:
- 如果节点有空闲CPU,Pod可以突破limits限制
- 当其他Pod也需要CPU时,才会被限制在1核以内
- CPU是以时间片方式分配的,不是硬性上限
3.2 内存限制的血泪教训
内存限制可是硬限制,超过就OOM(Out Of Memory)被杀。看这个例子:
resources:
limits:
memory: "512Mi"
requests:
memory: "256Mi"
如果这个容器内存使用超过512MiB,Kubernetes会毫不留情地干掉它。所以设置内存limits时一定要留够余量。
3.3 如何合理设置资源限制
根据经验,建议这样设置:
- 生产环境核心服务:用Guaranteed级别
- 普通服务:Burstable,requests设为日常使用量的120%
- 测试/开发环境:BestEffort或者低配Burstable
监控工具建议:
- 用Metrics Server收集资源使用数据
- 用Prometheus做长期监控
- 用Grafana做可视化
四、QoS的底层实现原理
4.1 Linux内核的cgroups机制
Kubernetes的QoS实际上是靠Linux的cgroups实现的。每个Pod都会被分配到对应的cgroup中:
- /kubepods.slice:所有Pod的父cgroup
- /kubepods/burstable.slice:Burstable Pods
- /kubepods/besteffort.slice:BestEffort Pods
4.2 OOM评分机制
当节点内存不足时,内核会根据OOM分数决定杀哪个进程。分数计算规则:
- Guaranteed Pod:-998分(几乎不会被杀)
- Burstable Pod:min(max(2, 1000 - (1000 * memoryRequest)/memoryAvailable)), 999)
- BestEffort Pod:1000分(最先被杀)
4.3 CPU调度优先级
CFS调度器会给不同QoS的Pod不同的权重:
- Guaranteed:1024
- Burstable:2-1024之间动态调整
- BestEffort:2
五、常见问题解决方案
5.1 Pod频繁OOM被杀
症状:Pod经常重启,日志显示OOMKilled
解决方案:
- 检查内存limits是否设置过小
- 使用
kubectl top pod查看实际使用量 - 适当提高limits值
- 优化应用内存使用
5.2 CPU节流影响性能
症状:应用性能下降,监控显示CPU throttling
解决方案:
- 检查CPU limits是否设置过低
- 考虑使用Guaranteed级别
- 优化应用CPU使用效率
- 增加节点资源
5.3 节点资源耗尽
症状:新Pod无法调度,节点状态显示MemoryPressure/DiskPressure
解决方案:
- 使用ResourceQuota限制命名空间资源
- 设置合理的requests/limits
- 增加集群节点
- 驱逐低优先级Pod
六、最佳实践总结
- 重要服务一定要用Guaranteed级别
- 内存limits要留足安全余量(建议20%)
- 使用HPA(Horizontal Pod Autoscaler)自动扩缩容
- 定期检查资源使用情况并调整限制
- 测试环境模拟压力测试,找出合适的资源限制值
记住,资源限制不是一劳永逸的,随着业务发展要不断调整。就像给小孩买衣服,不能总按去年的尺码来。
评论