为什么集群必须有资源配额
没有资源配额的Kubernetes集群,和一个没有红绿灯的十字路口效果相同。任何一个开发者部署一个resources未设limits的Pod,就能吃掉整台节点的CPU和内存,把同节点的其他服务挤到OOM。这不是理论风险——线上集群跑了一段时间后,一个忘了加limits的批处理任务吃掉节点96%内存,导致该节点所有Pod被驱逐,就是真实的生产事故。
Kubernetes提供两层配额机制:ResourceQuota在namespace级别限制资源总量,LimitRange在Pod/容器级别约束每个资源对象的默认值和上下限。两层配合才能形成完整的防护网。
ResourceQuota配置与实战
ResourceQuota限制一个namespace的资源使用总量。典型场景:一个多租户集群,每个团队一个namespace,限制每个团队最多用100个CPU核和200GB内存。
apiVersion: v1
kind: ResourceQuota
metadata:
name: team-alpha-quota
namespace: team-alpha
spec:
hard:
# 计算资源
requests.cpu: "100"
requests.memory: "200Gi"
limits.cpu: "200"
limits.memory: "400Gi"
# 对象数量
pods: "500"
services: "50"
persistentvolumeclaims: "100"
configmaps: "200"
secrets: "200"
# 存储资源
requests.storage: "500Gi"
# GPU(如果集群装了NVIDIA device plugin)
requests.nvidia.com/gpu: "8"
关键细节:ResourceQuota同时限制了requests和limits。如果只设了requests.cpu,用户提交Pod时只声明limits不声明requests,会直接被拒绝。这是很多人踩的坑——以为只要总量够就行,其实Kubernetes要求requests和limits都必须在配额范围内。
排查配额不足的Pod创建失败:
# 查看namespace的配额使用情况
kubectl get resourcequota -n team-alpha -o yaml
# 查看被配额拒绝的事件
kubectl get events -n team-alpha --field-selector reason=FailedScheduling
# 查看具体配额冲突
kubectl describe resourcequota team-alpha-quota -n team-alpha
优先级和配额抢占:当namespace配额用满,高优先级Pod可以抢占低优先级Pod。配置PriorityClass和Pod的priorityClassName:
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: critical-service
value: 1000000
globalDefault: false
preemptionPolicy: PreemptLowerPriority
description: "核心服务优先级"
但要注意:抢占不是瞬间的。kube-scheduler发现高优先级Pod无法调度后,先选一个低优先级Pod”受害者”,删除该Pod,等原Pod的容器真正退出、资源释放后,再调度高优先级Pod。整个过程可能持续几十秒到几分钟(取决于被抢占Pod的terminationGracePeriodSeconds)。
LimitRange:每个Pod的默认约束
ResourceQuota管总量,LimitRange管每个资源对象的默认值和上下限。没有LimitRange的namespace,用户提交Pod不声明resources,默认就是0 CPU / 0 memory——调度器把这种Pod当besteffort处理,节点资源紧张时最先被驱逐。
apiVersion: v1
kind: LimitRange
metadata:
name: team-alpha-limits
namespace: team-alpha
spec:
limits:
- type: Container
max:
cpu: "16"
memory: "32Gi"
min:
cpu: "50m"
memory: "64Mi"
default:
cpu: "500m"
memory: "512Mi"
defaultRequest:
cpu: "100m"
memory: "128Mi"
maxLimitRequestRatio:
cpu: "4"
memory: "3"
各字段含义:
– default:Pod不设limits时的默认limits值
– defaultRequest:Pod不设requests时的默认requests值
– max / min:limits和requests的上下限,超出直接拒绝
– maxLimitRequestRatio:limits/requests比值上限。设为4表示limits.cpu最多是requests.cpu的4倍。这个参数防止”requests写很小、limits写很大”的资源超卖行为
一个常见坑:LimitRange的default只对Pod没有显式声明resources的容器生效。如果容器只声明了limits没声明requests,Kubernetes会把requests设为等于limits(而不是取defaultRequest)。如果你希望requests低于limits,必须在Pod spec中同时声明两者。
多租户场景的配额策略
多租户集群的配额治理需要分层设计:
L1-集群级:kube-scheduler的配额预过滤,防止任何namespace超分集群总资源。用ClusterResourceQuota(OpenShift)或自定义Admission Webhook实现。
L2-Namespace级:ResourceQuota限制每个租户资源总量。
L3-容器级:LimitRange约束单个容器的资源规格,防止”一个容器吃掉整个namespace配额”。
L4-业务级:HPA + KEDA根据负载自动调整Pod数量,但HPA的maxReplicas不能超过namespace配额允许的Pod数量。
一个完整的配额管理GitOps工作流:
# Argocd Application - 自动同步配额配置
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: resource-quotas
namespace: argocd
spec:
source:
repoURL: git@github.com:infra/k8s-quotas.git
path: quotas
targetRevision: main
destination:
server: https://kubernetes.default.svc
syncPolicy:
automated:
prune: true
selfHeal: true
所有配额配置存在Git仓库,ArgoCD自动同步到集群。这样配额变更可追溯、可回滚,避免kubectl直接修改配额导致租户资源被意外回收。
配额监控告警
ResourceQuota使用率超过80%就应该告警,给租户预留扩容时间窗口。用kube-state-metrics + Prometheus实现:
# Prometheus告警规则
groups:
- name: resource-quota
rules:
- alert: NamespaceCPUQuotaNearExhaustion
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: 5m
labels:
severity: warning
annotations:
summary: "Namespace {{ $labels.namespace }} CPU配额使用率超过80%"
runbook: "https://wiki.example.com/runbook/quota-cpu"
- alert: NamespaceMemoryQuotaNearExhaustion
expr: |
kube_resourcequota{type="hard", resource="requests.memory"} > 0
and
(kube_resourcequota{type="used", resource="requests.memory"}
/ kube_resourcequota{type="hard", resource="requests.memory"}) > 0.8
for: 5m
labels:
severity: warning
annotations:
summary: "Namespace {{ $labels.namespace }} 内存配额使用率超过80%"
配额治理的核心不是”卡住”开发者,而是让集群资源使用变得可预测。当每个namespace的资源预算清晰可见,集群扩容规划才有数据支撑,而不是靠”感觉快不够了”来决定加节点。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/kubernetes-zi-yuan-pei-e-zhi-li-shi-zhan-resourcequota-yu/