4. 第一层
基础设施配额层是资源配额模型的最底层,直接映射到物理或虚拟化基础设施的原始资源。该层定义了平台能够分配给租户或工作负载的最小资源单元与上限。在本层中,策略即代码(Policy as Code)将基础设施的容量约束转化为可编程、可审计的策略规则,确保资源分配不超出物理边界。
4.1 计算资源配额:CPU 与内存
计算配额是基础设施层最核心的约束,决定了工作负载能够获得的处理能力与临时存储容量。在策略即代码模型中,CPU 和内存配额通常以“预留(Reservation)”和“限制(Limit)”两种维度定义。
| 维度 | CPU 配额定义 | 内存配额定义 | 策略示例(OPA/Rego) |
|---|---|---|---|
| 预留(Reservation) | 保证可用的最小 CPU 核心数(如 0.5 vCPU) | 保证可用的最小内存量(如 512 MiB) | request.cpu <= 2.0 |
| 限制(Limit) | 允许使用的最大 CPU 核心数(如 4 vCPU) | 允许使用的最大内存量(如 8 GiB) | limit.memory <= 8192 |
| 突发(Burst) | 允许短时超限的 CPU 百分比(如 200%) | 通常不允许内存突发 | burst.cpu <= 200 |
4.2 存储资源配额:磁盘容量与 IOPS
存储配额涵盖持久化数据的容量与性能两个维度。容量配额控制磁盘大小,IOPS(Input/Output Operations Per Second)配额控制存储的吞吐能力。在策略即代码中,存储配额通常与存储类(StorageClass)绑定,实现不同性能层级的差异化管控。
- 磁盘容量(Disk Size): 定义每个卷的最小/最大容量,如 10 GiB ~ 500 GiB。
- IOPS 限制: 定义每秒读写操作次数上限,如 3000 IOPS。
- 吞吐量(Throughput): 定义每秒数据传输速率,如 125 MB/s。
- 卷数量(Volume Count): 定义每个租户或命名空间允许创建的持久卷总数。
# OPA Rego 策略示例:存储配额校验
package infra.storage
# 允许的存储类列表
allowed_storage_classes := {"ssd-high", "hdd-standard"}
# 磁盘容量必须在 10Gi ~ 500Gi 之间
valid_size(size) {
size >= 10
size <= 500
}
# IOPS 不能超过存储类上限
valid_iops(storage_class, iops) {
storage_class == "ssd-high"
iops <= 10000
} {
storage_class == "hdd-standard"
iops <= 3000
}
# 拒绝不符合配额规则的 PVC 创建请求
deny[msg] {
input.kind == "PersistentVolumeClaim"
not valid_size(input.spec.resources.requests.storage)
msg = sprintf("存储卷容量 %v Gi 超出配额范围 [10, 500]", [input.spec.resources.requests.storage])
}
4.3 网络资源配额:带宽与 IP 地址
网络配额控制工作负载之间的通信能力与地址空间消耗。在云原生环境中,网络配额通常包括带宽限制、IP 地址数量、端口范围以及网络策略的生效范围。
| 配额项 | 典型值 | 策略即代码校验点 |
|---|---|---|
| 出站带宽(Egress Bandwidth) | 100 Mbps ~ 10 Gbps | 检查 Pod/VM 的 QoS 标记 |
| 入站带宽(Ingress Bandwidth) | 100 Mbps ~ 10 Gbps | 检查网络策略的速率限制 |
| 可用 IP 地址数 | 每个 VPC/子网 256 ~ 65536 | 检查 CIDR 分配是否超限 |
| 负载均衡器数量 | 每个租户 5 ~ 50 个 | 检查 Service 类型为 LoadBalancer 的计数 |
| 安全组规则数 | 每个安全组 50 ~ 100 条 | 检查入站/出站规则数量 |
4.4 基础设施配额层的分层架构图
下图展示了基础设施配额层的三层资源域及其策略管控关系。每个资源域内部包含具体的配额项,策略引擎在资源创建请求到达时进行校验。
4.5 配额定义的最佳实践
关键原则:基础设施配额层应遵循“最小保证、最大限制、可观测”的三位一体策略。
- 最小保证(Guarantee): 预留值确保工作负载在资源竞争时获得最低性能。
- 最大限制(Limit): 限制值防止单个工作负载耗尽集群资源,导致“吵闹邻居”问题。
- 可观测(Observability): 所有配额使用情况应暴露为指标(Metrics),供策略引擎和运维人员实时监控。
在策略即代码的实现中,基础设施配额层的策略通常以 ClusterPolicy 或 ValidatingWebhookConfiguration 的形式部署,作用于整个集群。以下是一个完整的 OPA 策略片段,展示了如何将 CPU、内存、存储和网络配额整合为一个准入控制规则集:
package infra.quota
# 全局配额上限
global_limits := {
"cpu": 4,
"memory": 8192,
"storage": 500,
"iops": 10000,
"bandwidth": 10240
}
# 校验计算资源
deny[msg] {
input.kind == "Pod"
container := input.spec.containers[_]
container.resources.limits.cpu > global_limits.cpu
msg = sprintf("容器 %v 的 CPU 限制 %v 超过全局上限 %v", [container.name, container.resources.limits.cpu, global_limits.cpu])
}
# 校验存储资源
deny[msg] {
input.kind == "PersistentVolumeClaim"
size := input.spec.resources.requests.storage
size > global_limits.storage
msg = sprintf("PVC %v 的存储请求 %v Gi 超过全局上限 %v", [input.metadata.name, size, global_limits.storage])
}
# 校验网络带宽(通过注解声明)
deny[msg] {
input.kind == "Pod"
annotation := input.metadata.annotations["kubernetes.io/egress-bandwidth"]
bandwidth := split(annotation, "M")[0]
to_number(bandwidth) > global_limits.bandwidth
msg = sprintf("Pod %v 的出口带宽 %v Mbps 超过全局上限 %v", [input.metadata.name, bandwidth, global_limits.bandwidth])
}
4.6 配额冲突与优先级处理
当多个策略同时作用于同一资源时,基础设施配额层需要定义明确的冲突解决规则。常见的处理策略包括:
- 拒绝优先(Deny by Default): 任何一条策略拒绝请求,则整个请求被拒绝。
- 最小权限(Least Privilege): 当多个策略给出不同上限时,取最小值作为最终配额。
- 显式覆盖(Explicit Override): 允许通过标签或注解显式指定使用某条策略,忽略其他冲突规则。
通过以上定义,基础设施配额层为整个资源配额模型提供了坚实的底层约束。下一层(租户配额层)将在此基础上引入多租户隔离与资源池化策略。