Skip to content

HAMi vGPU 完整部署指南 (V100 版本)

本文档包含 HAMi vGPU 的完整部署流程、国内镜像源配置、Helm Chart 参数说明及运维指南。

目录

  1. 概述
  2. 环境要求
  3. 国内镜像源配置
  4. Helm Chart 部署
  5. 配置详解
  6. vGPU 切分策略
  7. 使用示例
  8. 运维指南
  9. 故障排查

概述

HAMi 是什么?

HAMi (Heterogeneous AI Computing Virtualization) 是一个开源的 Kubernetes GPU 虚拟化方案,支持:

  • 软件 vGPU:通过 CUDA Hook 实现显存/算力隔离,无需 MIG 硬件支持
  • 多厂商 GPU:NVIDIA、AMD、华为昇腾、寒武纪、海光等
  • 细粒度资源分配:按 MB 分配显存,按百分比分配算力
  • 多集群管理:支持 Kubernetes 多集群统一管理

核心架构

┌─────────────────────────────────────────────────────────────┐
│                      用户 Pod 请求 GPU                       │
└───────────────────────┬─────────────────────────────────────┘


┌──────────────┐     ┌───────────────────┐     ┌──────────────────┐
│hami-scheduler│────▶│hami-device-plugin │────▶│  libvgpu.so     │
│  (调度决策)   │     │ (设备注册+分配)    │     │  (运行时限制)    │
└──────────────┘     └───────────────────┘     └──────────────────┘
       │                                              │
       ▼                                              ▼
  评估节点资源                                  CUDA API Hook
  选择最优 GPU                                 显存/算力限制

版本信息

组件版本说明
HAMiv2.10.0当前部署版本
Helm Charthami-2.10.0Chart 版本
Kubernetesv1.19+最低要求
NVIDIA Driver570.153.02推荐版本
CUDA12.8支持版本

环境要求

硬件要求

组件最低要求推荐配置
CPU2 cores4+ cores
内存4 GB8+ GB
磁盘20 GB50+ GB
GPU1x NVIDIA GPU支持 CUDA

软件要求

操作系统

  • Ubuntu 20.04 / 22.04 / 24.04
  • CentOS 7 / 8 / Stream 8/9
  • RHEL 8 / 9
  • Debian 11 / 12

Kubernetes

  • 版本:v1.19.x - v1.33.x
  • CNI:Calico / Flannel / Cilium
  • 运行时:containerd / Docker

NVIDIA 环境

  • NVIDIA 驱动:>= 470.x(推荐 535+ 或 570+)
  • CUDA Toolkit:>= 11.0
  • NVIDIA Container Toolkit:已安装
  • nvidia-smi 可用

验证环境

bash
# 检查 Kubernetes
kubectl version --short

# 检查节点
kubectl get nodes

# 检查 NVIDIA 驱动
nvidia-smi

# 检查 GPU 设备
ls /dev/nvidia*

# 检查 containerd
ctr --version

国内镜像源配置

方案一:华为云 SWR(推荐)

华为云容器镜像服务,国内访问速度快:

bash
# 拉取 HAMi 镜像
docker pull swr.cn-east-2.myhuaweicloud.com/kuboard/hami:v2.10.0

# 推送到本地仓库(如果有)
docker tag swr.cn-east-2.myhuaweicloud.com/kuboard/hami:v2.10.0 \
  your-registry.local/hami:v2.10.0
docker push your-registry.local/hami:v2.10.0

方案二:阿里云 ACR

bash
# 拉取镜像
docker pull registry.cn-hangzhou.aliyuncs.com/hami/hami:v2.10.0

# 重新打标签
docker tag registry.cn-hangzhou.aliyuncs.com/hami/hami:v2.10.0 \
  projecthami/hami:v2.10.0

方案三:DaoCloud 镜像加速

配置 containerd 使用 DaoCloud 镜像加速器:

bash
# 编辑 containerd 配置
sudo vim /etc/containerd/config.toml

# 添加以下内容
[plugins."io.containerd.grpc.v1.cri".registry.mirrors]
  [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
    endpoint = ["https://docker.m.daocloud.io"]
  [plugins."io.containerd.grpc.v1.cri".registry.mirrors."ghcr.io"]
    endpoint = ["https://ghcr.m.daocloud.io"]

# 重启 containerd
sudo systemctl restart containerd

方案四:自建 Harbor 仓库

bash
# 1. 安装 Harbor(参考官方文档)
# https://goharbor.io/docs/latest/install-config/

# 2. 创建 hami 项目
# 在 Harbor UI 中创建名为 "hami" 的公开项目

# 3. 拉取并推送镜像
docker pull swr.cn-east-2.myhuaweicloud.com/kuboard/hami:v2.10.0
docker tag swr.cn-east-2.myhuaweicloud.com/kuboard/hami:v2.10.0 \
  harbor.your-domain.com/hami/hami:v2.10.0
docker push harbor.your-domain.com/hami/hami:v2.10.0

# 4. 配置 Kubernetes 使用私有仓库
kubectl create secret docker-registry harbor-secret \
  --docker-server=harbor.your-domain.com \
---

## Helm Chart 部署

### 添加 Helm 仓库

```bash
# 添加 HAMi 官方仓库
helm repo add hami https://project-hami.github.io/HAMi/

# 更新仓库
helm repo update

# 查看可用版本
helm search repo hami

注意:如果官方仓库无法访问,可以使用国内镜像:

bash
# 使用 GitHub Release 直接下载
wget https://github.com/Project-HAMi/HAMi/releases/download/v2.10.0/hami-2.10.0.tgz

# 或使用代理
helm repo add hami https://ghproxy.com/https://raw.githubusercontent.com/Project-HAMi/HAMi/main/charts

安装 HAMi

基础安装

bash
# 创建命名空间
kubectl create namespace hami-system

# 安装 HAMi(使用默认配置)
helm install hami hami/hami \
  --namespace hami-system \
  --version 2.10.0

自定义安装(推荐)

创建 values.yaml

yaml
# values.yaml - HAMi 部署配置

# 镜像配置
scheduler:
  image: swr.cn-east-2.myhuaweicloud.com/kuboard/hami:v2.10.0
  pullPolicy: IfNotPresent
  replicas: 1
  resources:
    requests:
      cpu: 100m
      memory: 128Mi
    limits:
      cpu: 500m
      memory: 512Mi

devicePlugin:
  image: swr.cn-east-2.myhuaweicloud.com/kuboard/hami:v2.10.0
  pullPolicy: IfNotPresent
  # 只在有 GPU 的节点上运行
  nodeSelector:
    gpu: "on"
  resources:
    requests:
      cpu: 50m
      memory: 64Mi
    limits:
      cpu: 200m
      memory: 256Mi

# 设备配置
deviceConfig:
  nvidia:
    resourceCountName: nvidia.com/gpu
    resourceMemoryName: nvidia.com/gpumem
    resourceMemoryPercentageName: nvidia.com/gpumem-percentage
    resourceCoreName: nvidia.com/gpucores
    resourcePriorityName: nvidia.com/priority
    deviceSplitCount: 2
    deviceMemoryScaling: 1
    deviceCoreScaling: 1
    defaultMemory: 0
    defaultCores: 0
    defaultGPUNum: 1
    runtimeClassName: "nvidia"
    migProfileAllowlist: []

# 调度器配置
schedulerConfig:
  schedulerName: hami-scheduler
  leaderElection: true
  policy: binpack  # binpack(紧凑)或 spread(分散)

# 监控配置
monitoring:
  enabled: false
  serviceMonitor:
    enabled: false
    interval: 30s

# 节点配置(可选,覆盖全局配置)
nodeConfigs: []

# 容忍度
tolerations:
  - key: "node-role.kubernetes.io/master"
    operator: "Exists"
    effect: "NoSchedule"
  - key: "node-role.kubernetes.io/control-plane"
    operator: "Exists"
    effect: "NoSchedule"

安装:

bash
# 使用自定义 values.yaml 安装
helm install hami hami/hami \
  --namespace hami-system \
  --version 2.10.0 \
  -f values.yaml

# 或使用 --set 覆盖单个参数
helm install hami hami/hami \
  --namespace hami-system \
  --version 2.10.0 \
  --set scheduler.image=your-registry/hami:v2.10.0 \
  --set devicePlugin.image=your-registry/hami:v2.10.0

验证安装

bash
# 检查 Pod 状态
kubectl get pods -n hami-system

# 预期输出:
# NAME                              READY   STATUS    RESTARTS   AGE
# hami-device-plugin-xxxxx          2/2     Running   0          1m
# hami-scheduler-xxxxx              2/2     Running   0          1m

# 检查节点 GPU 资源
kubectl get nodes -o custom-columns="NAME:.metadata.name,GPU:.status.allocatable.nvidia\.com/gpu,MEM:.status.allocatable.nvidia\.com/gpumem"

# 检查设备注册
kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{.metadata.annotations.hami\.io/node-nvidia-register}{"\n\n"}{end}'

# 检查 HAMi ConfigMap
kubectl get cm hami-device-plugin -n hami-system -o yaml
kubectl get cm hami-scheduler-device -n hami-system -o yaml

--docker-username=xxx
--docker-password=xxx
-n hami-system


### K3s 镜像仓库配置

如果使用 K3s,编辑 `/etc/rancher/k3s/registries.yaml`:

```yaml
mirrors:
  docker.io:
    endpoint:
      - "https://docker.m.daocloud.io"
      - "https://registry.cn-hangzhou.aliyuncs.com"
  ghcr.io:
    endpoint:
      - "https://ghcr.m.daocloud.io"
  gcr.io:
    endpoint:
      - "https://registry.cn-hangzhou.aliyuncs.com"
  quay.io:
    endpoint:
      - "https://quay.m.daocloud.io"

重启 K3s 生效:

bash
sudo systemctl restart k3s
# 或
sudo systemctl restart k3s-agent
---

## 配置详解

### 核心 ConfigMap

HAMi 使用 3 个核心 ConfigMap 管理配置:

#### 1. hami-device-plugin

节点级别的设备配置:

```yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: hami-device-plugin
  namespace: hami-system
data:
  config.json: |
    {
      "nodeconfig": [
        {
          "name": "node-1",
          "operatingmode": "hami-core",
          "devicesplitcount": 4,
          "devicememoryscaling": 1,
          "preconfigureddevicememory": 0,
          "enablenumatopology": false,
          "migstrategy": "none",
          "filterdevices": {
            "uuid": [],
            "index": []
          },
          "enablegetpreferredallocation": false
        }
      ]
    }

参数说明

参数类型默认值说明
namestring-节点名称
operatingmodestringhami-core运行模式:hami-core(软件)或 mig(硬件)
devicesplitcountint2每卡切分份数
devicememoryscalingfloat1.0显存缩放因子
preconfigureddevicememoryint0预配置显存(MB),0 表示按 splitcount 均分
enablenumatopologyboolfalse启用 NUMA 拓扑感知
migstrategystringnoneMIG 策略:none / single / mixed
filterdevices.uuidlist[]过滤的 GPU UUID 列表
filterdevices.indexlist[]过滤的 GPU 索引列表

2. hami-scheduler-device

全局设备规格定义:

yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: hami-scheduler-device
  namespace: hami-system
data:
  device-config.yaml: |-
    nvidia:
      resourceCountName: nvidia.com/gpu
      resourceMemoryName: nvidia.com/gpumem
      resourceMemoryPercentageName: nvidia.com/gpumem-percentage
      resourceCoreName: nvidia.com/gpucores
      resourcePriorityName: nvidia.com/priority
      deviceSplitCount: 4
      deviceMemoryScaling: 1
      deviceCoreScaling: 1
      defaultMemory: 0
      defaultCores: 0
      defaultGPUNum: 1
      runtimeClassName: "nvidia"
      libCudaLogLevel: 1
      gpuCorePolicy: default
      overwriteEnv: false

资源名称映射

资源Kubernetes 资源名说明
GPU 数量nvidia.com/gpuvGPU 数量
显存(绝对值)nvidia.com/gpumem单位 MB
显存(百分比)nvidia.com/gpumem-percentage0-100
算力核心nvidia.com/gpucores0-100(百分比)
优先级nvidia.com/priority调度优先级

3. hami-scheduler

调度器配置:

yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: hami-scheduler
  namespace: hami-system
data:
  config.yaml: |
    apiVersion: kubescheduler.config.k8s.io/v1
    kind: KubeSchedulerConfiguration
    leaderElection:
      leaderElect: true
      resourceName: "hami-scheduler"
      resourceNamespace: "hami-system"
    profiles:
    - schedulerName: hami-scheduler
    extenders:
    - urlPrefix: "https://127.0.0.1:443"
      enableHTTPS: true
      tlsConfig:
        insecure: true
      filterVerb: filter
      bindVerb: bind
      nodeCacheCapable: true
      weight: 1
      httpTimeout: 30s
      managedResources:
      - ignoredByScheduler: true
        name: nvidia.com/gpu
      - ignoredByScheduler: true
        name: nvidia.com/gpumem
      - ignoredByScheduler: true
        name: nvidia.com/gpucores
      - ignoredByScheduler: true
        name: nvidia.com/gpumem-percentage

libvgpu.so 工作原理

HAMi 的核心黑科技是 libvgpu.so,通过 CUDA Hook 实现资源隔离:

容器启动

device-plugin Allocate

注入环境变量:
  - CUDA_DEVICE_MEMORY_LIMIT_0=4000m
  - CUDA_DEVICE_SM_LIMIT=0
  - NVIDIA_VISIBLE_DEVICES=GPU-xxx

挂载文件:
  - /usr/local/vgpu/libvgpu.so
  - /etc/ld.so.preload

LD_PRELOAD 生效

拦截 CUDA API:
  - cudaMalloc() → 检查显存限制
  - cudaMemcpy() → 检查带宽限制
  - cudaLaunchKernel() → 检查算力限制

运行时资源隔离

vGPU 切分策略

不同显卡的推荐切分方案

GPU 型号显存推荐切分数每份显存适用场景
RTX 20808 GB24 GB推理、小模型
RTX 3080 Ti12 GB26 GB推理、中等模型
RTX 309024 GB46 GB训练、大模型
RTX 409024 GB46 GB训练、大模型
A100 40GB40 GB4-75-10 GB企业级训练
A100 80GB80 GB4-710-20 GB大模型训练
H10080 GB4-710-20 GB超大模型

按场景配置

场景一:推理服务(高并发)

yaml
# values.yaml
deviceConfig:
  nvidia:
    deviceSplitCount: 4        # 高切分,支持更多并发
    deviceMemoryScaling: 1
yaml
# Pod 请求
resources:
  limits:
    nvidia.com/gpu: 1
    nvidia.com/gpumem: 2000    # 2GB 足够推理
    nvidia.com/gpucores: 25    # 25% 算力

场景二:模型训练(独占资源)

yaml
# values.yaml
deviceConfig:
  nvidia:
    deviceSplitCount: 1        # 不切分,独占
    deviceMemoryScaling: 1
yaml
# Pod 请求
resources:
  limits:
    nvidia.com/gpu: 1          # 独占整卡

场景三:混合负载

yaml
# 节点级配置
nodeConfigs:
  - name: inference-node
    devicesplitcount: 4        # 推理节点高切分
  - name: training-node
    devicesplitcount: 1        # 训练节点独占

更新配置

bash
# 编辑 ConfigMap
kubectl edit cm hami-device-plugin -n hami-system

# 重启 device-plugin 使配置生效
kubectl rollout restart ds/hami-device-plugin -n hami-system

# 验证
kubectl get pods -n hami-system

使用示例

示例一:vLLM 推理服务

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: vllm-qwen3-06b
spec:
  replicas: 1
  selector:
    matchLabels:
      app: vllm-qwen3-06b
  template:
    metadata:
      labels:
        app: vllm-qwen3-06b
    spec:
      containers:
      - name: vllm
        image: vllm/vllm-openai:latest
        args:
        - --model
        - /models/Qwen/Qwen3-0.6B
        - --max-model-len
        - "2048"
        ports:
        - containerPort: 8000
        resources:
          limits:
            nvidia.com/gpu: 1
            nvidia.com/gpumem: 6000      # 6GB 显存
            nvidia.com/gpucores: 50      # 50% 算力
        volumeMounts:
        - name: models
          mountPath: /models
      volumes:
      - name: models
        nfs:
          server: 192.168.1.100
          path: /models
---
apiVersion: v1
kind: Service
metadata:
  name: vllm-qwen3-06b
spec:
  selector:
    app: vllm-qwen3-06b
  ports:
  - port: 8001
    targetPort: 8000
  type: ClusterIP

示例二:Jupyter Notebook(交互式开发)

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: jupyter-gpu
spec:
  replicas: 1
  selector:
    matchLabels:
      app: jupyter-gpu
  template:
    metadata:
      labels:
        app: jupyter-gpu
    spec:
      containers:
      - name: jupyter
        image: jupyter/tensorflow-notebook:latest
        ports:
        - containerPort: 8888
        resources:
          limits:
            nvidia.com/gpu: 1
            nvidia.com/gpumem: 4000      # 4GB 显存
        env:
        - name: JUPYTER_TOKEN
          value: "your-password"
---
apiVersion: v1
kind: Service
metadata:
  name: jupyter-gpu
spec:
  selector:
    app: jupyter-gpu
  ports:
  - port: 8888
    targetPort: 8888
    nodePort: 30888
  type: NodePort

示例三:多 GPU 训练任务

yaml
apiVersion: v1
kind: Pod
metadata:
  name: pytorch-training
spec:
  containers:
  - name: trainer
    image: pytorch/pytorch:latest
    command: ["python", "-m", "torch.distributed.launch", "train.py"]
    resources:
      limits:
        nvidia.com/gpu: 4              # 4 张 GPU
        nvidia.com/gpumem: 24000       # 每张 24GB(RTX 3090 独占)
    env:
    - name: MASTER_ADDR
      value: "localhost"
    - name: MASTER_PORT
      value: "12355"
    - name: WORLD_SIZE
      value: "4"

运维指南

监控 HAMi 状态

bash
# 检查所有组件
kubectl get all -n hami-system

# 检查节点 GPU 注册状态
kubectl get nodes -o json | jq -r '.items[] | select(.metadata.annotations["hami.io/node-nvidia-register"]) | .metadata.name + ": " + .metadata.annotations["hami.io/node-nvidia-register"]'

# 检查设备分配
kubectl get nodes -o custom-columns="NAME:.metadata.name,GPU:.status.allocatable.nvidia\.com/gpu,MEM:.status.allocatable.nvidia\.com/gpumem,CORES:.status.allocatable.nvidia\.com/gpucores"

# 查看 Pod GPU 使用
kubectl top pods --containers | grep -E "GPU|nvidia"

日志查看

bash
# Scheduler 日志
kubectl logs -n hami-system deploy/hami-scheduler -c scheduler

# Device Plugin 日志
kubectl logs -n hami-system ds/hami-device-plugin -c device-plugin

# 查看特定节点日志
NODE=$(kubectl get pods -n hami-system -o wide | grep device-plugin | awk '{print $7}' | head -1)
kubectl logs -n hami-system $(kubectl get pods -n hami-system -o wide | grep $NODE | awk '{print $1}') -c device-plugin

升级 HAMi

bash
# 查看当前版本
helm list -n hami-system

# 升级到新版本
helm upgrade hami hami/hami \
  --namespace hami-system \
  --version 2.11.0 \
  -f values.yaml

# 回滚到上一版本
helm rollback hami -n hami-system

# 查看历史版本
helm history hami -n hami-system

卸载 HAMi

bash
# 卸载 Helm release
helm uninstall hami -n hami-system

# 删除命名空间(可选)
kubectl delete namespace hami-system

# 清理节点上的残留文件
# 在每个 GPU 节点上执行
sudo rm -rf /usr/local/vgpu
sudo rm -f /etc/ld.so.preload

备份配置

bash
# 导出 ConfigMaps
kubectl get cm -n hami-system -o yaml > hami-config-backup.yaml

# 导出 Helm values
helm get values hami -n hami-system > hami-values-backup.yaml

# 恢复
kubectl apply -f hami-config-backup.yaml
helm upgrade hami hami/hami -n hami-system -f hami-values-backup.yaml

故障排查

常见问题

1. GPU 未被识别

现象

  • nvidia-smi 显示 GPU,但 HAMi 未注册
  • 日志显示 Discovered 0 device(s)

排查

bash
# 检查 NVIDIA 驱动
nvidia-smi

# 检查设备文件
ls -la /dev/nvidia*

# 检查 device-plugin 日志
kubectl logs -n hami-system ds/hami-device-plugin -c device-plugin | tail -50

# 检查节点标签
kubectl get node <node-name> --show-labels | grep gpu

解决

bash
# 添加 GPU 标签
kubectl label node <node-name> gpu=on

# 重启 device-plugin
kubectl rollout restart ds/hami-device-plugin -n hami-system

2. vGPU 分配失败

现象

  • Pod 卡在 Pending 状态
  • 事件显示 Insufficient nvidia.com/gpumem

排查

bash
# 检查节点资源
kubectl describe node <node-name> | grep -A 10 "Allocated resources"

# 检查 Pod 事件
kubectl describe pod <pod-name>

# 检查已分配的 vGPU
kubectl get pods -A -o json | jq -r '.items[] | select(.metadata.annotations["hami.io/vgpu-devices-allocated"]) | .metadata.name + ": " + .metadata.annotations["hami.io/vgpu-devices-allocated"]'

解决

  • 减少 Pod 请求的显存
  • 增加 devicesplitcount 切分更多 vGPU
  • 添加更多 GPU 节点

3. GSP 固件初始化失败

现象

  • 日志显示 RmInitAdapter: Cannot initialize GSP firmware RM
  • nvidia-smi 只显示部分 GPU

排查

bash
# 检查内核日志
journalctl -k | grep -i nvidia | tail -30

# 检查 GPU 信息
cat /proc/driver/nvidia/gpus/*/information

解决

bash
# 禁用 GSP
echo "options nvidia NVreg_EnableGpuFirmware=0" | sudo tee /etc/modprobe.d/nvidia-gsp.conf

# 重载驱动
sudo rmmod nvidia_uvm nvidia_drm nvidia_modeset nvidia
sudo modprobe nvidia
sudo modprobe nvidia_uvm
sudo modprobe nvidia_drm

4. KVM 虚拟机 GPU 直通问题

现象

  • 虚拟机中 GPU MMIO 寄存器读取错误
  • regvalue: 0xbadf5620

排查

bash
# 检查虚拟化类型
systemd-detect-virt

# 检查 PCI 拓扑
lspci -t

# 检查 IOMMU
cat /proc/cmdline | grep iommu

解决

  • 联系 hypervisor 管理员检查 IOMMU 分组
  • 确保 GPU 在不同 PCI root port
  • 冷启动虚拟机(非热重启)

调试工具

bash
# 进入 device-plugin 容器
kubectl exec -it -n hami-system $(kubectl get pods -n hami-system -l app.kubernetes.io/component=hami-device-plugin -o name | head -1) -c device-plugin -- sh

# 查看 vGPU 库文件
ls -la /usr/local/vgpu/

# 检查容器挂载
crictl inspect <container-id> | grep -A 20 mounts

# 测试 CUDA 可见性
kubectl exec -it <pod-name> -- nvidia-smi

附录

A. 完整镜像列表

镜像标签说明
projecthami/hamiv2.10.0HAMi 主镜像
nvidia/k8s-device-pluginv0.14.5NVIDIA device plugin
k8s.gcr.io/kube-schedulerv1.28.0Kubernetes scheduler

B. 端口说明

端口协议说明
443HTTPSScheduler webhook
2379TCPetcd client(如使用内建 etcd)
2380TCPetcd peer

C. 文件路径

路径说明
/usr/local/vgpu/libvgpu.sovGPU 动态库
/usr/local/vgpu/containers/容器配置目录
/etc/ld.so.preload预加载配置
/var/lib/kubelet/device-plugins/K8s device plugin socket

D. 相关链接


文档版本: v1.0
更新时间: 2026-08-22
适用版本: HAMi v2.10.0