4. 资源模型核心对象:CPU、内存、存储、网络带宽、GPU等资源的建模方式与抽象层级
在多租户控制面架构中,资源模型是连接物理基础设施与上层调度策略的桥梁。核心资源对象(CPU、内存、存储、网络带宽、GPU)的建模方式直接决定了集群的利用率、隔离性以及容量规划的精度。本章将深入剖析每种资源的抽象层级、量化单位与建模范式。
4.1 资源抽象层级总览
资源模型通常分为三个抽象层级,从底层物理资源到上层租户可见的抽象资源,每一层解决不同的关注点:
| 抽象层级 | 代表对象 | 关注点 | 典型操作 |
|---|---|---|---|
| L1 物理/设备层 | Node、GPU Device、磁盘 | 总量、拓扑、NUMA亲和性 | 发现、健康检查、固件管理 |
| L2 资源池层 | ResourcePool、StorageClass | 配额、超分比、隔离域 | 池化、超分、预留、限额 |
| L3 租户可见层 | Pod Resource、PVC、NetworkPolicy | 请求量、限制量、QoS | 声明、调度、限流、计费 |
关键设计原则: 租户可见层只暴露“请求(Request)”与“限制(Limit)”两个语义,底层物理拓扑与超分策略对租户透明,从而简化租户模型并保留平台侧优化空间。
4.2 CPU 与内存:可压缩与不可压缩资源
CPU 与内存是调度中最核心的两种资源,其建模差异在于可压缩性:CPU 可被限流(throttle),内存不可压缩(OOM 风险)。
4.2.1 CPU 建模方式
- 单位: 核心数(cores),支持小数精度(如 0.5 core = 500m)。
- 抽象层级: 租户层使用 milliCPU(m)作为最小粒度;池化层按物理核与超分比计算可分配总量。
- 超分策略: 控制面通常允许 CPU 超分(如 8:1),但需配合
cpuManagerPolicy保证延迟敏感工作负载的独占性。 - 拓扑感知: 在 L1 层记录 NUMA 拓扑,调度时通过 TopologyManager 实现 CPU 与内存的亲和性分配。
4.2.2 内存建模方式
- 单位: 字节(Bytes),常用 GiB 或 MiB。
- 不可压缩特性: 内存超分比通常较低(1.2:1 ~ 1.5:1),且必须设置硬限制(Limit)防止租户越界。
- 回收机制: 控制面需监控实际使用量,当接近 Limit 时触发 Eviction 或 OOM Kill。
- HugePages: 对于数据库、DPDK 等场景,需建模 HugePages 作为独立资源类型,避免与普通内存混用。
实践建议: 在资源模型中为 CPU 和内存分别定义
capacity(物理总量)、allocatable(扣除系统开销后的可分配量)、requested(已分配量)三个字段,便于容量规划与碎片分析。
4.3 存储:从本地盘到分布式存储的抽象
存储资源建模需覆盖容量、性能(IOPS/吞吐)、持久性三个维度。多租户场景下,存储的隔离性比容量更关键。
| 存储类型 | 建模单位 | 关键属性 | 租户隔离方式 |
|---|---|---|---|
| 临时存储(EmptyDir) | GiB | 本地盘、随 Pod 生命周期 | Pod 级别限制(sizeLimit) |
| 块存储(云盘/本地盘) | GiB + IOPS | 持久化、快照、加密 | PVC 绑定 + StorageClass 隔离 |
| 文件存储(NAS/CFS) | GiB + 吞吐量 | 共享、多读多写、容量弹性 | 子目录隔离 + 配额限制 |
| 对象存储(S3/MinIO) | GiB + 请求数 | 无限扩展、RESTful 接口 | Bucket 隔离 + IAM 策略 |
4.3.1 存储资源池化模型
控制面通过 StorageClass 将底层存储设备抽象为多个资源池,每个池可定义:
- provisioner: 存储后端驱动(如 csi-nfs、csi-rbd)。
- reclaimPolicy: 回收策略(Retain/Delete)。
- allowVolumeExpansion: 是否支持在线扩容。
- mountOptions: 挂载参数(如 noatime、hard)。
容量规划陷阱: 存储的“可用容量”不等于“物理容量”。分布式存储(如 Ceph)需考虑副本因子(3x)、故障域冗余(至少 1 个 OSD 故障余量)以及数据压缩比。建议在资源模型中增加
usableCapacity 字段,由存储控制器实时计算。
4.4 网络带宽:容易被忽略的共享资源
网络带宽在多租户环境中常被忽略,但却是影响性能隔离的关键因素。建模方式分为节点级和租户级两个维度。
4.4.1 节点级带宽建模
- 物理带宽: 网卡速率(如 25Gbps、100Gbps),作为节点 capacity 的一部分。
- 可分配带宽: 扣除系统组件(kubelet、CNI、监控)开销后的剩余带宽。
- 超分比: 网络带宽通常不超分,但可通过 QoS 策略(如 HTB、TC)实现带宽保证。
4.4.2 租户级带宽建模
- Ingress/Egress 限速: 使用
kubernetes.io/egress-bandwidth等 annotation 声明。 - 网络策略: 通过 NetworkPolicy 限制租户间流量,间接控制带宽争用。
- SR-IOV 与 DPDK: 对于高性能场景,将物理网卡划分为 VF,作为独立资源分配给租户。
# 租户带宽声明示例(使用 CNI 插件 bandwidth)
apiVersion: v1
kind: Pod
metadata:
annotations:
kubernetes.io/ingress-bandwidth: "1G"
kubernetes.io/egress-bandwidth: "500M"
spec:
containers:
- name: app
image: nginx
resources:
requests:
cpu: "2"
memory: "4Gi"
4.5 GPU 与异构计算资源:独占与分时模型
GPU 资源建模面临的最大挑战是共享粒度与显存隔离。当前主流建模方式分为三种:
| 模型 | 粒度 | 隔离性 | 典型场景 | 代表实现 |
|---|---|---|---|---|
| 整卡独占 | 1 GPU | 强(物理隔离) | 训练、大模型推理 | nvidia.com/gpu |
| MIG/分区 | 1/7 GPU(A100) | 中(硬件隔离) | 多租户推理、开发测试 | nvidia.com/mig |
| 时间片共享 | 百分比 | 弱(软件隔离) | 轻量推理、批处理 | gpu-operator 时间片 |
4.5.1 GPU 资源模型关键字段
- gpu-count: 请求的 GPU 数量(整数或 MIG 切片)。
- memory: 显存需求(如 16Gi),用于 MIG 或时间片模型的显存预留。
- compute-capability: 计算能力版本(如 8.0),用于兼容性校验。
- affinity: GPU 间拓扑(NVLink、PCIe 交换),用于多卡通信优化。
4.6 资源建模的通用范式与扩展性
无论资源类型如何,多租户控制面的资源模型都应遵循以下通用范式:
- 声明式资源请求: 租户通过
resources.requests和resources.limits声明需求,控制面负责映射到池化资源。 - 资源维度正交化: 每种资源类型独立建模,避免耦合(如 CPU 与内存解耦,GPU 与网络带宽解耦)。
- 扩展资源机制: 通过
kubernetes.io/前缀或自定义资源名称(如example.com/FPGA)支持新硬件。 - 资源计量与计费: 在资源模型中嵌入计量字段(如
pricePerUnit、billingModel),为后续成本分摊提供数据基础。
// 资源模型核心数据结构示例(Go 伪代码)
type ResourceModel struct {
CPU ResourceDimension `json:"cpu"` // 单位:m
Memory ResourceDimension `json:"memory"` // 单位:Mi
Storage ResourceDimension `json:"storage"` // 单位:Gi
NetworkBW ResourceDimension `json:"networkBw"` // 单位:Mbps
GPU GPUResource `json:"gpu"` // 扩展资源
Extended map[string]ResourceDimension `json:"extended"` // 自定义扩展
}
type ResourceDimension struct {
Capacity int64 `json:"capacity"` // 物理总量
Allocatable int64 `json:"allocatable"` // 可分配量
Requested int64 `json:"requested"` // 已分配量
OversubRate float64 `json:"oversubRate"` // 超分比
}
type GPUResource struct {
Count int `json:"count"`
MemoryPerGPU int64 `json:"memoryPerGpu"` // 显存(Mi)
ComputeCap string `json:"computeCap"`
PartitionMode string `json:"partitionMode"` // exclusive | mig | timeslice
}
容量规划启示: 资源模型的抽象层级越高,对底层拓扑的感知越弱,调度灵活性越强,但碎片风险也越大。建议在 L2 资源池层保留拓扑标签(如
topology.kubernetes.io/zone、node-role.kubernetes.io/gpu),以便在调度时进行局部性优化。