Kubernetes GPU 虚拟化实战:HAMi DRA 模式完整指南
3 分钟阅读
一块 A10 24GB 显存的 GPU,在传统模式下只能给一个 Pod 用。但如果跑的是 batch 推理任务,很可能只用到了 10GB 显存和 30% 算力——剩下 14GB 就这么空着。
如果能把一块物理 GPU 按显存和算力细粒度地切分,让多个 Pod 共享呢?
这就是 HAMi 要解决的问题。
本文聚焦 HAMi DRA 模式的部署与使用。Kubernetes 在 1.34 中正式 GA 了 DRA(Dynamic Resource Allocation),让调度器参与资源分配,在 Pod 调度阶段就精确匹配设备属性。HAMi 的 2.9 版本已经正式接入了 DRA。
什么是 HAMi
HAMi(异构 AI 计算虚拟化中间件)是一个用于管理 Kubernetes 集群中异构 AI 计算设备的开源平台,前身为 k8s-vGPU-scheduler。
核心能力
| 能力 | 说明 |
|---|---|
| 多设备支持 | 兼容多种异构 AI 计算设备(GPU、NPU 等) |
| 共享访问 | 多个容器可同时共享设备,提高资源利用率 |
| 硬限制 | 在容器内强制执行严格的内存限制,防止资源冲突 |
| 动态分配 | 根据工作负载需求按需分配设备内存 |
| 灵活单位 | 支持按 MB 或占总设备内存百分比的方式指定内存分配 |
| 类型选择 | 可请求特定类型的异构 AI 计算设备 |
| UUID 定向 | 使用设备 UUID 精确指定特定设备 |
| 工作负载透明 | 容器内无需修改代码 |
| 简单部署 | 使用 Helm 轻松安装和卸载 |
| 社区驱动 | 由互联网、金融、制造业、云服务等多领域组织联合发起 |
DRA 模式的两条路径
DRA 的核心改进在于:调度器在 Pod 调度阶段就能精确匹配设备属性,避免了 DevicePlugin"调度到节点后才发现资源不够"的问题。
HAMi DRA 提供了两种使用模式:
| 模式 | ResourceClaim 创建 | 适用场景 |
|---|---|---|
| 原生 DRA 模式 | 手动创建 ResourceClaim | 新业务,精细化控制 |
| DevicePlugin 兼容模式 | Webhook 自动转换 | 存量业务零改造迁移 |
两种模式的底层调度与切分逻辑完全一致,差异仅在于 ResourceClaim 的创建方式。
环境要求
| 要求 | 说明 |
|---|---|
| Kubernetes | 1.34+,需开启 DRAConsumableCapacity Feature Gate |
| Container Runtime | 必须开启 CDI |
| NVIDIA 驱动 | 440 及以上版本 |
⚠️ 特别注意:
DRAConsumableCapacity在 1.36 才默认开启,1.34、1.35 需手动配置 Feature Gate。
HAMi 安装
第一步:安装 GPU Operator(关闭 DevicePlugin)
helm repo add nvidia https://helm.ngc.nvidia.com/nvidia && helm repo update
helm upgrade --install --wait gpu-operator \
-n gpu-operator --create-namespace \
nvidia/gpu-operator \
--version=v26.3.1 \
--set driver.enabled=true \
--set devicePlugin.enabled=false
关键参数 --set devicePlugin.enabled=false:关闭 DevicePlugin,避免与后续安装的 DRA Driver 冲突。
第二步:安装 cert-manager
HAMi DRA Webhook 需要 TLS 证书,因此需要提前安装 cert-manager 用于自动签发。
helm repo add cert-manager https://charts.jetstack.io
helm repo update
helm install cert-manager cert-manager/cert-manager \
-n cert-manager --create-namespace \
--set crds.enabled=true
第三步:Helm 安装 HAMi
先为节点打标签,未标记的节点不会被 HAMi 接管:
kubectl label nodes {nodeid} gpu=on
然后安装 HAMi:
helm repo add hami-charts https://project-hami.github.io/HAMi/
helm -n hami-system install hami hami-charts/hami \
--set dra.enabled=true \
--create-namespace
⚠️ 注意:DRA 模式与传统模式不兼容,请勿同时启用。如果 GPU 驱动是主机预装(非 GPU Operator 安装),则需额外指定
--set hami-dra.drivers.nvidia.containerDriver=false。
验证安装
正常情况下,会在 hami-system 命名空间下启动以下 Pod:
NAME READY STATUS RESTARTS AGE
hami-dra-driver-kubelet-plugin-hflbh 1/1 Running 0 2m49s
hami-hami-dra-monitor-7b484d5f95-rlkcg 1/1 Running 0 22m
hami-hami-dra-webhook-64bfdc6b86-d4nlr 1/1 Running 0 22m
查看 ResourceSlice 确认 dra-driver 正常发布资源:
kubectl get resourceslice

ResourceSlice 的详情中记录了 GPU 的架构、型号、显存等信息,用 -oyaml 查看完整字段:
apiVersion: resource.k8s.io/v1
kind: ResourceSlice
metadata:
name: ecs-a10-sh-hami-core-gpu.project-hami.io-hnn6d
spec:
devices:
- attributes:
architecture:
string: Ampere
brand:
string: Nvidia
productName:
string: NVIDIA A10
cudaComputeCapability:
version: 8.6.0
driverVersion:
version: 550.144.3
type:
string: hami-gpu
uuid:
string: GPU-f1c7d08c-ae21-13e7-0de0-9eb14ff71eaf
capacity:
cores:
value: "100"
memory:
value: 23028Mi
name: hami-gpu-0
driver: hami-core-gpu.project-hami.io
nodeName: ecs-a10-sh
使用:两种模式实战
原生 DRA 模式
先创建 ResourceClaim 声明资源需求,再创建 Pod 引用该 Claim:
# 申请 10G 显存 + 50 cores 的 A10 GPU
apiVersion: resource.k8s.io/v1
kind: ResourceClaim
metadata:
name: gpu-half-claim
spec:
devices:
requests:
- name: gpu
exactly:
deviceClassName: hami-core-gpu.project-hami.io
allocationMode: ExactCount
count: 1
capacity:
requests:
cores: 50
memory: "10Gi"
---
apiVersion: v1
kind: Pod
metadata:
name: gpu-test-dra-native
spec:
containers:
- name: cuda
image: nvidia/cuda:13.0.1-base-ubi9
command: ["sleep", "3600"]
resources:
claims:
- name: gpu
resourceClaims:
- name: gpu
resourceClaimName: gpu-half-claim
restartPolicy: Never
查看 ResourceClaim 的分配状态:
kubectl get resourceclaim gpu-half-claim -oyaml
关键输出:
status:
allocation:
devices:
results:
- consumedCapacity:
cores: "50"
memory: 10Gi
device: hami-gpu-0
driver: hami-core-gpu.project-hami.io
pool: ecs-a10-sh
request: gpu
shareID: 6108e68f-a7ec-4a30-9782-634885c0c728
进入 Pod 执行 nvidia-smi,可以看到显存限制为我们申请的 10G:

显存从物理的 23028Mi 限制到了申请的 10240Mi——HAMi 生效了。
DevicePlugin 兼容模式
原生 DRA 模式需要手动创建 ResourceClaim,对存量业务不够友好。为了便于迁移,HAMi 提供了兼容模式:
用户仍然像传统方式在 resources 中申请资源,由 HAMi DRA Webhook 自动拦截并转换为 ResourceClaim。
# 申请 1 块 GPU,10Gi 显存 + 50% 算力
apiVersion: v1
kind: Pod
metadata:
name: gpu-test-compatible
spec:
containers:
- name: cuda
image: nvidia/cuda:13.0.1-base-ubi9
command: ["sleep", "3600"]
resources:
limits:
nvidia.com/gpu: 1
nvidia.com/gpumem: 10240
nvidia.com/gpucores: 50
restartPolicy: Never
HAMi 会根据 nvidia.com/gpumem、nvidia.com/gpucores 自动生成 ResourceClaim:
kubectl get resourceclaim
NAME STATE AGE
default-gpu-test-compatible-cuda allocated,reserved 2m47s
Webhook 转换的映射关系:
| Pod 配置 | ResourceClaim 中的值 |
|---|---|
nvidia.com/gpu: 1 | count: 1, 选择器 type == "hami-gpu" |
nvidia.com/gpumem: 10240 | memory: "10737418240" (10Gi 的字节值) |
nvidia.com/gpucores: 50 | cores: "50" |
Pod 中执行 nvidia-smi,同样验证显存限制生效:

兼容模式也正常生效了,存量业务零改造即可迁移。
小结
对于已在用 DevicePlugin 方式的存量业务,兼容模式提供了零改造的迁移路径,只需安装 HAMi DRA 后,原有的 GPU 资源申请方式就能自动转换为 DRA 模式运行。
对于新业务,原生 DRA 模式提供了更精细化的控制能力,可以在 ResourceClaim 中精确指定显存、算力甚至特定 GPU UUID。