4. 资源配额模型设计:Kubernetes ResourceQuota 与 LimitRange 的 YAML 定义、配额模型抽象
在 Sigstore 策略即代码(Policy-as-Code, PaC)的治理框架中,资源配额模型是检测“漂移告警”的基准锚点。本章将深入 Kubernetes 原生配额原语 ResourceQuota 与 LimitRange 的 YAML 定义,并抽象出可被 Sigstore 策略引擎消费的配额模型。
4.1 配额原语对比:ResourceQuota vs LimitRange
| 维度 | ResourceQuota | LimitRange |
|---|---|---|
| 作用域 | 命名空间级别,聚合所有 Pod/Container 的资源总和 | 命名空间级别,约束单个 Pod/Container 的资源边界 |
| 管控对象 | CPU/内存总量、PVC 存储总量、对象数量(如 Pod、Service) | 单个容器的 requests/limits 最小/最大值、默认值、比例 |
| 漂移检测点 | 总和超限 → 拒绝创建新 Pod;总和远低于阈值 → 资源浪费 | 单个容器配置超出 min/max → 拒绝或自动注入默认值 |
| Sigstore 策略关联 | 策略检查命名空间总配额是否被篡改或降级 | 策略检查单个工作负载的资源配置是否合规 |
关键认知: ResourceQuota 是“总量闸门”,LimitRange 是“单例标尺”。在配额模型抽象中,两者必须同时建模,才能完整覆盖“宏观预算”与“微观规格”两个漂移维度。
4.2 ResourceQuota YAML 定义与字段解析
以下是一个面向生产环境的 ResourceQuota 定义,包含计算资源、存储资源和对象数量配额:
apiVersion: v1
kind: ResourceQuota
metadata:
name: prod-quota
namespace: production
spec:
hard:
# 计算资源
requests.cpu: "32"
requests.memory: "128Gi"
limits.cpu: "64"
limits.memory: "256Gi"
# 存储资源
requests.storage: "500Gi"
persistentvolumeclaims: "20"
# 对象数量
pods: "100"
services: "20"
configmaps: "30"
secrets: "30"
services.loadbalancers: "5"
services.nodeports: "10"
scopeSelector:
matchExpressions:
- operator: In
scopeName: PriorityClass
values:
- high-priority
漂移告警关注点:
- hard 字段被篡改:例如
requests.cpu从 "32" 被改为 "64",导致资源预算膨胀。 - scopeSelector 被移除或修改:导致高优先级 Pod 不再受配额约束,造成资源抢占。
- 配额总量与集群实际容量不匹配:例如集群总 CPU 为 64 核,但配额总和设为 128 核,形成“超卖漂移”。
4.3 LimitRange YAML 定义与字段解析
LimitRange 用于定义命名空间内单个容器的资源默认值和边界:
apiVersion: v1
kind: LimitRange
metadata:
name: container-limits
namespace: production
spec:
limits:
- type: Container
default:
cpu: "500m"
memory: "512Mi"
defaultRequest:
cpu: "200m"
memory: "256Mi"
max:
cpu: "4"
memory: "8Gi"
min:
cpu: "50m"
memory: "64Mi"
maxLimitRequestRatio:
cpu: "4"
memory: "4"
- type: PersistentVolumeClaim
max:
storage: "100Gi"
min:
storage: "1Gi"
常见漂移场景:
- max 字段被放大:例如
max.cpu从 "4" 改为 "16",允许单个容器过度占用资源。 - default 字段被删除:导致未显式设置资源限制的 Pod 被拒绝创建,引发部署失败告警。
- maxLimitRequestRatio 被移除:允许容器设置过高的 limit/request 比例,造成资源碎片。
4.4 配额模型抽象:从 YAML 到策略可消费的结构
为了让 Sigstore 策略引擎能够对配额进行一致性校验,需要将原生 YAML 抽象为配额模型(Quota Model)。该模型包含三个核心层级:
- 资源域(Resource Domain):标识配额所属的命名空间、集群、环境(如 production/staging)。
- 配额项(Quota Item):每个资源类型(cpu/memory/storage)的 hard 值、min/max、默认值。
- 约束规则(Constraint Rule):scopeSelector、maxLimitRequestRatio 等条件逻辑。
以下是一个抽象后的配额模型 JSON 示例(Sigstore 策略引擎可直接消费):
{
"apiVersion": "quota.sigstore.dev/v1",
"kind": "QuotaModel",
"metadata": {
"namespace": "production",
"cluster": "prod-cluster-01"
},
"spec": {
"resourceQuota": {
"requests.cpu": "32",
"requests.memory": "128Gi",
"limits.cpu": "64",
"limits.memory": "256Gi",
"pods": "100"
},
"limitRange": {
"container": {
"default": { "cpu": "500m", "memory": "512Mi" },
"max": { "cpu": "4", "memory": "8Gi" },
"min": { "cpu": "50m", "memory": "64Mi" },
"maxLimitRequestRatio": { "cpu": 4, "memory": 4 }
}
},
"scopeSelector": {
"matchExpressions": [
{ "operator": "In", "scopeName": "PriorityClass", "values": ["high-priority"] }
]
}
}
}
抽象价值: 将 ResourceQuota 和 LimitRange 统一为
QuotaModel 后,Sigstore 策略只需对比“期望模型”与“运行时模型”的差异,即可精准识别配额漂移,无需分别解析两种不同的 Kubernetes 资源类型。
4.5 配额模型漂移检测流程(SVG 架构图)
下图展示了从 YAML 定义到配额模型抽象,再到漂移检测的完整链路:
4.6 配额模型抽象的关键字段映射表
下表将 Kubernetes 原生字段映射到抽象模型字段,便于策略编写者理解转换逻辑:
| Kubernetes 原生字段 | 抽象模型字段 | 数据类型 | 漂移检测示例 |
|---|---|---|---|
spec.hard.requests.cpu |
resourceQuota.requests.cpu |
string (Kubernetes quantity) | 期望 "32" → 运行时 "64" → 漂移 |
spec.limits[0].max.cpu |
limitRange.container.max.cpu |
string (Kubernetes quantity) | 期望 "4" → 运行时 "8" → 漂移 |
spec.scopeSelector.matchExpressions |
scopeSelector.matchExpressions |
array of objects | 期望包含 PriorityClass → 运行时缺失 → 漂移 |
spec.limits[0].maxLimitRequestRatio.cpu |
limitRange.container.maxLimitRequestRatio.cpu |
integer | 期望 4 → 运行时 10 → 漂移 |
4.7 配额模型设计的避坑指南
常见设计错误:
- 忽略 scopeSelector:仅比较 hard 字段,导致高优先级 Pod 的配额豁免被遗漏检测。
- 硬编码资源值:在策略中写死 "32" 或 "128Gi",而非从模型抽象层读取,导致集群扩容后策略失效。
- 未处理默认值注入:LimitRange 的 default 字段会在 Pod 创建时自动注入,策略模型必须包含默认值,否则漂移检测会误报。
- 存储配额遗漏:只关注 CPU/内存,忽略
requests.storage和persistentvolumeclaims,导致存储资源超卖。
最佳实践:
- 将 ResourceQuota 和 LimitRange 的 YAML 存储在 Git 仓库中,作为“单一事实来源”。
- 使用 Sigstore 策略定期(如每 5 分钟)对比 Git 中的期望模型与集群运行时模型。
- 在配额模型抽象层增加
metadata.cluster和metadata.environment标签,支持多集群差异化策略。