基于模拟硬件的多租户GPU Kubernetes:使用Kamaji与HAMi

基于模拟硬件的多租户GPU Kubernetes:使用Kamaji与HAMi

💡 原文英文,约2100词,阅读约需8分钟。
📝

内容提要

本文介绍如何用Kamaji与HAMi在单机无GPU环境下搭建多租户GPU共享平台。Kamaji将各租户的Kubernetes控制面以Pod形式运行在同一管理集群中,实现租户隔离;HAMi支持Pod按显存和算力比例申请GPU切片,使多个Pod共享一张显卡。作者通过模拟设备插件伪造A100和L4显卡,完成两个租户集群的部署,八项测试全部通过,验证了调度、超额申请拒绝和租户隔离。主要问题是模拟插件不释放节点锁,需手动添加注解解决。该实验仅验证调度链路,未测试真实GPU隔离与性能。

🔎

延伸解读

控制面与GPU共享的分层协作

Kamaji与HAMi分别解决不同层面的问题:Kamaji将租户控制面以Pod形式托管在管理集群,避免为每个团队单独准备控制面机器;HAMi则在租户集群内把整卡拆成显存和算力切片。两者没有重叠,真正的集成点在于租户API服务器需通过Konnectivity隧道回调运行在工作节点上的HAMi webhook。这一跳若失败,GPU Pod会退回默认调度器,HAMi便无法介入。

模拟环境能验证什么、不能验证什么

该实验用mock设备插件伪造A100和L4,验证了调度链路、超额申请拒绝和租户隔离,八项测试全部通过。但它不证明运行时GPU隔离:HAMi-core依赖NVIDIA驱动在容器内实施显存与算力限制,模拟卡没有可执行的限制对象。此外,没有运行CUDA负载,吞吐和邻居干扰效应均未测试。因此结果只说明“接线正确”,不代表生产性能与隔离强度。

模拟插件的节点锁陷阱

实验中GPU Pod卡在“node lock contention”,原因是HAMi绑定Pod时会锁定节点并标记bind-phase为allocating,真实设备插件完成分配后释放锁,而mock插件不会,锁需5分钟才过期。作者通过手动注解Pod为success并移除节点锁解决。这是模拟环境特有的产物,并非Kamaji或HAMi的缺陷,但提醒使用mock插件时需为每个GPU Pod补上释放锁的步骤。

无GPU时的预演价值与边界

对于尚未采购GPU的团队,该方案提供了一条低成本预演路径:单机4核CPU、8GB内存、20GB磁盘即可搭建两个隔离租户并测试调度策略。但需注意,工作节点加入方式并非Kamaji官方支持路径,官方推荐kubeadm或Cluster API;节点GPU数据也是手工写入注解。正式环境应改用真实设备插件,并补充CUDA负载下的隔离与性能验证。

❓

Q&A

Kamaji 和 HAMi 分别解决多租户 GPU 场景下的什么问题?

Kamaji 解决集群隔离问题:它把每个租户的 Kubernetes 控制面作为 Pod 运行在同一个管理集群中,租户无需各自独占控制面机器。HAMi 解决 GPU 共享问题:它允许 Pod 按显存(MB)和算力(%)申请 GPU 切片,把多个 Pod 打包到同一张显卡上。两者工作在不同层次,互不重叠。

没有物理 GPU 的情况下,怎么搭建并测试 GPU 共享平台?

使用 HAMi 的 mock device plugin 跳过硬件发现:在节点注解中描述伪造的显卡(如 A100 80GB 或 L4 24GB),插件据此注册 gpumem 和 gpucores 容量,HAMi 的 webhook、调度器和配额逻辑照常运行。整个实验可在一台 4 核 CPU、8GB 内存、20GB 磁盘的 Linux 主机上以 Docker 容器完成。

Kamaji 和 HAMi 结合时,关键的集成点在哪里?

关键集成点是租户 API server 调用 HAMi webhook 的路径。租户的 API server 运行在管理集群内,而 HAMi 的 webhook 运行在租户的工作节点上,因此每次创建 GPU Pod 时,准入调用需要经过 Kamaji 的 Konnectivity 隧道回到租户侧。如果这条路径失败,GPU Pod 会回退到默认调度器,HAMi 就无法感知它们。

HAMi 如何防止 GPU 被超额申请?

HAMi 调度器会检查节点上剩余的显存和算力。例如三个 Pod 各申请 20000MB 和 30% 算力后,第四个 30% 的 Pod 会因 CardInsufficientCore 保持 Pending;申请 90000MB 超过整卡 81920MB 的 Pod 会因 CardInsufficientMemory 保持 Pending。

实验中 GPU Pod 卡在 node lock contention 是什么原因,怎么解决?

HAMi 在绑定 Pod 时会锁定节点并标记 hami.io/bind-phase: allocating,真实设备插件完成分配后会释放锁,但 mock 插件不会释放,导致锁要等 5 分钟才过期。解决办法是手动模拟设备插件的动作:对 Pod 执行 kubectl annotate pod <pod> hami.io/bind-phase=success --overwrite,并对节点执行 kubectl annotate node <node> hami.io/mutex.lock-。这是 mock 环境特有的问题,不是 Kamaji 或 HAMi 的缺陷。

这个实验验证了哪些内容,又有哪些没有验证?

实验验证了调度链路和租户隔离:两个租户集群各自只能看到自己的节点、Pod 和 GPU 容量,八项测试全部通过,包括多 Pod 共享一张卡、超额申请被拒。但没有验证运行时 GPU 隔离(mock 卡没有驱动可供 HAMi-core 强制执行显存和算力限制)、没有性能数据(未运行 CUDA 负载,吞吐和邻居干扰未测试),设备数据是手工构造的,工作节点加入方式也非 Kamaji 官方支持路径。

🏷️

标签

➡️

继续阅读