HAMI 是什么 HAMI 全称是 Heterogeneous AI Computing Virtualization Middleware,是一个面向 Kubernetes 的开源异构 AI 计算虚拟化中间件,前称是 k8s-vGPU-scheduler,是一个设计用于管理 k8s 集群中异构 AI 计算设备的“全合一”图表。它可以提供在任务之间共享异构 AI 设备的能力。截止文章发布时间,HAMi 是 CNCF Sandbox 和 CNAI Landscape 的项目。
核心能力
设备共享 HAMi 提供强大的设备共享功能,使多个任务可以共享同一个 GPU、MLU 或 NPU 设备,最大限度地利用异构 AI 计算资源。可以实现如下能力:
多任务共享: 同一设备可以由多个任务共享,每个任务仅使用部分设备。
设备内存控制: 可以按MB或百分比分配内存。
使用特定设备: 允许选择特定类型的异构 AI 设备或使用其 UUID 定位设备。
容器内硬限制: 对流式多处理器施加硬限制。
非侵入控制: 管理资源分配时无需对现有程序进行任何更改。
动态 MIG 支持: 支持使用 mig-parted 进行动态 MIG 调整。
设备资源隔离
可以实现将一款 GPU 设备隔离显存资源,参考例子:
1 2 3 4 resources: limits: nvidia.com/gpu: 1 nvidia.com/gpumem: 3000
结果如下,拥有 24G 显存的 4090 卡,显存限制在 3000 MiB。
HAMI 架构 参考下面的 HAMI 架构图,HAMI 主要组件如下:
HAMi MutatingWebhook:通过扫描每个提交的 pod 的资源字段,判断是否包含 HAMI 资源,存在则将调度器设置为 HAMi-scheduler。
HAMi scheduler-extender:负责将任务分配给适当的节点和设备。
HAMi-device-plugin:设备插件层从任务的注释字段获取调度结果,并将相应的设备映射到容器。
HAMi-Core:容器内资源控制负责监控容器内的资源使用情况,并提供硬隔离能力。
支持HAMi的设备 截止至 2025-06-26 支持的设备
生产商
制造商
类型
内存隔离
核心隔离
多卡支持
GPU
NVIDIA
全部
✅
✅
✅
MLU
Cambricon
370, 590
✅
✅
❌
DCU
Hygon
Z100, Z100L
✅
✅
❌
Ascend
Huawei
910B, 910B3, 310P
✅
✅
❌
GPU
iluvatar
全部
✅
✅
❌
GPU
Mthreads
MTT S4000
✅
✅
❌
DPU
Teco
检查中
进行中
进行中
❌
实验环境
Env
Version
Ubuntu
22.04.5
RKE2
v1.31.9+rke2r1
HAMI
v2.6.0
Driver
560.35.03
CUDA
12.6
GPU
NVIDIA GeForce RTX 4090
先决条件
安装过程 驱动安装 首先需要安装 NVIDIA 驱动和 CUDA。CUDA 是 NVIDIA 的并行计算平台,它通过利用 GPU 的强大计算能力来处理计算工作负载,从而显著提升性能。
NVIDIA 官方文档有关于不同操作系统的详细安装教程,我们可以参考 NVIDIA 驱动安装 和 CUDA 安装 文档进行安装即可。(这里由于我拿到机器的时候,驱动已经安装好了,所以驱动安装部分我没有验证过)
我另一篇文章在 RKE2 集群上运行 GPU 工作负载 ,里面有关于 GT710 显卡的简易安装教程,也可以试一下这个方法可不可行。
确认驱动是否安装成功,可以执行 nvidia-smi 命令进行查看:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 root@node2122:~ Thu Jun 26 01:26:08 2025 +-----------------------------------------------------------------------------------------+ | NVIDIA-SMI 560.35.03 Driver Version: 560.35.03 CUDA Version: 12.6 | |-----------------------------------------+------------------------+----------------------+ | GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. | | | | MIG M. | |=========================================+========================+======================| | 0 NVIDIA GeForce RTX 4090 On | 00000000:01:00.0 Off | Off | | 66% 30C P8 24W / 450W | 22781MiB / 24564MiB | 0% Default | | | | N/A | +-----------------------------------------+------------------------+----------------------+ | 1 NVIDIA GeForce RTX 4090 On | 00000000:23:00.0 Off | Off | | 65% 29C P8 25W / 450W | 22209MiB / 24564MiB | 0% Default | | | | N/A | +-----------------------------------------+------------------------+----------------------+ | 2 NVIDIA GeForce RTX 4090 On | 00000000:41:00.0 Off | Off | | 65% 32C P8 31W / 450W | 22209MiB / 24564MiB | 0% Default | | | | N/A | +-----------------------------------------+------------------------+----------------------+ | 3 NVIDIA GeForce RTX 4090 On | 00000000:61:00.0 Off | Off | | 68% 30C P8 15W / 450W | 22209MiB / 24564MiB | 0% Default | | | | N/A | +-----------------------------------------+------------------------+----------------------+ | 4 NVIDIA GeForce RTX 4090 On | 00000000:81:00.0 Off | Off | | 30% 30C P8 17W / 450W | 6203MiB / 24564MiB | 0% Default | | | | N/A | +-----------------------------------------+------------------------+----------------------+ | 5 NVIDIA GeForce RTX 4090 On | 00000000:A1:00.0 Off | Off | | 30% 31C P8 24W / 450W | 1861MiB / 24564MiB | 0% Default | | | | N/A | +-----------------------------------------+------------------------+----------------------+ | 6 NVIDIA GeForce RTX 4090 On | 00000000:C1:00.0 Off | Off | | 67% 29C P8 25W / 450W | 22455MiB / 24564MiB | 0% Default | | | | N/A | +-----------------------------------------+------------------------+----------------------+ | 7 NVIDIA GeForce RTX 4090 On | 00000000:E1:00.0 Off | Off | | 64% 29C P8 25W / 450W | 22191MiB / 24564MiB | 0% Default | | | | N/A | +-----------------------------------------+------------------------+----------------------+ +-----------------------------------------------------------------------------------------+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=========================================================================================| | 1 N/A N/A 320266 C Xinf vLLM worker: 1 22192MiB | | 2 N/A N/A 320268 C Xinf vLLM worker: 2 22192MiB | | 3 N/A N/A 320267 C Xinf vLLM worker: 3 22192MiB | | 4 N/A N/A 330370 C python 6194MiB | | 5 N/A N/A 237239 C python 1852MiB | | 6 N/A N/A 321302 C python 22446MiB | | 7 N/A N/A 241782 C ...ntu/miniconda3/envs/xrlf/bin/python 22182MiB | +-----------------------------------------------------------------------------------------+
nvidia-container-toolkit 是 NVIDIA 提供的一组工具,可帮助用户构建和运行 GPU 加速的容器。也就是可以让我们在容器化环境(Docker/Containerd)中使用 GPU。
其他操作系统可以参考官方安装文档 。我的实验环境是 Ubuntu 22.04,安装 nvidia-container-toolkit 参考如下:
1 2 3 4 curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg && curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list sed -i -e '/experimental/ s/^#//g' /etc/apt/sources.list.d/nvidia-container-toolkit.list apt-get update apt-get install -y nvidia-container-toolkit
使用 nvidia-ctk
配置 Docker 默认运行时:
1 nvidia-ctk runtime configure --runtime=docker
查看 daemon.json
配置是否生效:
1 2 3 4 5 6 7 8 9 cat /etc/docker/daemon.json { "runtimes" : { "nvidia" : { "args" : [], "path" : "nvidia-container-runtime" } } }
重启 Docker
1 systemctl restart docker
验证是否可以使用 Docker
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 root@node2122:~ ========== == CUDA == ========== CUDA Version 11.4.3 Container image Copyright (c) 2016-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. This container image and its contents are governed by the NVIDIA Deep Learning Container License. By pulling and using the container, you accept the terms and conditions of this license: https://developer.nvidia.com/ngc/nvidia-deep-learning-container-license A copy of this license is made available in this container at /NGC-DL-CONTAINER-LICENSE for your convenience. Wed Jun 25 17:25:14 2025 +-----------------------------------------------------------------------------------------+ | NVIDIA-SMI 560.35.03 Driver Version: 560.35.03 CUDA Version: 12.6 | |-----------------------------------------+------------------------+----------------------+ | GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. | | | | MIG M. | |=========================================+========================+======================| | 0 NVIDIA GeForce RTX 4090 On | 00000000:01:00.0 Off | Off | | 66% 29C P8 24W / 450W | 22781MiB / 24564MiB | 0% Default | | | | N/A | +-----------------------------------------+------------------------+----------------------+ | 1 NVIDIA GeForce RTX 4090 On | 00000000:23:00.0 Off | Off | | 65% 29C P8 24W / 450W | 22209MiB / 24564MiB | 0% Default | | | | N/A | +-----------------------------------------+------------------------+----------------------+ | 2 NVIDIA GeForce RTX 4090 On | 00000000:41:00.0 Off | Off | | 66% 32C P8 31W / 450W | 22209MiB / 24564MiB | 0% Default | | | | N/A | +-----------------------------------------+------------------------+----------------------+ | 3 NVIDIA GeForce RTX 4090 On | 00000000:61:00.0 Off | Off | | 68% 30C P8 16W / 450W | 22209MiB / 24564MiB | 0% Default | | | | N/A | +-----------------------------------------+------------------------+----------------------+ | 4 NVIDIA GeForce RTX 4090 On | 00000000:81:00.0 Off | Off | | 30% 29C P8 17W / 450W | 6203MiB / 24564MiB | 0% Default | | | | N/A | +-----------------------------------------+------------------------+----------------------+ | 5 NVIDIA GeForce RTX 4090 On | 00000000:A1:00.0 Off | Off | | 30% 31C P8 24W / 450W | 1861MiB / 24564MiB | 0% Default | | | | N/A | +-----------------------------------------+------------------------+----------------------+ | 6 NVIDIA GeForce RTX 4090 On | 00000000:C1:00.0 Off | Off | |100% 29C P8 25W / 450W | 22455MiB / 24564MiB | 0% Default | | | | N/A | +-----------------------------------------+------------------------+----------------------+ | 7 NVIDIA GeForce RTX 4090 On | 00000000:E1:00.0 Off | Off | | 64% 29C P8 25W / 450W | 22191MiB / 24564MiB | 0% Default | | | | N/A | +-----------------------------------------+------------------------+----------------------+ +-----------------------------------------------------------------------------------------+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=========================================================================================| | No running processes found | +-----------------------------------------------------------------------------------------+
containerd 也可以通过 nvidia-ctk
去配置,关键参数如下,具体就不演示了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 version = 2 [plugins] [plugins."io.containerd.grpc.v1.cri" ] [plugins."io.containerd.grpc.v1.cri" .containerd] default_runtime_name = "nvidia" [plugins."io.containerd.grpc.v1.cri" .containerd.runtimes] [plugins."io.containerd.grpc.v1.cri" .containerd.runtimes.nvidia] privileged_without_host_devices = false runtime_engine = "" runtime_root = "" runtime_type = "io.containerd.runc.v2" [plugins."io.containerd.grpc.v1.cri" .containerd.runtimes.nvidia.options] BinaryName = "/usr/bin/nvidia-container-runtime"
安装 RKE2 集群 HAMI 毕竟是一个设计用于管理 k8s 集群中异构AI计算设备的平台,所以我们需要有一个 k8s 集群来承载 HAMI,这里我们选择可以快速部署安装的 RKE2 集群。
基于脚本下载二进制文件:
1 curl -sfL https://get.rke2.io | INSTALL_RKE2_VERSION=v1.31.9+rke2r1 sh -
这里踩了一个坑,在 v1.30.4+rke2r1 这个版本上,貌似触发了个 bug,containerd 配置无法生效。所以使用了 v1.31.9+rke2r1 这个版本。
(可选)如果服务器在国内且没有翻墙代理,或者使用本地 Harbor 镜像仓库,可以手动配置镜像仓库源:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 mirrors: docker.io: endpoint: - "https://docker.m.daocloud.io" quay.io: endpoint: - "https://swr.cn-north-4.myhuaweicloud.com" rewrite: "(^.+$)" : "ddn-k8s/quay.io/$1 " registry.k8s.io: endpoint: - "https://swr.cn-north-4.myhuaweicloud.com" rewrite: "(^.+$)" : "ddn-k8s/registry.k8s.io/$1 "
启动 rke2-server:
1 2 3 systemctl enable rke2-server.service systemctl start rke2-server.service
等待命令集群部署好后,我们执行 kubectl 命令查看集群是否起来了。
1 2 3 NAME STATUS ROLES AGE VERSION node2122 Ready control-plane,etcd,master 7h38m v1.31.9+rke2r1
设置 NVIDIA 为默认运行时:
1 2 3 4 5 6 cat <<EOF > /var/lib/rancher/rke2/agent/etc/containerd/config.toml.tmpl {{ template "base" . }} [plugins."io.containerd.cri.v1.runtime".containerd] default_runtime_name = "nvidia" EOF
重启 rke2-server:
1 systemctl restart rke2-server.service
为 node 设置 标签:
1 kubectl label node node2122 gpu=on
安装 HAMI 接着我们开始安装 HAMI。
首先添加 HAMI 仓库:
1 2 3 helm repo add hami-charts https://project-hami.github.io/HAMi/ helm repo update
接着我们需要获取当前集群的 k8s 版本,这里我们安装的版本是 v1.31.9
。
在线安装方式:
1 helm install hami hami-charts/hami -n hami --create-namespace --set scheduler.kubeScheduler.imageTag=v1.31.9
离线安装方式:如果镜像在本地Harbor,可以设置镜像地址:
1 2 3 4 5 6 7 8 9 IMG_REG=<Harbor_URL> helm install hami hami-charts/hami -n hami --create-namespace \ --set scheduler.kubeScheduler.imageTag=v1.30.4 \ --set scheduler.extender.image=$IMG_REG /projecthami/hami \ --set devicePlugin.image=$IMG_REG /projecthami/hami \ --set devicePlugin.monitorimage=$IMG_REG /projecthami/hami \ --set scheduler.image=$IMG_REG /projecthami/hami \ --set scheduler.patch.image=$IMG_REG /jettech/kube-webhook-certgen:v1.5.2 \ --set scheduler.patch.imageNew=$IMG_REG /liangjw/kube-webhook-certgen:v1.1.1
确认组件是否正常运行:
1 2 3 4 NAME READY STATUS RESTARTS AGE hami-device-plugin-9kbz8 2/2 Running 0 7h41m hami-scheduler-8444dcb567-sfw7c 2/2 Running 0 7h42m
这里 scheduler 一般不会有问题,可能会出问题的是 device-plugin ,如果这个起不来,可以查看日志看看是什么报错,一般可能是没有配置 NVIDIA 为默认运行时。如果直接看不到 device-plugin ,请确认节点是否有配置gpu=on
标签。
启动 GPU pod 使用下面这段配置创建一个测试工作负载。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 apiVersion: apps/v1 kind: Deployment metadata: labels: app: gpu-test name: gpu-test namespace: default spec: replicas: 1 selector: matchLabels: app: gpu-test strategy: type: Recreate template: metadata: labels: app: gpu-test namespace: default spec: containers: - image: nvidia/cuda:11.4.3-runtime-ubuntu20.04 imagePullPolicy: IfNotPresent name: gpu-test resources: limits: nvidia.com/gpu: '1' nvidia.com/gpumem: 10240 stdin: true tty: true runtimeClassName: nvidia
关键参数如下:
1 2 3 4 resources: limits: nvidia.com/gpu: 1 nvidia.com/gpumem: 10240
启动 deployment:
1 kubectl create -f gpu-test.yaml
确认 pod 是否正常运行:
1 2 3 NAME READY STATUS RESTARTS AGE gpu-test-758f7877c5-5drv2 1/1 Running 0 4s
验证 pod 是否按照 limit 的大小进行分配:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 Wed Jun 25 18:02:12 2025 +-----------------------------------------------------------------------------------------+ | NVIDIA-SMI 560.35.03 Driver Version: 560.35.03 CUDA Version: 12.6 | |-----------------------------------------+------------------------+----------------------+ | GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. | | | | MIG M. | |=========================================+========================+======================| | 0 NVIDIA GeForce RTX 4090 On | 00000000:23:00.0 Off | Off | | 65% 29C P8 25W / 450W | 0MiB / 10240MiB | 0% Default | | | | N/A | +-----------------------------------------+------------------------+----------------------+ +-----------------------------------------------------------------------------------------+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=========================================================================================| | No running processes found | +-----------------------------------------------------------------------------------------+
可以看到,已经正常分配 10240 MiB 显存。
WebUI 安装 HAMI 也提供一个可视化的 WebUI 界面,我们可以通过 Helm 进行安装。
安装 Prometheus 首先需要先安装 Prometheus,我们可以直接安装社区的 kube-prometheus-stack,里面包含了 prometheus+grafana+alertmanager。
通过 Helm 进行安装:
1 2 3 helm repo add prometheus-community https://prometheus-community.github.io/helm-charts helm repo update helm install prometheus -n prometheus --create-namespace prometheus-community/kube-prometheus-stack
查看是否安装成功:
1 2 3 4 5 6 7 8 NAME READY STATUS RESTARTS AGE alertmanager-prometheus-kube-prometheus-alertmanager-0 2/2 Running 0 19m prometheus-grafana-788974cbb5-s742s 3/3 Running 0 19m prometheus-kube-prometheus-operator-5f4c64f45d-cqv79 1/1 Running 0 19m prometheus-kube-state-metrics-54f9649f7c-8nfc2 1/1 Running 0 19m prometheus-prometheus-kube-prometheus-prometheus-0 2/2 Running 0 19m prometheus-prometheus-node-exporter-8grzd 1/1 Running 0 19m
创建 NodePort 访问 Grafana 和 Prometheus,参考如下:
Grafana-NodePort:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 apiVersion: v1 kind: Service metadata: name: prometheus-grafana-nodeport namespace: prometheus spec: ports: - name: http-web port: 80 protocol: TCP targetPort: 3000 selector: app.kubernetes.io/instance: prometheus app.kubernetes.io/name: grafana type : NodePort
访问 <Node_IP>:<NodePort>
,账号密码默认是admin/prom-operator
Prometheus-NodePort:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 apiVersion: v1 kind: Service metadata: name: prometheus-nodeport namespace: prometheus spec: ports: - name: http-web port: 9090 protocol: TCP targetPort: 9090 - appProtocol: http name: reloader-web port: 8080 protocol: TCP targetPort: reloader-web selector: app.kubernetes.io/name: prometheus operator.prometheus.io/name: prometheus-kube-prometheus-prometheus type: NodePort
安装 HAMI WebUI 我们通过 Helm 进行安装,首先添加仓库:
1 helm repo add hami-webui https://project-hami.github.io/HAMi-WebUI
这里我们对接刚刚的 Prometheus,我们查询一下 Prometheus 的 Service,我们需要使用这个 Service 进行对接。
1 2 3 4 5 6 kubectl -n prometheus get svc ... ... prometheus-kube-prometheus-prometheus ClusterIP 10.43.153.38 <none> 9090/TCP,8080/TCP 17m ... ...
接着开始安装:
1 helm install hami-webui -n hami hami-webui/hami-webui --create-namespace --set externalPrometheus.enabled=true --set externalPrometheus.address="http://prometheus-kube-prometheus-prometheus.prometheus.svc.cluster.local:9090" --set service.type=NodePort
确认 pod 状态都正常:
1 2 3 hami-webui-5c58b5cff-q8r6t 2/2 Running 0 2m1s hami-webui-dcgm-exporter-smjrn 1/1 Running 0 2m1s
这里我们已经设置了 NodePort 暴露出去,所以我们直接访问 NodePort 就可以看到了 WebUI 了。
1 2 3 4 5 6 ... ... hami-webui NodePort 10.43.171.70 <none> 3000:30686/TCP,8000:31641/TCP 4m20s ... ...
访问 3000 端口对应的 NodePort,效果如下:
通过这个 UI,我们可以看到显卡分配情况:
在任务管理可以看到具体已运行的任务:
常用示例 独占 GPU 1 2 3 resources: limits: nvidia.com/gpu: 2
为容器分配特定设备内存 1 2 3 4 resources: limits: nvidia.com/gpu: 2 nvidia.com/gpumem: 3000
按百分比分配设备内存给容器 1 2 3 4 resources: limits: nvidia.com/gpu: 2 nvidia.com/gpumem-percentage: 50
为容器分配设备核心资源 1 2 3 4 resources: limits: nvidia.com/gpu: 2 nvidia.com/gpucores: 50
分配任务到特定类型 1 2 3 4 5 6 7 8 9 10 11 12 metadata: annotations: nvidia.com/use-gputype: "A100,V100" ... ... spec: ... ... resources: limits: nvidia.com/gpu: 2
将任务分配给特定的 GPU 1 2 3 4 5 6 7 8 9 10 11 metadata: annotations: nvidia.com/use-gpuuuid: "GPU-123456" ... ... spec: ... ... resources: limits: nvidia.com/gpu: 2
将任务分配给 mig 实例 此示例将为 A100-40GB-PCIE 设备分配 2g.10gb * 2 或为 A100-80GB-XSM 设备分配 1g.10gb * 2。
1 2 3 4 5 6 7 8 9 10 11 12 13 metadata: annotations: nvidia.com/vgpu-mode: "mig" hami.io/gpu-scheduler-policy: "binpack" ... ... spec: ... ... resources: limits: nvidia.com/gpu: 2 nvidia.com/gpumem: 8000