为什么Kubernetes集群必须配置资源配额
在DevOps实践中,Kubernetes集群的资源管理是最容易被忽视的环节。没有资源配额约束的集群,任何一个团队或服务都可能意外申请过多资源,导致其他Pod无法调度,甚至触发节点OOM。这在多租户共享集群中尤其致命——一个未设置limits的测试Pod可能吃掉整个节点的内存,让生产服务全部Pending。
Kubernetes提供两层资源控制机制:
– LimitRange:命名空间级别的默认值和上下限约束,作用于单个Pod/Container
– ResourceQuota:命名空间级别的总量限制,约束整个命名空间的总资源消耗
两者配合使用才能形成完整的资源防护网。
LimitRange配置详解与常见踩坑
LimitRange定义了容器资源申请的默认值、默认请求比和上下限:
apiVersion: v1
kind: LimitRange
metadata:
name: default-limits
namespace: production
spec:
limits:
- type: Container
default: # 默认limits(未显式设置时生效)
cpu: "2"
memory: "4Gi"
defaultRequest: # 默认requests
cpu: "500m"
memory: "512Mi"
max: # 单容器允许的最大值
cpu: "8"
memory: "16Gi"
min: # 单容器允许的最小值
cpu: "100m"
memory: "128Mi"
maxLimitRequestRatio: # limits/requests的最大比值
cpu: "4"
memory: "3"
- type: Pod
max:
cpu: "16"
memory: "32Gi"
几个关键细节:
1. default和defaultRequest必须同时设置:如果只设default不设defaultRequest,创建无resources字段的Pod时,requests会被自动设为与limits相同值。这意味着调度器认为这个Pod需要2 CPU,而不是500m——大量小服务会因此无法调度。
2. maxLimitRequestRatio控制超卖比例:设为3意味着memory的limits最多是requests的3倍。超过此比值的Pod会被拒绝创建。这个参数防止用户把requests压到极低而limits设到极高,导致节点上实际资源不足。
3. Pod级别的max约束所有容器之和:单个容器可以申请8 CPU,但整个Pod的所有容器CPU总和不能超过16。
ResourceQuota的精细化配置
ResourceQuota限制命名空间的总资源消耗:
apiVersion: v1
kind: ResourceQuota
metadata:
name: team-alpha-quota
namespace: team-alpha
spec:
hard:
# 计算资源
requests.cpu: "32"
requests.memory: "64Gi"
limits.cpu: "64"
limits.memory: "128Gi"
# 对象数量
pods: "50"
services: "20"
persistentvolumeclaims: "30"
# 存储资源
requests.storage: "500Gi"
# 特殊资源(GPU等)
requests.nvidia.com/gpu: "4"
ResourceQuota会强制命名空间内所有Pod都必须显式设置requests和limits——否则创建会被拒绝。这就是为什么LimitRange和ResourceQuota必须配合:LimitRange提供默认值填补空白,ResourceQuota约束总量。
PriorityClass与ResourceQuota的协同
在SRE稳定性工程中,不同优先级的服务应该有不同的资源保障策略:
# 高优先级(生产核心服务)
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: critical
value: 1000000
preemptionPolicy: PreemptLowerPriority
globalDefault: false
description: "Production critical services"
---
# 中优先级(生产非核心服务)
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: normal
value: 100000
preemptionPolicy: PreemptLowerPriority
globalDefault: true
description: "Normal production services"
---
# 低优先级(批处理/测试)
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: batch
value: 10000
preemptionPolicy: PreemptLowerPriority
globalDefault: false
description: "Batch and test workloads"
配置PriorityClass后,当集群资源不足时,调度器会驱逐低优先级Pod来给高优先级Pod腾出空间。这在故障应急响应场景下非常有效——核心服务有资源保障,批处理任务可以等。
实际场景:多团队共享集群的配额分配
一个典型的3团队共享集群,节点总资源96 CPU / 384Gi内存:
# 团队A(核心交易服务,40%资源)
apiVersion: v1
kind: ResourceQuota
metadata:
name: team-a-quota
namespace: team-a
spec:
hard:
requests.cpu: "38"
requests.memory: "153Gi"
limits.cpu: "76"
limits.memory: "230Gi"
pods: "100"
---
# 团队B(数据分析,35%资源)
apiVersion: v1
kind: ResourceQuota
metadata:
name: team-b-quota
namespace: team-b
spec:
hard:
requests.cpu: "33"
requests.memory: "134Gi"
limits.cpu: "66"
limits.memory: "201Gi"
pods: "80"
---
# 团队C(测试环境,25%资源)
apiVersion: v1
kind: ResourceQuota
metadata:
name: team-c-quota
namespace: team-c
spec:
hard:
requests.cpu: "24"
requests.memory: "96Gi"
limits.cpu: "48"
limits.memory: "144Gi"
pods: "60"
注意requests总量(38+33+24=95)略低于集群总资源(96),留出1 CPU给系统组件(kube-proxy、Calico等)。
监控告警与配额使用率追踪
Kubernetes的ResourceQuota使用情况可以通过kubectl和Prometheus同时监控:
# 查看命名空间配额使用情况
kubectl describe resourcequota -n team-alpha
# 输出示例:
# Name: team-alpha-quota
# Resource Used Hard
# -------- ---- ----
# limits.cpu 45 64
# limits.memory 89Gi 128Gi
# pods 32 50
# requests.cpu 28 32
# requests.memory 52Gi 64Gi
# Prometheus告警规则
# 配额使用率超过80%告警
- alert: NamespaceQuotaNearExhaustion
expr: |
kube_resourcequota_used / kube_resourcequota_hard > 0.8
for: 10m
labels:
severity: warning
annotations:
summary: "Namespace {{ $labels.namespace }} 的 {{ $labels.resource }} 配额使用率超过80%"
在CI/CD流水线中,建议加入配额检查步骤:部署前检查目标命名空间的剩余配额,如果不足以容纳新部署,提前告警而非等到Pod创建失败。
LimitRange与ResourceQuota的故障排查
当Pod创建失败时,几个常见错误和排查方法:
1. “exceeded quota”错误:
# 查看哪个资源超限
kubectl describe resourcequota -n <namespace>
# 临时方案:申请增加配额
kubectl patch resourcequota team-a-quota -n team-a -p '{"spec":{"hard":{"requests.cpu":"40"}}}'
2. “limit ratio exceeded”错误:Pod的limits/requests比值超过LimitRange的maxLimitRequestRatio。修改Pod的resources配置,让比值在范围内。
3. “must set requests/limits”错误:命名空间有ResourceQuota但Pod没有设置resources字段,且没有LimitRange提供默认值。确保LimitRange已正确创建。
4. Pod一直Pending但无明确错误:可能是requests总和超过ResourceQuota但错误信息被调度器吞掉了。用kubectl describe pod <pod-name>查看Events字段。
混沌工程实践中,可以故意将某个命名空间的ResourceQuota降到当前使用量以下,验证团队能否快速响应和处理资源不足的场景——这也是SRE成熟度的一个重要指标。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/kubernetes-zi-yuan-pei-e-guan-li-shi-zhan-limitrange-yu/