HAMi 技术文档索引

CNCF Sandbox Go Version License Build Status


项目简介

HAMi(Heterogeneous AI Computing Virtualization Middleware) 是 CNCF Sandbox 级别的开源项目,旨在为 Kubernetes 集群提供异构加速设备(GPU、NPU、MLU、DCU 等)的虚拟化与共享调度能力。HAMi 通过 Scheduler Extender、Mutating Webhook、Device Plugin 以及用户态拦截库(libvgpu.so)四大核心组件,实现了对 NVIDIA GPU 等硬件设备的细粒度显存与算力隔离,使多个容器能安全地共享同一块物理设备,从而大幅提升集群 GPU 利用率并降低基础设施成本。


整体架构

下图展示了一个 Pod 从提交到最终在容器内使用 vGPU 的完整数据流:

flowchart LR subgraph user["用户层"] A["Pod Submit (kubectl apply)"] end subgraph controlplane["Kubernetes 控制平面"] B["API Server"] C["Mutating Webhook"] D["kube-scheduler"] end subgraph hamischeduler["HAMi Scheduler (Scheduler Extender)"] E["Filter (节点筛选)"] F["Bind (设备绑定)"] end subgraph nodecomponents["节点组件"] G["kubelet"] H["Device Plugin (ListAndWatch / Allocate)"] I["Container Runtime"] end subgraph container["容器内部"] J["libvgpu.so (LD_PRELOAD 拦截)"] K["用户应用"] end subgraph observability["可观测性"] L["vGPU Monitor"] M["Prometheus"] end A -->|"创建 Pod"| B B -->|"Admission Review"| C C -->|"注入 vGPU 资源请求"| B B -->|"调度请求"| D D -->|"Extender Filter"| E E -->|"返回可用 节点列表"| D D -->|"Extender Bind"| F F -->|"写入设备分配 Annotation"| B B -->|"绑定节点"| G G -->|"Allocate 请求"| H H -->|"配置环境变量 挂载 libvgpu.so"| I I --> J J -->|"API 拦截 显存/算力限制"| K L -->|"采集 vGPU 使用指标"| M style user fill:#e8f5e9,stroke:#4caf50,color:#000 style controlplane fill:#e3f2fd,stroke:#2196f3,color:#000 style hamischeduler fill:#fff3e0,stroke:#ff9800,color:#000 style nodecomponents fill:#f3e5f5,stroke:#9c27b0,color:#000 style container fill:#fce4ec,stroke:#e91e63,color:#000 style observability fill:#e0f2f1,stroke:#009688,color:#000

关键路径说明

阶段组件核心职责
准入Mutating Webhook将用户声明的 hami.io/vgpu 等资源转换为 Device Plugin 可识别的扩展资源
调度Scheduler Extender (Filter)基于节点真实设备用量,筛选满足 vGPU 请求的节点
绑定Scheduler Extender (Bind)选定设备,将分配结果写入 Pod Annotation
分配Device Plugin (Allocate)读取 Annotation,配置环境变量和挂载卷,注入 libvgpu.so
拦截libvgpu.so在用户态通过 LD_PRELOAD 拦截 CUDA API,实施显存与算力配额
监控vGPU Monitor周期性采集容器 vGPU 使用量,暴露 Prometheus 指标

仓库组件结构

HAMi 项目由两个核心仓库组成:Go 语言实现的控制平面组件和 C 语言实现的设备拦截层。

flowchart TB subgraph hami_repo["HAMi 仓库 (Go)"] direction TB S["Scheduler Extender pkg/scheduler/"] W["Mutating Webhook pkg/webhook/"] DP["Device Plugin pkg/device-plugin/"] DM["Device Manager pkg/device/"] MON["vGPU Monitor pkg/monitor/"] API["API Types pkg/api/"] UTIL["Util & Config pkg/util/"] end subgraph core_repo["HAMi-core 仓库 (C)"] direction TB HOOK["CUDA Hook Layer src/cuda/"] MEM["Memory Manager src/memory/"] COMPUTE["Compute Limiter src/compute/"] SHM["Shared Memory IPC src/shm/"] LIB["libvgpu.so (最终产物)"] end S -->|"Annotation 传递设备分配"| DP DP -->|"挂载 + 环境变量"| LIB MON -->|"读取共享内存"| SHM HOOK --> MEM HOOK --> COMPUTE MEM --> SHM COMPUTE --> SHM style hami_repo fill:#e8eaf6,stroke:#3f51b5,color:#000 style core_repo fill:#fbe9e7,stroke:#ff5722,color:#000

核心数据类型

以下类图展示了 HAMi 中关键的数据结构及其关联关系:

classDiagram class Devices { <> +CommonWord() string +MutateAdmission(ctr *v1.Container, pod *v1.Pod) bool +CheckHealth(devType string, n *v1.Node) (bool, bool) +NodeCleanUp(nn string) error +GetNodeDevices(n v1.Node) ([]*api.DeviceInfo, error) +CheckType(annos map[string]string, d util.DeviceUsage, n util.ContainerDeviceRequest) (bool, bool, bool) +CheckUUID(annos map[string]string, d util.DeviceUsage) bool +LockNode(n *v1.Node, pod *v1.Pod) error +ReleaseNodeLock(n *v1.Node, pod *v1.Pod) error +Allocate(devs []*api.DeviceInfo, reqs util.ContainerDeviceRequest) ([]*api.DeviceInfo, error) +GenerateResourceRequests(ctr *v1.Container) util.ContainerDeviceRequest end class DeviceUsage { +ID string +Index uint +Used int32 +Count int32 +Usedmem int32 +Totalmem int32 +Totalcore int32 +Usedcores int32 +Numa int +Type string +Health bool } class DeviceInfo { +ID string +Index uint +Count int32 +Devmem int32 +Devcore int32 +Type string +Numa int +Health bool } class ContainerDeviceRequest { +Nums int32 +Type string +Memreq int32 +MemPercentagereq int32 +Coresreq int32 } class ContainerDevice { +Idx int +UUID string +Type string +Usedmem int32 +Usedcores int32 } class PodDevices { +Name string +UID string +Devices map~string~ContainerDevice[][] } class NodeInfo { +ID string +Node *v1.Node +Devices DeviceUsageList +Score float32 } class NodeScore { +NodeID string +Devices DeviceUsageList +Score float32 } Devices ..> DeviceInfo : "返回设备信息" Devices ..> ContainerDeviceRequest : "生成资源请求" NodeInfo --> DeviceUsage : "包含多个设备" NodeScore --> DeviceUsage : "评分关联设备" PodDevices --> ContainerDevice : "容器设备映射" ContainerDeviceRequest ..> DeviceUsage : "匹配检查"

数据类型说明

类型说明
Devices设备插件接口,所有硬件类型(NVIDIA、Cambricon、Hygon 等)必须实现此接口
DeviceUsage表示节点上单个设备的当前使用状态(已用/总量的显存和算力)
DeviceInfo设备的静态元信息(ID、类型、总显存、总算力、NUMA 节点)
ContainerDeviceRequest单个容器对设备的资源需求(数量、显存、算力比例)
ContainerDevice分配给容器的具体设备实例(UUID、已分配显存和算力)
PodDevicesPod 级别的设备分配汇总,映射容器名到其设备列表
NodeInfo调度器视角下的节点信息,包含所有设备使用状态和评分
NodeScoreFilter 和 Score 阶段产出的节点评分结果

模块目录

本技术文档按以下模块组织,涵盖从入门到深入的完整知识体系:

编号模块内容概述
01项目总览HAMi 项目背景、设计目标、整体架构与核心概念
02入门教程面向初学者的安装部署、快速上手与代码调试指南
03调度器深度解析Scheduler Extender 的 Filter / Score / Bind 链路,Binpack 与 Spread 策略,拓扑感知调度
04Webhook 准入控制Mutating Webhook 的资源注入逻辑、Pod 标注转换与默认值填充
05Device Plugin 机制Kubernetes Device Plugin 接口实现、ListAndWatch 注册流程与 Allocate 分配链路
06HAMi-core 拦截层libvgpu.so 的 CUDA API Hook、显存管理、算力限制与共享内存通信
07多设备支持NVIDIA GPU、Cambricon MLU、Hygon DCU、Iluvatar GPU 等设备的适配实现
08监控与可观测性vGPU Monitor 指标采集、Prometheus 集成与 Grafana 面板配置
09调试与排障常见问题排查、日志分析、调度链路 Debug 与性能诊断
10运维与生产实践高可用部署、升级策略、容量规划与最佳实践
11开发者贡献指南代码规范、开发环境搭建、测试框架与 PR 流程

术语表

术语全称 / 英文说明
vGPUVirtual GPUHAMi 定义的虚拟 GPU 抽象。通过软件方式将一块物理 GPU 切分为多个逻辑设备,每个 vGPU 拥有独立的显存配额和算力上限,供不同容器隔离使用。
Scheduler ExtenderKubernetes Scheduler ExtenderKubernetes 调度器扩展点。HAMi 通过实现 Filter 和 Bind 扩展,在原生调度流程中注入设备感知的节点筛选与设备绑定逻辑,确保 Pod 被调度到拥有足够可用 vGPU 资源的节点。
Device PluginKubernetes Device PluginKubernetes 设备插件框架(kubelet gRPC 接口)。HAMi Device Plugin 负责向 kubelet 注册 vGPU 扩展资源,并在 Allocate 阶段读取调度器写入的 Annotation,配置容器环境变量和挂载 libvgpu.so。
LD_PRELOADLD_PRELOAD Environment VariableLinux 动态链接器的环境变量,指定在加载其他共享库之前优先加载的库。HAMi-core 利用 LD_PRELOAD 将 libvgpu.so 注入容器进程,拦截 CUDA API 调用以实施显存和算力限制。
Shared Memory RegionPOSIX Shared Memory (shm)HAMi-core 使用的进程间通信机制。libvgpu.so 与 vGPU Monitor 通过共享内存区域交换设备使用量数据,Monitor 据此采集指标并检测是否超配。
NUMANon-Uniform Memory Access非统一内存访问架构。在多路服务器中,GPU 通常连接到特定 NUMA 节点。HAMi 调度器支持 NUMA 感知,尽量将 Pod 调度到 GPU 与 CPU 处于同一 NUMA 域的节点,以减少跨域内存访问延迟。
MIGMulti-Instance GPUNVIDIA Ampere 及更新架构支持的硬件级 GPU 分区技术。MIG 将一块物理 GPU 划分为多个独立的 GPU 实例,每个实例拥有独立的显存、缓存和计算单元。HAMi 可与 MIG 协同工作,在 MIG 实例上进一步进行软件级 vGPU 切分。
Topology-Aware Scheduling拓扑感知调度考虑 GPU 间互联拓扑(NVLink、PCIe Switch)的调度策略。当 Pod 请求多块 GPU 时,HAMi 调度器优先选择互联带宽最高的 GPU 组合,以优化多卡训练的通信性能。
BinpackBin Packing Strategy装箱调度策略。优先将 Pod 调度到已有较多设备被使用的节点上,使设备尽量集中使用,以减少资源碎片化并为大规模任务预留完整节点。
SpreadSpread Strategy分散调度策略。将 Pod 均匀分散到不同节点上,避免单节点过载,提高集群整体的容错能力和资源利用率均衡性。

推荐阅读顺序

对于不同角色的读者,建议按以下顺序阅读:

集群管理员 / SRE

01 项目总览02 入门教程08 监控与可观测性10 运维与生产实践09 调试与排障

平台开发者

01 项目总览03 调度器深度解析04 Webhook 准入控制05 Device Plugin 机制06 HAMi-core 拦截层

AI 应用开发者

01 项目总览02 入门教程07 多设备支持09 调试与排障

开源贡献者

01 项目总览11 开发者贡献指南 → 感兴趣的具体模块文档


HAMi Technical Documentation — CNCF Sandbox Project