16.6.4 资源请求与限制(QoS)

资源请求与限制(QoS)概述#

Kubernetes 通过为容器设置 requestslimits,在调度与运行时进行资源分配与约束,并据此划分 QoS(服务质量)等级。合理配置能够提升资源利用率、稳定性与故障隔离能力。

文章图片

requests 与 limits 的作用#

  • requests:调度时的资源保证值,影响 Pod 能否被调度以及节点可分配资源的计算。
  • limits:运行时资源上限,超过上限将触发限制或 OOM 终止。
  • CPU:可压缩资源,超限会被节流(throttling)。
  • Memory:不可压缩资源,超限会触发 OOMKill。

命令示例:查看节点可分配资源#

# 查看节点可分配资源(可用于判断 requests 是否能被满足)
kubectl get node -o wide
kubectl describe node <node-name> | sed -n '/Allocatable:/,/Conditions:/p'

QoS 等级与判定规则#

Kubernetes 根据 Pod 中所有容器的 requests/limits 配置自动分配 QoS:
- Guaranteed
条件:所有容器都设置了 CPU/Memory 的 requests 与 limits,且二者相等。
特性:最高优先级,最强资源保障,驱逐优先级最低。
- Burstable
条件:至少一个容器设置了 requests/limits,但不满足 Guaranteed 条件。
特性:可突发使用资源,但在资源紧张时优先被驱逐。
- BestEffort
条件:所有容器都未设置 CPU/Memory 的 requests 与 limits。
特性:最低保障,资源紧张时最先被驱逐。

YAML 示例:三类 QoS Pod#

# 文件: qos-demo.yaml
apiVersion: v1
kind: Pod
metadata:
  name: qos-guaranteed
spec:
  containers:
  - name: app
    image: nginx:1.25
    resources:
      requests:
        cpu: "500m"
        memory: "256Mi"
      limits:
        cpu: "500m"
        memory: "256Mi"
---
apiVersion: v1
kind: Pod
metadata:
  name: qos-burstable
spec:
  containers:
  - name: app
    image: nginx:1.25
    resources:
      requests:
        cpu: "100m"
        memory: "64Mi"
      limits:
        cpu: "500m"
        memory: "256Mi"
---
apiVersion: v1
kind: Pod
metadata:
  name: qos-besteffort
spec:
  containers:
  - name: app
    image: nginx:1.25
# 应用并查看 QoS 分类
kubectl apply -f qos-demo.yaml
kubectl get pod qos-guaranteed qos-burstable qos-besteffort -o custom-columns=NAME:.metadata.name,QOS:.status.qosClass

资源限制与驱逐行为#

  • 内存压力:节点内存不足时,驱逐顺序通常为 BestEffort → Burstable → Guaranteed。
  • CPU压力:主要表现为节流,不一定触发驱逐。
  • 驱逐阈值:受 kubelet 的 eviction 配置影响,应结合节点水位进行监控与调优。

原理草图:驱逐与节流#

文章图片

配置示例与实践要点#

  • 为关键业务设置 requests=limits,确保稳定运行。
  • 为弹性负载设置较低 requests、适度 limits,提升集群利用率。
  • 避免所有 Pod 设为 BestEffort,降低可预测性与稳定性风险。
  • 使用资源配额(ResourceQuota)和限制范围(LimitRange)进行统一治理。
  • 通过监控与容量评估,持续调整 requests/limits 的合理区间。

限制范围与配额示例#

# 文件: namespace-limit.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: dev
---
apiVersion: v1
kind: LimitRange
metadata:
  name: dev-limit
  namespace: dev
spec:
  limits:
  - type: Container
    default:
      cpu: "500m"
      memory: "256Mi"
    defaultRequest:
      cpu: "100m"
      memory: "64Mi"
---
apiVersion: v1
kind: ResourceQuota
metadata:
  name: dev-quota
  namespace: dev
spec:
  hard:
    requests.cpu: "2"
    requests.memory: "2Gi"
    limits.cpu: "4"
    limits.memory: "4Gi"
kubectl apply -f namespace-limit.yaml
kubectl get limitrange,resourcequota -n dev

常见问题与排查思路#

  • Pod 无法调度:检查 requests 是否超过节点可用资源。
    bash kubectl describe pod <pod-name> | sed -n '/Events:/,$p' kubectl describe node <node-name> | sed -n '/Allocatable:/,/Non-terminated Pods:/p'
  • 频繁 OOMKill:检查内存 limits 是否过低,或存在内存泄漏。
    bash kubectl describe pod <pod-name> | grep -E 'OOMKilled|Reason' kubectl top pod <pod-name> --containers
  • CPU 性能抖动:观察 throttling 指标与 limits 设置是否过紧。
    bash # 需安装 metrics-server kubectl top pod <pod-name> --containers
  • QoS 不符合预期:核对所有容器的 requests/limits 是否齐全且一致。
    bash kubectl get pod <pod-name> -o jsonpath='{.status.qosClass}{"\n"}' kubectl get pod <pod-name> -o jsonpath='{.spec.containers[*].resources}{"\n"}'

练习与实操#

  1. 创建三类 QoS Pod,验证 qosClass 是否符合预期。
  2. 将 Burstable 的 limits 调小,观察是否出现 CPU throttling。
  3. 为命名空间设置 LimitRange,创建不带 resources 的 Pod,验证是否自动注入默认值。
  4. 人为将 requests 设置过高,观察调度失败事件原因。

最佳实践总结#

  • 核心业务 Guaranteed,非核心业务 Burstable,避免 BestEffort 运行生产关键服务。
  • 按服务画像与峰谷负载设定 requests/limits,保持可用性与成本平衡。
  • 配合 HPA/VPA 与容量规划,形成闭环资源治理体系。