news 2026/6/10 15:08:31

单节点 Kubernetes 部署 HAMi,并基于 8G 显卡测试 vGPU 切分

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
单节点 Kubernetes 部署 HAMi,并基于 8G 显卡测试 vGPU 切分

一、环境说明

这次测试环境是一套单节点 Kubernetes 集群,节点上有一张 NVIDIA GPU,显存 8G 左右。部署目标是使用 HAMi 对单张 GPU 做 vGPU 共享,让多个 Pod 可以共享同一张物理 GPU。

HAMi 原名k8s-vGPU-scheduler,现在是 Kubernetes 上的异构算力虚拟化中间件,主要用于 GPU、NPU 等异构设备的共享、隔离和调度。对于 NVIDIA GPU 来说,HAMi 可以让 Pod 按显存、GPU core 等维度申请资源,从而避免一个小任务独占整张 GPU。HAMi 官方文档中也说明,它支持多种异构 AI 计算设备,并且支持多个容器或工作负载共享设备资源。

本文主要测试以下内容:

1. 部署前检查 NVIDIA Driver 和 NVIDIA Container Toolkit 2. 使用 Helm 部署 HAMi 3. 验证 HAMi 组件是否正常 4. 测试一张 8G GPU 被两个 Pod 共享 5. 测试 nvidia.com/gpumem 显存切分 6. 测试 nvidia.com/gpumem-percentage 显存百分比切分 7. 测试 nvidia.com/gpucores 算力比例限制 8. 测试指定 GPU 型号 9. 测试指定 GPU UUID 10. 说明 nvidia.com/gpu: 2 这个容易误解的点

二、部署 HAMi 前需要准备什么

在 Kubernetes 上使用 NVIDIA GPU,大体要先解决三件事:

1. 宿主机能识别 GPU 2. 容器能使用 GPU 3. Kubernetes 能调度 GPU 资源

HAMi 官方 Helm 部署文档中提到,部署前需要在 GPU 节点上准备 NVIDIA Driver 和 NVIDIA Container Toolkit,并且假设nvidia-container-runtime已经配置为默认的底层运行时。也就是说,HAMi 本身不是用来安装显卡驱动的,驱动和容器运行时环境需要提前准备好。

这里有一点需要注意:

在 HAMi 场景下,通常不需要再单独部署 NVIDIA 官方 k8s-device-plugin。

原因是 HAMi 安装后会部署自己的hami-device-plugin,由它负责把 HAMi 管理的 GPU 资源注册给 kubelet。HAMi 官方 FAQ 也说明,HAMi Device Plugin、Volcano vGPU Device Plugin、NVIDIA 官方 Device Plugin 都会管理 GPU 资源,同一个节点上建议只使用一种 GPU 管理插件,避免资源冲突。

如果你的集群里已经通过 GPU Operator 部署了 NVIDIA 官方 device-plugin,需要注意不要让两个 device-plugin 同时管理同一种nvidia.com/gpu资源,否则很容易出现资源显示、调度行为和实际设备分配对不上的问题。


三、检查宿主机和容器 GPU 环境

3.1 检查宿主机 GPU 是否正常

先在宿主机上执行:

nvidia-smi

正常情况下应该能看到显卡信息,例如:

NVIDIA GeForce RTX 3070 Ti Laptop GPU Memory-Usage: 0MiB / 8192MiB

查看 GPU 型号:

nvidia-smi --query-gpu=name --format=csv,noheader

查看 GPU UUID:

nvidia-smi --query-gpu=index,name,uuid,memory.total --format=csv,noheader

示例输出:

0, NVIDIA GeForce RTX 3070 Ti Laptop GPU, GPU-998864a7-78d9-dbab-e122-4c37842ce7cf, 8192 MiB

后面测试nvidia.com/use-gputypenvidia.com/use-gpuuuid时会用到这两个值。


3.2 检查 Docker 容器是否能使用 GPU

如果你的机器上使用 Docker,可以先用 Docker 跑一个容器测试 GPU 是否能被容器识别。

docker run --rm --gpus all nvidia/cuda:11.0.3-base-ubuntu18.04 nvidia-smi

如果这里不能正常输出 GPU 信息,就不要急着安装 HAMi,应该先处理 NVIDIA Driver、NVIDIA Container Toolkit 或 Docker runtime 配置。


3.3 注意 Docker 和 containerd 的区别

这里要特别注意:

Docker 测试成功,不代表 Kubernetes Pod 一定能使用 GPU。

原因是现在很多 Kubernetes 集群默认使用的是 containerd,而不是 Docker。HAMi 官方部署文档里 Docker 和 containerd 的 NVIDIA runtime 配置是分开的:如果 Kubernetes 使用 Docker,需要把nvidia-container-runtime配成 Docker 的默认 runtime;如果 Kubernetes 使用 containerd,需要在 containerd 配置中把 NVIDIA runtime 配成默认 runtime。

可以通过下面命令查看节点使用的容器运行时:

kubectl get node -o wide

如果显示的是 containerd,可以使用 NVIDIA 官方推荐的方式配置:

sudo nvidia-ctk runtime configure --runtime=containerd sudo systemctl restart containerd

NVIDIA 官方文档也说明,Kubernetes 使用 containerd 时,可以通过nvidia-ctk runtime configure --runtime=containerd配置,然后重启 containerd。

如果是 Docker,则可以使用:

sudo nvidia-ctk runtime configure --runtime=docker sudo systemctl restart docker

本文后面的 Pod YAML 没有显式配置:

runtimeClassName: nvidia

前提是 NVIDIA runtime 已经被配置为默认容器运行时。如果你的集群不是默认使用 NVIDIA runtime,而是通过 RuntimeClass 暴露nvidiaruntime,那么需要根据实际环境给 Pod 增加:

runtimeClassName: nvidia

四、安装 HAMi

4.1 给 GPU 节点打标签

HAMi 默认只管理带有gpu=on标签的 GPU 节点。官方文档说明,需要给 GPU 节点打gpu=on标签,没有这个标签的节点不能被 HAMi scheduler 管理。先查看节点名称:

kubectl get node

给节点打标签:

kubectl label nodes master-01 gpu=on --overwrite

确认标签:

kubectl get node master-01 --show-labels | grep gpu=on

如果你发现hami-scheduler正常,但是hami-device-plugin没有起来,优先检查这个标签是否存在。


4.2 添加 HAMi Helm 仓库

先查看 Kubernetes Server 版本:

kubectl version

添加 HAMi Helm 仓库:

helm repo add hami-charts https://project-hami.github.io/HAMi/ helm repo update

4.3 安装 HAMi

安装时需要设置 kube-scheduler 镜像版本和 Kubernetes Server 版本匹配。HAMi 官方安装文档中也明确写到,scheduler.kubeScheduler.imageTag需要和 Kubernetes Server 版本保持一致。

例如 Kubernetes Server 版本是v1.29.0,安装命令如下:

helm install hami hami-charts/hami \ --set scheduler.kubeScheduler.imageTag=v1.29.0 \ -n kube-system

这里的v1.29.0要替换成你自己集群的 Kubernetes Server 版本。

如果你的版本是v1.27.9,那就写成:

helm install hami hami-charts/hami \ --set scheduler.kubeScheduler.imageTag=v1.27.9 \ -n kube-system

五、验证 HAMi 组件是否正常

执行:

kubectl -n kube-system get pod | grep -E "hami|vgpu"

新版本一般能看到类似:

hami-device-plugin-xxxxx 2/2 Running hami-scheduler-xxxxx 2/2 Running

老版本可能叫:

vgpu-device-plugin-xxxxx Running vgpu-scheduler-xxxxx Running

HAMi 官方文档中也说明,如果hami-device-pluginhami-scheduler都是 Running,说明安装成功。查看节点资源:

kubectl describe node master-01

重点看CapacityAllocatable

Capacity: nvidia.com/gpu: 10 Allocatable: nvidia.com/gpu: 10

这里有个容易误解的点:

nvidia.com/gpu: 10

这不是说机器上有 10 张物理 GPU,而是 HAMi 把一张物理 GPU 按默认配置注册成了多个可分配的 vGPU 份额。HAMi 配置中nvidia.deviceSplitCount默认值是10,含义是单张 GPU 默认最多允许分配给 10 个任务。所以在单卡 8G 的机器上看到nvidia.com/gpu: 10是正常现象。


六、HAMi 常用资源字段说明

HAMi 在 Pod 里主要通过下面几个资源字段控制 GPU 申请:

resources: limits: nvidia.com/gpu: 1 nvidia.com/gpumem: 3000 nvidia.com/gpucores: 30

字段含义如下:

nvidia.com/gpu 表示申请 GPU/vGPU 设备分配实例。安装 HAMi 后,节点上看到的 nvidia.com/gpu 数量通常来自 HAMi 的 deviceSplitCount 配置。例如单卡默认可能显示为 10,但这个 10 不是 10 张物理 GPU,也不表示单个 Pod 可以从同一张物理 GPU 上申请多个 vGPU。 nvidia.com/gpumem 表示申请多少 GPU 显存。官方示例中 nvidia.com/gpumem: 3000 表示每个 vGPU 申请 3G 左右显存。 nvidia.com/gpumem-percentage 表示按百分比申请显存。例如 10 表示申请这张 GPU 约 10% 的显存。 nvidia.com/gpucores 表示申请 GPU core 的比例。例如 30 可以理解为申请约 30% 的 GPU 算力。

这里注意一点:

nvidia.com/gpumem 和 nvidia.com/gpumem-percentage 不要同时写在同一个容器里。

前者表示按固定显存大小申请,后者表示按百分比申请,二者选择一种即可。HAMi 官方显存示例中也明确说明,nvidia.com/gpumem不能和nvidia.com/gpumem-percentage一起使用。

Kubernetes 里 GPU 这类扩展资源一般写在limits下。如果只写limits,Kubernetes 会默认把 limit 当作 request 使用。Kubernetes 官方文档也说明,GPU 可以只写 limits;如果同时写 requests 和 limits,两者必须相等;不能只写 GPU requests 而不写 limits。


七、容易误解的点:nvidia.com/gpu: 2不是从一张卡里拿 2 份 vGPU

前面在查看节点资源时,可以看到类似下面的结果:

Capacity: nvidia.com/gpu: 10 Allocatable: nvidia.com/gpu: 10

如果是单卡环境,这里很容易产生一个误解:

既然节点上显示 nvidia.com/gpu: 10, 是不是说明这一张物理 GPU 被切成了 10 份, 所以单个 Pod 写 nvidia.com/gpu: 2, 就是从这一张物理 GPU 里拿 2 份 vGPU?

这个理解是不对的。

HAMi 官方 FAQ 对这个问题有明确说明:deviceSplitCount: 10表示一张物理 GPU 最多可以同时服务 10 个任务,但它并不表示一个任务可以从同一张物理 GPU 上申请多个 vGPU。当一个任务申请nvidia.com/gpu: 2时,HAMi 会把它解释为需要两个物理 GPU,而不是从同一张 GPU 上申请两个 vGPU。也就是说,下面这种写法:

resources: limits: nvidia.com/gpu: 2

可以简单理解为:

这个 Pod 需要 2 个 GPU/vGPU 设备分配实例,并且这 2 个实例不能来自同一张物理 GPU。 对于我的单卡环境来说,可以简单理解为这个 Pod 需要 2 张物理 GPU,所以无法调度成功。

而不是:

这个 Pod 需要从 1 张 GPU 里拿 2 个 vGPU 份额。

所以在单节点、单张 8G GPU 环境里,如果创建下面这个 Pod:

apiVersion: v1 kind: Pod metadata: name: hami-gpu-2-test spec: restartPolicy: Never containers: - name: cuda image: nvidia/cuda:11.0.3-base-ubuntu18.04 command: ["bash", "-lc", "nvidia-smi && sleep 3600"] resources: limits: nvidia.com/gpu: 2 nvidia.com/gpumem: 2000 nvidia.com/gpucores: 30

这个 Pod 无法调度成功。因为当前节点只有一张物理 GPU,而 Pod 申请的是 2 个 GPU/vGPU 设备分配实例。创建后查看 Pod:

kubectl get pod hami-gpu-2-test

一般会看到它处于Pending状态:

NAME READY STATUS RESTARTS AGE hami-gpu-2-test 0/1 Pending 0 1m

继续查看事件:

kubectl describe pod hami-gpu-2-test

可以看到调度失败相关信息。这里要把两个概念分清楚:

deviceSplitCount 表示一张物理 GPU 最多允许多少个任务共享。 nvidia.com/gpu 表示这个 Pod 申请几个 GPU/vGPU 设备分配实例。 当单个 Pod 写成 nvidia.com/gpu: 2 时,HAMi 会按需要 2 个 GPU/vGPU 设备实例处理。 在单卡环境下,它无法从同一张物理 GPU 上拿到两个 vGPU。

HAMi FAQ 里也说明,vGPU 的设计目标是让多个任务共享同一张 GPU,而不是让一个任务在同一张 GPU 上绑定多个 vGPU。deviceSplitCount: 10只是允许最多 10 个任务共享该 GPU,并不会增加真实的物理 GPU 资源。

所以,如果目标是:

一张 8G GPU 同时跑两个 Pod

正确做法不是创建一个 Pod 并写:

nvidia.com/gpu: 2

而是创建两个 Pod,每个 Pod 都申请:

resources: limits: nvidia.com/gpu: 1 nvidia.com/gpumem: 3000 nvidia.com/gpucores: 30

也就是:

Pod A 申请 1 个 vGPU,3000MB 显存,30% GPU core。 Pod B 申请 1 个 vGPU,3000MB 显存,30% GPU core。

这样两个 Pod 才能共享同一张物理 GPU。


八、测试 1:运行一个基础 HAMi GPU Pod

先验证 HAMi 调度链路和容器内 GPU 可见性。

apiVersion: v1 kind: Pod metadata: name: hami-basic spec: restartPolicy: Never containers: - name: cuda image: nvidia/cuda:11.0.3-base-ubuntu18.04 command: ["bash", "-lc", "nvidia-smi && sleep 3600"] resources: limits: nvidia.com/gpu: 1 nvidia.com/gpumem: 2000 nvidia.com/gpucores: 30

进入容器验证:

kubectl exec -it hami-basic -- nvidia-smi

如果正常,会看到类似下面的输出:

[HAMI-core Msg(...): Initializing.....] Memory-Usage: 0MiB / 2000MiB

重点看容器里显示的总显存是否变成了你申请的值。例如这里申请的是2000,那么容器内看到的显存上限应该接近2000MiB


九、测试 2:一张 8G 卡切给两个 Pod,每个 Pod 申请 3G 显存

测试目的:

验证两个 Pod 是否可以共享同一张 8G 物理 GPU。 每个 Pod 申请 3000MB 显存。 两个 Pod 总共申请 6000MB,小于 8G,所以理论上可以同时 Running。

YAML 如下:

apiVersion: v1 kind: Pod metadata: name: hami-gpumem-3000-1 spec: restartPolicy: Never containers: - name: cuda image: nvidia/cuda:11.0.3-base-ubuntu18.04 command: ["bash", "-lc", "nvidia-smi && sleep 3600"] resources: limits: nvidia.com/gpu: 1 nvidia.com/gpumem: 3000 nvidia.com/gpucores: 30 --- apiVersion: v1 kind: Pod metadata: name: hami-gpumem-3000-2 spec: restartPolicy: Never containers: - name: cuda image: nvidia/cuda:11.0.3-base-ubuntu18.04 command: ["bash", "-lc", "nvidia-smi && sleep 3600"] resources: limits: nvidia.com/gpu: 1 nvidia.com/gpumem: 3000 nvidia.com/gpucores: 30

分别进入两个 Pod:

kubectl exec -it hami-gpumem-3000-1 -- nvidia-smi kubectl exec -it hami-gpumem-3000-2 -- nvidia-smi

预期结果:

两个 Pod 都能 Running。 两个 Pod 内执行 nvidia-smi 都能看到 GPU。 每个 Pod 内看到的 GPU 总显存大约是 3000MiB。

如果这两个 Pod 都能正常运行,说明 HAMi 已经可以把一张物理 GPU 按显存维度切给多个 Pod 使用。


十、测试 3:按显存百分比切分

除了直接写nvidia.com/gpumem,HAMi 也支持通过nvidia.com/gpumem-percentage按百分比申请显存。例如 8G 显存的 GPU,申请 10%:

apiVersion: v1 kind: Pod metadata: name: hami-gpumem-percent-10 spec: restartPolicy: Never containers: - name: cuda image: nvidia/cuda:11.0.3-base-ubuntu18.04 command: ["bash", "-lc", "nvidia-smi && sleep 3600"] resources: limits: nvidia.com/gpu: 1 nvidia.com/gpumem-percentage: 10 nvidia.com/gpucores: 10

验证:

kubectl exec -it hami-gpumem-percent-10 -- nvidia-smi

预期结果:

容器内看到的总显存约等于整卡显存的 10%。 如果物理卡是 8192MiB,那么 10% 大约就是 819MiB。

这里建议 Pod 名字和百分比保持一致。比如资源里写的是nvidia.com/gpumem-percentage: 10,Pod 名称就叫hami-gpumem-percent-10,避免后面排查时看乱。


十一、测试 4:按 GPU core 百分比限制

nvidia.com/gpucores可以理解为 HAMi 里用于申请 GPU 算力比例的字段。比如:

nvidia.com/gpucores: 30

可以简单理解为申请约 30% GPU core 算力。这里的30不是指 30 个物理 CUDA Core,而是 HAMi 定义的 GPU core 使用比例。测试 YAML:

apiVersion: v1 kind: Pod metadata: name: hami-gpucores-30 spec: restartPolicy: Never containers: - name: cuda image: nvidia/cuda:11.0.3-base-ubuntu18.04 command: ["bash", "-lc", "nvidia-smi && sleep 3600"] env: - name: GPU_CORE_UTILIZATION_POLICY value: "force" resources: limits: nvidia.com/gpu: 1 nvidia.com/gpumem: 2000 nvidia.com/gpucores: 30

查看:

kubectl get pod hami-gpucores-30 kubectl exec -it hami-gpucores-30 -- nvidia-smi

这里要注意:

nvidia-smi 只能证明容器能看到 GPU,以及显存视图是否被限制。 如果要验证 gpucores 的算力限制,需要运行 CUDA 压测程序观察 GPU-Util,而不是只看 nvidia-smi。

HAMi 官方文档说明,nvidia.com/gpucores是通过 time-slice 方式实现的,所以通过nvidia-smi查询 core utilization 时可能会有波动,不一定稳定卡在某一个固定数值。


十二、GPU_CORE_UTILIZATION_POLICY=force 是什么

在测试 HAMi 的 GPU core 限制时,经常会看到下面这个环境变量:

env: - name: GPU_CORE_UTILIZATION_POLICY value: "force"

这个配置不是 Kubernetes 原生字段,而是 HAMi 容器侧配置项,主要给容器里的 HAMi-core 使用。HAMi 官方配置文档把GPU_CORE_UTILIZATION_POLICY放在Container Configs: Env下面,也就是说它属于容器运行时侧的环境变量,不是 Kubernetes 原生资源字段。

要理解这个参数,关键是要把 HAMi 的两个阶段分开看:

第一阶段:调度阶段 HAMi scheduler 根据 Pod 里申请的 nvidia.com/gpu、nvidia.com/gpumem、nvidia.com/gpucores 判断当前节点、当前 GPU 是否还有足够资源。 第二阶段:容器运行阶段 Pod 启动以后,容器里的 CUDA/NVML 调用会受到 HAMi-core 的影响,从而让容器看到被分配后的 GPU 资源视图,并对显存、GPU core 等资源进行运行时控制。

先看 Pod 资源申请:

resources: limits: nvidia.com/gpu: 1 nvidia.com/gpumem: 2000 nvidia.com/gpucores: 30

这几个字段首先会进入 HAMi 的调度逻辑。它表达的是:

这个 Pod 需要 1 个 GPU/vGPU 设备分配实例; 这个 Pod 需要 2000MB 左右显存; 这个 Pod 需要 30% GPU core 配额。

所以在调度阶段,HAMi scheduler 会根据这些资源申请去判断:

这张 GPU 的剩余显存是否足够; 这张 GPU 的剩余 core 配额是否足够; 这个 Pod 是否可以放到这张 GPU 上。

举个例子,假设一张 GPU 上已经有一个 Pod 申请了:

nvidia.com/gpumem: 3000 nvidia.com/gpucores: 70

这时候再来一个 Pod 申请:

nvidia.com/gpumem: 3000 nvidia.com/gpucores: 40

即使显存还够,也可能因为 GPU core 配额不够而无法调度。这个阶段的重点是:

nvidia.com/gpucores 用于调度层面的资源计算。 HAMi scheduler 会根据它判断这张 GPU 还能不能继续放这个 Pod。

但是,调度成功不代表容器运行时一定会强制把 GPU 利用率压到30%以下。因为调度器只负责“把 Pod 放到哪里”,Pod 真正运行起来以后,就进入了 HAMi-core 的运行时控制阶段。

也就是说:

nvidia.com/gpucores: 30 首先表示:调度时我申请 30% GPU core 配额。 GPU_CORE_UTILIZATION_POLICY=force 表示:容器运行起来以后,HAMi-core 也要强制按照 nvidia.com/gpucores 的值去限制 GPU core utilization。

这才是GPU_CORE_UTILIZATION_POLICY=force的重点。

12.1 不加 GPU_CORE_UTILIZATION_POLICY=force 时

如果只写:

resources: limits: nvidia.com/gpu: 1 nvidia.com/gpumem: 2000 nvidia.com/gpucores: 30

而不写:

env: - name: GPU_CORE_UTILIZATION_POLICY value: "force"

那么nvidia.com/gpucores: 30仍然会参与 HAMi 的调度计算。HAMi scheduler 仍然会认为这个 Pod 申请了 30% GPU core,并用这个值判断当前 GPU 是否还有足够的 core 配额。

但是容器真正运行 CUDA 程序时,是否强制把 GPU core utilization 限制在30%以下,就取决于 HAMi-core 的默认策略。

不加 GPU_CORE_UTILIZATION_POLICY=force 时, nvidia.com/gpucores 主要体现为调度层面的 core 配额申请。 HAMi scheduler 会用它判断资源够不够, 但容器运行阶段不一定适合用来强验证 core 限制效果。

12.2 加上 GPU_CORE_UTILIZATION_POLICY=force 时

如果写成:

env: - name: GPU_CORE_UTILIZATION_POLICY value: "force" resources: limits: nvidia.com/gpu: 1 nvidia.com/gpumem: 2000 nvidia.com/gpucores: 30

它的含义就是:

调度阶段: HAMi scheduler 按照 30% GPU core 计算这个 Pod 是否可以调度。 运行阶段: Pod 启动后,HAMi-core 也会根据 nvidia.com/gpucores 的值,对容器内 GPU core utilization 做限制。

HAMi 官方配置文档中对force的说明是:限制 core utilization 低于nvidia.com/gpucores

所以如果只是为了让 HAMi scheduler 做资源计算,写nvidia.com/gpucores就可以。

但如果是为了测试运行时 GPU core 限制效果,建议同时加上:

env: - name: GPU_CORE_UTILIZATION_POLICY value: "force"

这样测试目标更明确:

既验证调度层面的 GPU core 配额计算; 也验证容器运行时 HAMi-core 对 GPU core utilization 的限制。

12.3 default、force、disable 三种策略怎么理解

HAMi 官方配置中,GPU_CORE_UTILIZATION_POLICY有三个常见取值:

default 默认策略。 force 强制限制 core utilization,使其低于 nvidia.com/gpucores。 disable 任务执行期间忽略 nvidia.com/gpucores 设置的利用率限制。

可以这样理解:

策略调度阶段容器运行阶段
defaultnvidia.com/gpucores仍然参与调度计算使用 HAMi-core 默认策略
forcenvidia.com/gpucores参与调度计算HAMi-core 强制限制 core utilization
disablenvidia.com/gpucores仍然可能参与调度计算运行时忽略nvidia.com/gpucores的利用率限制

这里最容易混淆的是disable。如果写成:

env: - name: GPU_CORE_UTILIZATION_POLICY value: "disable"

它主要影响的是容器运行时阶段,意思是运行任务时忽略nvidia.com/gpucores设置的利用率限制。但是不要简单理解成:

disable 后调度阶段也完全不看 nvidia.com/gpucores。

调度阶段是否能放下这个 Pod,仍然取决于 HAMi scheduler 对 Pod 资源申请的计算。GPU_CORE_UTILIZATION_POLICY这个环境变量重点影响的是容器运行时 HAMi-core 的行为。


十三、测试 5:指定 GPU 型号

HAMi 支持通过 Pod annotation 指定要使用的 GPU 型号。官方配置文档中nvidia.com/use-gputype的含义是:如果设置了这个 annotation,那么 Pod 分配到的设备类型必须是这里指定的类型。先查看本机 GPU 型号:

nvidia-smi --query-gpu=name --format=csv,noheader

示例:

NVIDIA GeForce RTX 3070 Ti Laptop GPU

然后写 YAML:

apiVersion: v1 kind: Pod metadata: name: hami-use-gputype-3070 annotations: nvidia.com/use-gputype: "NVIDIA GeForce RTX 3070 Ti Laptop GPU" spec: restartPolicy: Never containers: - name: cuda image: nvidia/cuda:11.0.3-base-ubuntu18.04 command: ["bash", "-lc", "nvidia-smi && sleep 3600"] resources: limits: nvidia.com/gpu: 1 nvidia.com/gpumem: 2000 nvidia.com/gpucores: 30

查看:

kubectl get pod hami-use-gputype-3070 kubectl exec -it hami-use-gputype-3070 -- nvidia-smi

预期结果:

如果 annotation 里的 GPU 型号和 nvidia-smi 查出来的型号一致,Pod 可以 Running。

十四、测试 6:指定 GPU UUID

HAMi 也支持通过nvidia.com/use-gpuuuid指定 GPU UUID。官方配置文档中说明,如果设置了nvidia.com/use-gpuuuid,Pod 分配到的设备必须属于指定 UUID 列表。先查看 UUID:

nvidia-smi --query-gpu=index,name,uuid,memory.total --format=csv,noheader

示例:

0, NVIDIA GeForce RTX 3070 Ti Laptop GPU, GPU-998864a7-78d9-dbab-e122-4c37842ce7cf, 8192 MiB

把 UUID 写进 Pod annotation:

apiVersion: v1 kind: Pod metadata: name: hami-use-gpuuuid annotations: nvidia.com/use-gpuuuid: "GPU-998864a7-78d9-dbab-e122-4c37842ce7cf" spec: restartPolicy: Never containers: - name: cuda image: nvidia/cuda:11.0.3-base-ubuntu18.04 command: ["bash", "-lc", "nvidia-smi && sleep 3600"] resources: limits: nvidia.com/gpu: 1 nvidia.com/gpumem: 2000 nvidia.com/gpucores: 30

验证:

kubectl get pod hami-use-gpuuuid kubectl exec -it hami-use-gpuuuid -- nvidia-smi

在单卡环境里,指定正确 UUID 的意义主要是验证 annotation 是否生效。如果是多卡机器,这个功能更有用,可以指定任务只能跑到某一张或某几张 GPU 上。


十五、总结

这次在单节点 Kubernetes 环境中部署了 HAMi,并基于一张 8G NVIDIA GPU 做了几个基础测试。

整体来看,HAMi 的核心作用就是让 GPU 不再只能以整卡方式分配给一个 Pod,而是可以按显存、core、设备型号、设备 UUID 等维度进行更细粒度的调度和限制。

本次测试中需要重点记住几件事:

1. 部署 HAMi 前,宿主机必须先能正常执行 nvidia-smi。 2. 容器运行时必须配置 NVIDIA Container Toolkit。 3. HAMi 节点需要打 gpu=on 标签。 4. scheduler.kubeScheduler.imageTag 要和 Kubernetes Server 版本匹配。 5. 单卡环境下看到 nvidia.com/gpu: 10 是 HAMi 默认切分数量,不是 10 张物理卡。 6. nvidia.com/gpumem 可以按固定显存大小申请 GPU。 7. nvidia.com/gpumem-percentage 可以按百分比申请显存。 8. nvidia.com/gpumem 和 nvidia.com/gpumem-percentage 不要同时使用。 9. nvidia.com/gpucores 表示申请 GPU core 比例,不是 CUDA Core 数量。 10. GPU_CORE_UTILIZATION_POLICY=force 更适合用来测试 GPU core 运行时限制效果。 11. nvidia.com/use-gputype 和 nvidia.com/use-gpuuuid 可以用来做指定型号或指定卡调度。 12. 单个 Pod 写 nvidia.com/gpu: 2,不是从一张卡里拿 2 份 vGPU;在单卡环境里会无法调度。

对于单卡实验环境来说,HAMi 的价值很明显:一张 8G GPU 可以被多个测试 Pod 共享,不再因为一个小任务就独占整张卡。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/10 15:08:30

喜报!NetFarmer荣获2025年度HubSpot两项亚洲关键大奖

2026年1月,在HubSpot的年度合作伙伴评选中,铂金级合作伙伴NetFarmer(上海旺田信息技术有限公司)同时获得两项重要的亚洲地区奖项:• Upsell & Cross-sell 第一名• Growth Getter增长奖 第三名此次获奖不仅仅是数字…

作者头像 李华
网站建设 2026/6/10 15:07:41

云瀚智链国产化适配能力测评:融合会议、AI决策与资产加速

1. 产品定位与解决的问题▲产品架构图云瀚智链定位为数字化决策支撑平台,区别于传统会议软件仅解决“沟通”问题,它串联“数据采集 → 分析决策 → 协同沟通 → 决策下达 → 执行跟踪”全流程,将会议系统、数字资产、AI问答、工单告警整合成一…

作者头像 李华
网站建设 2026/6/10 15:05:02

微信旧版本下载 | 微信历史版本大全:微信4.1.10 for Windows 官方安装包

微信旧版本下载 | 微信历史版本大全:微信4.1.10 for Windows 官方安装包如果您正在苦苦寻找微信历史版本,尤其是稳定、干净的微信旧版本安装包,那么这篇文章正好能解决您的需求。今天我们为大家带来的是微信 4.1.10 for Windows 版本&#xf…

作者头像 李华
网站建设 2026/6/10 15:03:13

从‘虚短虚断’到动手搭建:我的第一个差分放大电路仿真与实测全记录(附Multisim文件)

从理论到实践:差分放大电路的设计、仿真与实测全流程解析 在电子工程的学习道路上,差分放大电路是一个绕不开的重要里程碑。作为模拟电路设计的核心模块之一,它不仅在仪器仪表、传感器接口和通信系统中扮演关键角色,更是理解现代集…

作者头像 李华