Kubernetes资源配额与限制管理实战:从Requests/Limits到LimitRange

Kubernetes资源管理的核心概念:Requests与Limits

Kubernetes中每个Pod可以定义CPU和内存的requests与limits两个维度的资源约束。requests是调度器分配节点时的依据,limits是容器运行时的资源上限。理解这两者的差异和组合方式,是做好K8s资源管理的基础。

当Pod只设置了requests而未设置limits时,容器最低能获得requests声明的资源量,但可以无上限地使用节点可用资源。当Pod设置了limits而未设置requests时,Kubernetes默认将requests设置为与limits相同的值。当两者都未设置时,容器对资源的使用不受约束,这在生产环境中是极其危险的配置——一个失控的容器可能耗尽节点资源导致整台机器雪崩。

三种常见的配置模式:第一种,requests=limits,即Guaranteed QoS,适合对延迟敏感的核心服务;第二种,requests小于limits,Burstable QoS,适合负载波动较大的服务,可以在空闲时借用节点资源;第三种,requests=limits=0,BestEffort QoS,仅在开发测试环境使用,生产环境应当避免。

ResourceQuota:命名空间级别的资源管控

ResourceQuota在命名空间级别限制资源消耗总量,防止一个团队或项目占用过多集群资源。以下是一个典型的ResourceQuota配置:

apiVersion: v1
kind: ResourceQuota
metadata:
  name: team-alpha-quota
  namespace: team-alpha
spec:
  hard:
    requests.cpu: "40"
    requests.memory: 64Gi
    limits.cpu: "80"
    limits.memory: 128Gi
    pods: "50"
    services: "10"
    persistentvolumeclaims: "20"

这个配置约束team-alpha命名空间的CPU requests总量不超过40核,limits不超过80核,内存requests不超过64Gi,limits不超过128Gi。同时限制了Pod、Service、PVC的数量上限。

当命名空间中的资源使用量接近配额时,Kubernetes会拒绝新的资源创建请求。运维人员需要通过监控面板持续跟踪各命名空间的资源使用率,在配额耗尽前做出扩容或调优决策。

需要注意的细节:ResourceQuota对limits的约束是硬限制,超出即拒绝,不会自动杀死已有容器。如果命名空间中已有Pod的limits总和达到配额上限,新Pod将无法创建。因此配额规划时应预留20%的缓冲空间。

LimitRange:Pod级别的默认值与边界约束

ResourceQuota管控命名空间总量,LimitRange则管控单个容器或Pod的资源范围。当开发者提交Pod spec时未设置resources字段,LimitRange可以自动注入默认值。当开发者设置了超出范围的值,LimitRange会拦截并拒绝。

apiVersion: v1
kind: LimitRange
metadata:
  name: default-limits
  namespace: team-alpha
spec:
  limits:
  - type: Container
    default:           # 未设置limits时的默认值
      cpu: "2"
      memory: 4Gi
    defaultRequest:    # 未设置requests时的默认值
      cpu: "500m"
      memory: 512Mi
    max:               # limits允许的最大值
      cpu: "8"
      memory: 16Gi
    min:               # requests允许的最小值
      cpu: "100m"
      memory: 128Mi
    maxLimitRequestRatio:  # limits与requests的最大比值
      cpu: "4"

maxLimitRequestRatio是一个容易被忽略但很关键的参数。将CPU的ratio设为4,意味着limits最多只能是requests的4倍。这个约束防止开发者设置极低的requests和极高的limits,在调度阶段偷取节点资源配额。生产环境建议将CPU ratio控制在2-4之间,内存ratio设为1(即limits等于requests),因为内存不可压缩,超限会直接触发OOM Kill。

QoS等级与驱逐优先级

Kubernetes根据Pod的资源配置将其分为三个QoS等级,这个等级直接影响节点资源紧张时的驱逐顺序。

Guaranteed等级:requests等于limits且都不为0。这类Pod获得最高保障,只有在节点不可恢复时才会被驱逐。Burstable等级:requests小于limits或只设置了其中一个。这类Pod在节点内存不足时优先被驱逐。BestEffort等级:requests和limits均未设置。这类Pod最容易被驱逐,节点压力下第一批被清理。

驱逐机制由kubelet的Eviction Manager执行。当节点可用内存低于kubelet配置的eviction-hard阈值(默认memory.available<750Mi)时,kubelet按QoS等级从低到高选择Pod驱逐。同等级内按内存使用量占requests的比例排序,使用比例高的先被驱逐。

这就引出一个实战要点:核心业务Pod必须设置requests=limits,确保Guaranteed QoS。日志采集、监控Agent等辅助组件可以设置较小的requests,让它们在Burstable QoS下运行,在节点压力大时优先让出资源。

资源配额监控与告警配置

光有配额约束不够,还需要可视化监控配额使用情况。Prometheus + Grafana是K8s生态中最常用的监控方案。

Prometheus采集ResourceQuota使用指标的核心查询:

# 命名空间CPU requests使用率
kube_resourcequota{type="hard", resource="requests.cpu"} 
/ 
kube_resourcequota{type="used", resource="requests.cpu"}

# 命名空间内存limits使用率
kube_resourcequota{type="used", resource="limits.memory"} 
/ 
kube_resourcequota{type="hard", resource="limits.memory"}

Grafana面板建议按团队/命名空间分组展示,将CPU requests、CPU limits、内存requests、内存limits四项指标的使用率以百分比形式呈现。当使用率超过80%时面板变为黄色,超过90%变为红色。

告警规则配置:

- alert: NamespaceQuotaNearLimit
  expr: |
    kube_resourcequota{type="used", resource="requests.cpu"}
    / kube_resourcequota{type="hard", resource="requests.cpu"}
    > 0.85
  for: 10m
  labels:
    severity: warning
  annotations:
    summary: "命名空间 {{ $labels.namespace }} CPU requests配额使用率超过85%"

多租户场景下的资源配额规划策略

当集群服务多个团队时,资源配额规划需要平衡公平性和利用率。一个实用的策略是将集群总资源的70%通过ResourceQuota分配给各团队,剩余30%作为弹性资源池。各团队在配额用尽后可申请临时扩容,弹性资源池的分配由自动化审批流程控制,超过24小时未使用的临时配额自动回收。

另一个常见的优化手段是启用Cluster Autoscaler配合ResourceQuota。当某命名空间的Pod因资源不足处于Pending状态时,Autoscaler自动扩容节点。但需要设置集群节点数上限和扩容冷却时间,避免因配额配置错误导致无限扩容。冷却时间建议设为10分钟,最大节点数按集群容量上限的1.5倍配置。

资源配额管理不是一次性配置,而是持续优化的过程。每季度复盘各团队的实际资源使用率(Prometheus数据),将长期低利用率的配额回收重新分配,避免资源浪费。GPU等昂贵资源的配额管理更是如此,GPU requests设置应严格等于实际需求,通过时间片调度提升利用率。

原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/kubernetes-zi-yuan-pei-e-yu-xian-zhi-guan-li-shi-zhan-cong/

(0)
小编小编
上一篇 17小时前
下一篇 17小时前

相关推荐