4. 资源模型核心对象:CPU、内存、存储、网络带宽、GPU等资源的建模方式与抽象层级

在多租户控制面架构中,资源模型是连接物理基础设施与上层调度策略的桥梁。核心资源对象(CPU、内存、存储、网络带宽、GPU)的建模方式直接决定了集群的利用率、隔离性以及容量规划的精度。本章将深入剖析每种资源的抽象层级、量化单位与建模范式。

4.1 资源抽象层级总览

资源模型通常分为三个抽象层级,从底层物理资源到上层租户可见的抽象资源,每一层解决不同的关注点:

抽象层级 代表对象 关注点 典型操作
L1 物理/设备层 Node、GPU Device、磁盘 总量、拓扑、NUMA亲和性 发现、健康检查、固件管理
L2 资源池层 ResourcePool、StorageClass 配额、超分比、隔离域 池化、超分、预留、限额
L3 租户可见层 Pod Resource、PVC、NetworkPolicy 请求量、限制量、QoS 声明、调度、限流、计费
关键设计原则: 租户可见层只暴露“请求(Request)”与“限制(Limit)”两个语义,底层物理拓扑与超分策略对租户透明,从而简化租户模型并保留平台侧优化空间。
资源抽象三层模型与映射关系 L3 租户可见层 Pod Resource (CPU: 2, Mem: 4Gi) | PVC (10Gi, ssd-premium) | Network Bandwidth (100Mbps) L2 资源池层 CPU Pool (超分比 8:1) | Memory Pool (超分比 1.5:1) | StorageClass (replica=3) | GPU Pool (独占) L1 物理/设备层 NUMA Node 0/1 | GPU A100 x4 | NVMe SSD x8 | 25GbE NIC x2 映射方向:租户声明 → 池化调度 → 物理绑定;反向用于容量核算与碎片回收

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 交换),用于多卡通信优化。
GPU 资源建模三种模式对比 整卡独占 GPU 0 GPU 1 租户A独占整卡 MIG 分区 1g 2g 3g 4g 硬件分区,显存隔离 时间片共享 租户A 50% | 租户B 30% | 租户C 20% 时间片轮转 + 显存超分 软件隔离,适合推理 建模选择建议 • 整卡独占:适用于训练任务、大模型推理,资源模型简单,但碎片率高。 • MIG 分区:适用于多租户推理、开发环境,需控制面支持 MIG 设备插件与拓扑调度。 • 时间片共享:适用于轻量推理、批处理,需配合显存隔离机制(如 GPU Memory Manager)。 • 混合模型:同一集群可同时支持三种模式,通过 ResourceClass 或 RuntimeClass 区分。 • 容量规划时,需将 GPU 显存与计算单元分开建模,避免显存不足导致调度失败。

4.6 资源建模的通用范式与扩展性

无论资源类型如何,多租户控制面的资源模型都应遵循以下通用范式:

  1. 声明式资源请求: 租户通过 resources.requests 和 resources.limits 声明需求,控制面负责映射到池化资源。
  2. 资源维度正交化: 每种资源类型独立建模,避免耦合(如 CPU 与内存解耦,GPU 与网络带宽解耦)。
  3. 扩展资源机制: 通过 kubernetes.io/ 前缀或自定义资源名称(如 example.com/FPGA)支持新硬件。
  4. 资源计量与计费: 在资源模型中嵌入计量字段(如 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),以便在调度时进行局部性优化。