Kubernetes资源配额的作用
Kubernetes集群中,一个命名空间的Pod如果不设资源上限,单个工作负载可能耗尽整个节点的CPU和内存,导致其他业务被驱逐。ResourceQuota和LimitRange是K8s内建的两级资源控制机制:ResourceQuota限制命名空间的总资源量,LimitRange约束单个Pod的资源范围。两者配合使用,才能构建合理的多租户资源隔离。
LimitRange:单个资源对象的边界
LimitRange定义了单个容器请求和使用的资源上下限。当开发者提交的Pod未指定resources字段时,LimitRange会自动注入默认值,防止零资源声明的工作负载进入集群。
apiVersion: v1
kind: LimitRange
metadata:
name: default-limits
namespace: team-alpha
spec:
limits:
- type: Container
max:
cpu: "4"
memory: "8Gi"
min:
cpu: "50m"
memory: "64Mi"
default:
cpu: "500m"
memory: "512Mi"
defaultRequest:
cpu: "100m"
memory: "128Mi"
maxLimitRequestRatio:
cpu: "4"
memory: "3"
关键参数说明:
default/defaultRequest:Pod未指定resources时自动注入的值。default是limit上限,defaultRequest是request值。
maxLimitRequestRatio:限制limit/request的比值上限。设为4表示CPU limit不能超过request的4倍,防止过度超卖。
max/min:不管Pod怎么声明,实际生效的值都不会超过这个范围。超出范围的Pod创建会被API Server直接拒绝。
ResourceQuota:命名空间级别的总量控制
LimitRange只管单个容器,ResourceQuota管整个命名空间的资源总量:
apiVersion: v1
kind: ResourceQuota
metadata:
name: team-alpha-quota
namespace: team-alpha
spec:
hard:
# 计算资源
requests.cpu: "16"
requests.memory: "32Gi"
limits.cpu: "32"
limits.memory: "64Gi"
# 对象数量
pods: "50"
services: "20"
persistentvolumeclaims: "30"
# 存储资源
requests.storage: "500Gi"
# 高端资源
requests.nvidia.com/gpu: "4"
部署ResourceQuota后,该命名空间内所有容器的资源请求总量不得超过hard限制。当总量达到上限,新Pod创建会返回403 Forbidden错误,提示exceeded quota。
两级配额的联动配置
实际生产环境中,LimitRange和ResourceQuota必须联动设计。典型策略如下:
1. 按团队规模分配总量
一个10人研发团队,按每人最多跑5个Pod、每个Pod默认0.5核1Gi内存估算:ResourceQuota设requests.cpu=25、requests.memory=50Gi。LimitRange的default设cpu=500m/memory=1Gi,max设cpu=4/memory=8Gi。
2. 防止资源囤积
# 在ResourceQuota中加上对象数限制
spec:
hard:
pods: "50"
requests.cpu: "16"
requests.memory: "32Gi"
3. 优先级与抢占配合
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: critical-workload
value: 1000000
globalDefault: false
preemptionPolicy: PreemptLowerPriority
---
apiVersion: v1
kind: ResourceQuota
metadata:
name: critical-quota
namespace: production
spec:
hard:
requests.cpu: "32"
requests.memory: "64Gi"
pods: "100"
配额超限的告警与监控
ResourceQuota的使用率需要纳入监控告警体系。通过Prometheus原生指标监控配额使用百分比:
# Prometheus规则:配额使用率超80%告警
- alert: NamespaceQuotaNearLimit
expr: |
kube_resourcequota{type="hard", resource="requests.cpu"} > 0
and
kube_resourcequota{type="used", resource="requests.cpu"}
/ kube_resourcequota{type="hard", resource="requests.cpu"} > 0.8
for: 10m
labels:
severity: warning
annotations:
summary: "命名空间 CPU配额使用超过80%"
当告警触发时,运维团队需要评估是调整配额上限还是优化业务资源消耗,而不是简单加资源了事。
DevOps实践中常见的配额配置错误
错误1:只设LimitRange不设ResourceQuota
结果:单个容器有上限,但命名空间内Pod数量无限制,资源总量失控。
错误2:LimitRange的default和defaultRequest差距过大
结果:大量Pod使用default的较高limit值,实际资源利用率极低,造成调度浪费。建议limit/request比值控制在2-3倍。
错误3:忽略Init Container的资源配额
Init Container的resources如果超过LimitRange的max,Pod创建会失败。Init Container通常需要较多CPU但较少内存,建议单独设置type: InitContainer的LimitRange条目。
错误4:未配置QuotaScope优先级配额
K8s 1.22+支持QuotaScope,可按优先级类别分别设置配额。不使用此功能会导致低优先级任务占用高优先级工作的资源配额。
CI/CD流水线中的配额自动化
在CI/CD流程中,资源配额应作为自动化部署的前置检查:
# 部署前检查配额余量
def check_quota(namespace, needed_cpu, needed_mem):
used = get_quota_used(namespace)
hard = get_quota_hard(namespace)
remaining_cpu = hard["cpu"] - used["cpu"]
remaining_mem = hard["memory"] - used["memory"]
if remaining_cpu < needed_cpu or remaining_mem < needed_mem:
print(f"配额不足: 剩余CPU {remaining_cpu}, 需要CPU {needed_cpu}")
return False
return True
# 在CI流水线中调用
if not check_quota("team-alpha", 2, "4Gi"):
sys.exit("部署终止:命名空间资源配额不足")
通过在CI/CD流水线中加入配额检查,可以在部署阶段就拦截超限请求,避免Pod进入Pending状态等待超时。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/kubernetes-ji-qun-zi-yuan-pei-e-guan-li-cong-limitrange-dao/