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/